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 }
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' }
使用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