- new 的特點
- 如果實現一個 new 操作符
一、new 運算符
new
運算符創建一個用戶定義的對象類型的實例或具有構造函數的內置對象的實例。new 關鍵字會進行如下的操作:
- 創建一個空的 js 對象{}
- 鏈接該對象(即設置該對象的構造函數)到另一個對象 ;
- 將步驟
1
新創建的對象作爲this
的上下文 ; - 如果該函數沒有返回對象,則返回
this
。
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
var car1 = new Car('Eagle', 'Talon TSi', 1993);
console.log(car1.make);
// expected output: "Eagle"
二、手工實現一個 new 操作符
實現步驟
- 上面說了
new
操作符會返回一個對象, 所以我們需要在創建一個object
- 那麼我們需要將構造函數的的原型 設置到另一個對象上
- 將創建的對象 作爲
this
的上下文 - 有屬性返回屬性, 沒有則返回
this
function create(Con, ...args) {
let obj = {};
Object.setPrototypeOf(obj, Con.prototype)
let result = Con.apply(obj, args)
return result instanceof Object ? result : obj
}
上面的函數 第一個參數作爲構造函數傳入, 接下來的參數被構造函數使用
然後按上面的1、2、3、4
步驟實現
- 創建一個 空對象
- 將 構造函數的原型 設置給 空對象。 等用於
obj.__proto__ = Con.prototype
- 將 obj 綁定到構造函數上, 並且通過剩餘參數傳入
- 最後 判斷 返回值是否爲對象, 如果爲對象 則 返回使用構造函數的result, 否則就返回 obj
那我們來看看最後實現的效果吧
function Test(name, age) {
this.name = name
this.age = age
}
Test.prototype.intr = function () {
console.log(`my name is ${this.name}, i'm ${this.age} years old`)
}
const me = create(Test, 'gavin', '21')
console.log(me.name) //output: gavin
console.log(me.age) //output: 21
me.intr() // my name is gavin, i'm 21 years old``
參考
web docs: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
掘金 yck: https://juejin.im/post/5c7b963ae51d453eb173896e