構造函數函數特點
1.函數體內使用了this關鍵字,代表了所要生成的對象實例
2.生成對象的時候必須使用new命令
3每個函數都自動添加一個名稱為prototype屬性,這是一個對象
4每個對象內部都有一個屬性_proto_(規范沒有這個名稱,但是瀏覽器都是這么實現)
5指向其類型的prototype,類的實例也是對象,其_prototype_屬性指向類的prototype
new命令的作用,就是執行構造函數,返回一個實例對象。
使用new命令是,他后面的函數執行下面的步驟
1創建一個空對象,作為將要返回的對象實例
2將這個空對象的原型,指向構造函數的prototype屬性
3將這個空對象復制給函數內部this關鍵字
4開始執行構造函數內部的代碼
如果構造函數內部return語句,后面跟着一個對象,
new命令會返回renturn語句指定的對象否則不管return語句,返回this
var Vehicle = function () {
this.price = 1000;
return 1000;
};
(new Vehicle()) === 1000
// false
上面代碼中,構造函數Vehicle的return語句返回一個數值。這時,new命令就會忽略這個return語句,返回“構造”后的this對象。
但是,如果return語句返回的是一個跟this無關的新對象,new命令會返回這個新對象,而不是this對象。這一點需要特別引起注意。
function _new(/* 構造函數 */ constructor, /* 構造函數參數 */ params) {
// 將 arguments 對象轉為數組
var args = [].slice.call(arguments);
// 取出構造函數
var constructor = args.shift();
// 創建一個空對象,繼承構造函數的 prototype 屬性
var context = Object.create(constructor.prototype);
// 執行構造函數
var result = constructor.apply(context, args);
// 如果返回結果是對象,就直接返回,否則返回 context 對象
return (typeof result === 'object' && result != null) ? result : context;
}
// 實例
var actor = _new(Person, '張三', 28);
new target 使用這個屬性可以判斷函數調用時候是否使用new
function f() {
if (!new.target) {
throw new Error('請使用 new 命令調用!');
}
// ...
}
f() // Uncaught Error: 請使用 new 命令調用!
instanceof 是一個操作符可以判斷對象是否為某種類型的實例
p1 instanceof Person; // true