new操作符實現原理:
function news(func) {
var target = {};//生成新對象
target.__proto__ = func.prototype;//實例的__proto__指向原型,構造函數的prototype也指向原型(鏈接到原型)
var res = func.call(target);//把函數的this綁定在了新生成的對象中
if (typeof (res) == "object" || typeof (res) == "function") {
return res;//如果傳入的函數(構造函數)有自己的返回值,則返回該值
}
return target;//如果如果傳入的函數(構造函數)沒有自己的返回值,則返回新對象
}
如果暫時看不明白,請往下看:
1.明白new的原理首先我們需要明白原型,構造函數,實例的關系
- 原型(prototype):一個簡單的對象,用於實現對象的屬性繼承。可以簡單理解成對象的父親。在火狐和谷歌中,每個js對象中都包含一個__proto__(非標准)的屬性指向它爹(該對象原型),可obj.__proto__進行訪問。
- 構造函數:可以 通過new來新建一個對象 的函數。
- 實例:通過 構造函數 和 new 創建出來的 對象,就是實例。實例通過__proto__指向原型,通過constructor指向構造函數。
寫明是栗子,以函數Father為例,函數Father就是一個構造函數,我們可以通過它構建一個實例
function Father() {
let colors = [1,2,3];
return colors;
}
const instance = new Father();
此時,instance為實例,構造函數為Father,構造函數擁有一個prototype的屬性指向原型。
因此原型為:
const prototype = Father.prototype;
因此看得出三者的關系:
實例.__proto__===原型
原型.constructor === 構造函數
構造函數.prototype === 原型
實例.constructor === 構造函數
例子:
function instanceFun(){
this.colors=['res','pink','black']
}
const instance = new Father();
console.log(instanceFun.prototype.constructor,'構造函數');
console.log(instance.__proto__,'實例訪問原型');
console.log(instanceFun.prototype,'構造函數訪問原型');
console.log(instance.constructor,'實例的構造函數');
2.new運算符的執行過程
- 新生成一個對象
- 鏈接到原型
- 綁定this
- 返回新對象(如果構造函數有自己 retrun 時,則返回該值)