一、什麼是new? 眾所周知,在JS中,new的作用是通過構造函數來創建一個實例對象。 像下麵這樣:(和普通函數不一樣,當函數用作 構造函數 時,首字母一般要大寫,以作區分。) 二、new經歷了什麼過程? Foo明明只是一個函數,可是為什麼new Foo()執行後會突然返回一個對象呢? 我們從結果出 ...
一、什麼是new?
眾所周知,在JS中,new的作用是通過構造函數來創建一個實例對象。
像下麵這樣:(和普通函數不一樣,當函數用作構造函數時,首字母一般要大寫,以作區分。)
function Foo(name) {
this.name = name;
}
console.log("new Foo('mm')的類型:",typeof new Foo('mm')); // object
console.log("Foo的類型:",typeof Foo); // function
二、new經歷了什麼過程?
Foo明明只是一個函數,可是為什麼new Foo()執行後會突然返回一個對象呢?
我們從結果出發可以推斷出,既然返回了一個對象,那麼這事肯定和對象有關係。
實際上new幫我們做了這樣幾件事:
- 幫我們創建了一個空對象,例如:obj;
- 將空對象原型的記憶體地址
__proto__
指向函數的原型對象;(這裡涉及到了原型鏈的知識) - 利用函數的call方法,將原本指向window的綁定對象this指向了obj。(這樣一來,當我們向函數中再傳遞實參時,對象的屬性就會被掛載到obj上。)
- 利用函數返回對象obj。
三、new的過程分析
function Foo(name) {
this.name = name;
return this;
}
var obj = {};
obj.__proto__ = Foo.prototype;
// Foo.call(obj, 'mm');
var foo = Foo.call(obj, 'mm');
console.log(foo);
分析:
首先預編譯,聲明提升,解釋執行。
執行時按照順序來進行,
- obj指向空對象;
- obj的原型地址指向構造函數Foo的原型對象;
- 執行
Foo.call(obj, 'mm');
this.name = name;
通過函數的call方法將this綁定到obj(也就是說this就是obj),實參mm傳入構造函數Foo中,這樣this.name = 'mm',那麼obj.name = 'mm',也就是說name屬性被掛載到obj對象上。return this;
就是return obj,這樣obj這個對象就被返回出來了。
- 將結果賦值給變數foo。
- 列印結果。
四、總結
第三部分的代碼直接用new 構造函數效果是相同的。
function Foo(name) {
this.name = name;
}
var foo = new Foo('mm');
console.log(foo);
簡而言之,new操作符幫我們做了四件事:
- 創建空對象;
- 空對象的原型指針指向構造函數的原型對象;
- 利用函數的call方法改變this指向,在空對象上掛載屬性或方法;
- 返回對象。