Javascript 面向對象編程中的‘new’

0 通常函數調用

function personFn(name, age) {
    var personObj = {};

    personObj.name = name;
    personObj.age = age;
    
    return personObj;
}

var alex = personFn('Alex', 30);
console.log(alex); // -> { name: 'Alex', age: 30 }

 

1 使用new 建立對象

function PersonConstructor(name, age) {
    this.name = name;
    this.age = age;
}

var alex = new PersonConstructor('Alex', 30);
console.log(alex); // -> PersonConstructor { name: 'Alex', age: 30 }

使用new觸發的函數通常稱爲「構造函數」,大寫字母開頭,生成的對象包含「構造函數」名+返回的對象javascript

其實使用new觸發函數,Javascript engine會特殊處理,下面註釋的僞碼能夠當作Javscript engine加入的特殊處理java

function PersonConstructor(name, age) {
    // this = {};
    // this.__proto__ = PersonConstructor.prototype;

    // Set up logic such that: if
    // there is a return statement
    // in the function body that
    // returns anything EXCEPT an
    // object, array, or function:
    //     return 'this' (the newly
    //     constructed object)
    //     instead of that item at
    //     the return statement;

    this.name = name;
    this.age = age;

    // return this;
}

整段代碼能夠分解爲下面幾個部分:函數

1 建立一個空對象,將它綁定給thisthis

2 將對象的_proto_屬性設置爲構造函數的原型prototypespa

3 返回邏輯:若是代碼沒有返回,或者返回的不是object, array, 或者 function中的一種,那麼將返回thisprototype

4 在代碼末尾添加return, 若是代碼中沒有returncode

 

例子對象

function Demo() {
    console.log(this);
    this.value = 5;
    return 10;
}

/*1*/ var demo = new Demo(); // -> Demo {}
/*2*/ console.log(demo.__proto__ === Demo.prototype); // -> true
/*3*/ console.log(demo); // -> Demo { value: 5 }

function SecondDemo() {
    this.val = '2nd demo';
}

/*4*/ console.log(new SecondDemo()); // -> SecondDemo { val: '2nd demo' }

 

2 使用new 建立非構造函數

使用new 建立開頭的普通函數,會發生什麼?ip

function personFn(name, age) {
    var personObj = {};

    personObj.name = name;
    personObj.age = age;
    
    return personObj;
}

var alex = new personFn('Alex', 30);
console.log(alex); // -> { name: 'Alex', age: 30 }

結果和普通函數調用是同樣的,咱們看看Javascript engine 加入代碼後的樣子原型

function personFn(name, age) {
    // this = {};
    // this.constructor = PersonConstructor;
    // this.__proto__ = PersonConstructor.prototype;

    // Set up logic such that: if
    // there is a return statement
    // in the function body that
    // returns anything EXCEPT an
    // object, array, or function:
    //     return this (the newly
    //     constructed object)
    //     instead of that item at
    //     the return statement;

    var personObj = {};

    personObj.name = name;
    personObj.age = age;
    
    return personObj;
    
    // return this;
}

 

註釋掉的代碼主要作了下面四件事:

1 生成空對象,this綁定到這個空對象上

2 設置對象的構造函數和_proto_屬性

3 設置返回邏輯

4 若是沒有返回的話,添加return在代碼的最後

 

其實這些操做並無影響以前的代碼,由於以前的代碼並無用到this, 並且也有返回對象

小結:使用new 對象時,構造函數裏必須使用this纔有價值

 

參考資料:

https://www.educative.io/collection/page/5679346740101120/5707702298738688/5750085036015616

相關文章
相關標籤/搜索