前言
在js中,創建對象有三種方式
- {} // 對象字面量
- new Object()
- Object.create()
1和2的區別很小,1不能傳參,2可以傳參。
new Object() 和Object.create() 區別就比較大了
1. new關鍵字
new 關鍵字做了幾件事
- 創建一個新對象
- 將新對象的原型指向構造函數的原型
- 執行構造函數,綁定this
- 返回這個對象
比如創建一個Car對象,偽代碼
// new Car()
var obj = new Object()
obj._proto_ = Car.prototype
// 執行構造函數, 綁定this
Car.call(obj)
我們注意到比較關鍵的地方是,它調用了Car對象的構造函數,並通過call將obj的this綁定到了Car對象上
這一步操作將Car對象上的屬性,繼承到了obj上
2. Object.create()
Object.create做了什么事情呢?
它同樣是創建一個新對象,將新對象的原型關聯到構造函數上
var f = function() { }
f.prototype = Car
return new f()
可以看出,在Object.create的內部,並沒有去調用Car構造函數,而是調用了創建新對象的構造函數,因此Car上的屬性不會繼承到Object.create創建的實例中
3. 例子
比較鮮明的地方是在繼承的時候
子類去繼承父類的原型方法的時候,很多人會這樣寫
// 父類是People,子類是Male
Male.prototype = new People()
new確實能夠繼承,但是調用了父類的構造函數,把父類的屬性也給繼承到了原型上,但是我們僅僅只是想要父類的原型方法,所以這樣寫是存在副作用的
正確的寫法應該是
Male.prototype = Object.create(People.prototype)
這種方式,不會調用父類的構造函數,而是生成新對象,將新對象與父類原型關聯,然后new這個新對象返回
將 new 構造函數
的方式轉變了成 new 新對象
的方式,這樣就更加純凈,干脆