new 運算符建立一個用戶定義的對象類型的實例或具備構造函數的內置對象的實例javascript
先看看 new 實現了哪些功能, 先來看一段代碼:java
function Person(age) {
this.age = age;
}
Person.prototype.getAge = function() {
console.log("年齡爲:" + this.age );
}
var person = new Person(18);
person.age; // 訪問構造函數裏的屬性
// 18
person.getAge(); // 訪問原型裏的屬性
// 年齡爲:18
複製代碼
從上面代碼能夠知道,實例 person 能夠:數組
這個是最基本的了,也是剛學會new一個對象就知道這是new的特色app
探討完上面,接下來看看new還作了什麼?來看幾個例子函數
function Person(age) {
this.age = age;
}
var person = new Person(18);
console.log(person); // Person {age: 18}
複製代碼
從構造函數直觀看,最後是沒有 return語句的,但咱們從返回結果也能夠看出構造函數時默認狀況會返回一個新對象測試
咱們嘗試在構造函數最後返回一個對象ui
function Person(age) {
this.age = age;
return { name: '手動返回一個對象' }
}
var person = new Person(18);
console.log(person); // {name: "手動返回一個對象"}
複製代碼
打印出來的結果能夠看書:return 以前的代碼片斷都被覆蓋了,最後返回 return 後面的對象。this
若是構造函數最後return的不是對象呢,試下基本數據類型spa
function Person(age) {
this.age = age;
return 1
}
var person = new Person(18);
console.log(person); // Person {age: 18}
複製代碼
從打印出來的結果可知,和沒有return效果同樣。prototype
mdn上把內部操做大概分爲4步:
- 建立一個空的簡單JavaScript對象(即{ } );
- 連接該對象(即設置該對象的構造函數)到另外一個對象 ;(所以this就指向了這個新對象)
- 執行構造函數中的代碼(爲這個新對象添加屬性);
- 若是該函數沒有返回對象,則返回this。
new 是關鍵詞,不能夠直接覆蓋。這裏使用 create 來模擬實現 new 的效果。
function myNew() {
// 建立一個空的對象
var obj = new Object(),
// 得到構造函數,arguments中去除第一個參數
Con = [].shift.call(arguments);
// 連接到原型,obj 能夠訪問到構造函數原型中的屬性
obj.__proto__ = Con.prototype;
// 綁定 this 實現繼承,obj 能夠訪問到構造函數中的屬性
var ret = Con.apply(obj, arguments);
// 優先返回構造函數返回的對象
return ret instanceof Object ? ret : obj;
};
複製代碼
來看看上面是怎麼一步步模擬實現的:
在上面咱們用instanceof方法來判斷是否爲對象
instanceof 運算符用於檢測構造函數的 prototype 屬性是否出如今某個實例對象的原型鏈上。
測試:
function Person(age) {
this.age = age;
}
Person.prototype.getAge = function() {
console.log("年齡爲:" + this.age );
}
var person = create(Person, 18)
person.age; // 訪問構造函數裏的屬性
// 18
person.getAge(); // 訪問原型裏的屬性
// 年齡爲:18
複製代碼
模擬實現成功!