模擬實現new
需滿足:
- 繫結this
- 新建一個物件
- 將物件連結到原型
- 返回新的物件
/**
* 因為new是關鍵字,所以不能直接覆蓋。
* 我們這邊用create來模擬實現。
*/
function create () {
let obj = {}
let Con = [].shift.call(arguments)
// 連結原型,使得新建物件可以訪問到建構函式原型上的屬性
obj.__proto__ = Con.prototype
// 繫結this
Con.apply(obj, arguments)
return obj
}
複製程式碼
建構函式返回值有如下三種情況:
- 1、有 return ,返回一個物件,例項只能訪問返回物件中的例項
- 2、沒有 return ,即返回 undefined,例項只能訪問到建構函式中的屬性,和情況1完全相反。
- 3、返回 undefined 以外的基本型別,等於沒有返回,例項只能訪問到建構函式中的屬性,和情況1完全相反。
綜上,所以需要判斷下返回的值是不是一個物件,如果是物件則返回這個物件,不然返回新建立的 obj物件。
/**
* 因為new是關鍵字,所以不能直接覆蓋。
* 我們這邊用create來模擬實現。
*/
function create () {
let obj = {}
let Con = [].shift.call(arguments)
// 連結原型,使得新建物件可以訪問到建構函式原型上的屬性
obj.__proto__ = Con.prototype
// 繫結this
let ret = Con.apply(obj, arguments)
return ret instanceof Object ? ret : obj
}
複製程式碼
// 測試用例
function Car(color) {
this.color = color;
}
Car.prototype.start = function() {
console.log(this.color + " car start");
}
var car = create(Car, "black");
car.color;
// black
car.start();
// black car start
複製程式碼
模擬實現instanceof
instanceof
運算子用來檢測 constructor.prototype
是否存在於引數 object 的原型鏈上。
function instanceof1 (left, right) {
// 獲取型別原型
let prototype = right.prototype
// 獲取物件原型
left = left.__proto__
// 判斷物件的型別是否等於型別的原型
while (true) {
if (left === null)
return false
if (left === prototype)
return true
left = left.__proto__
}
}
複製程式碼
收工~