j**ascript語言的物件體系不是基於類的,而是基於建構函式和原型鏈。j**ascript語言使用建構函式作為物件的模板。所謂建構函式就是專門用來生成例項物件的函式。建構函式就是乙個普通的函式,但是有自己的特徵和用法。
var vehicle = function () ;
上面**中,vehicle就是建構函式。為了與普通函式區別,建構函式名字的第乙個字母通常大寫。
建構函式的特點有兩個。
new命令的作用就是執行建構函式,返回乙個例項物件。
var v = new vehicle();
v.price() // 1000
使用new命令時,根據需要,建構函式也可以接受引數。
var vehicle = function (p) ;
var v = new vehicle(500);
如果忘了使用new命令,直接呼叫建構函式,建構函式就變成普通函式,並不會生成例項物件。而且由於後面會說到的原因,this這時代表全域性物件,將造成一些意想不到的結果。
為了保證建構函式與new命令一起使用,乙個解決辦法是,建構函式內部使用嚴格模式,即第一行加上use strict。這樣的話,一旦忘了使用new命令,直接呼叫建構函式就會報錯。
function fubar(foo, bar)
fubar() // typeerror: cannot set property "_foo" of undefined
由於嚴格模式中,函式內部的this不能指向全域性物件,預設等於undefined,導致不加new呼叫會報錯。
另乙個解決方法,建構函式內部判斷是否使用new命令,如果發現沒有使用,則直接返回乙個例項物件。
function fubar(foo, bar)
this._foo = foo;
this._bar = bar;
}fubar(1, 2)._foo // 1
(new fubar(1, 2))._foo // 1
使用new命令時,它後面的函式依次執行下面的步驟。
var vehicle = function () ;
};(new vehicle()).price // 2000
另一方面,如果對普通函式(內部沒有this關鍵字的函式)使用new命令,則會返回乙個空物件。
function getmessage()
var msg = new getmessage();
msg // {}
typeof msg // "object"
new命令簡化的內部流程,可以用下面的**表示。
function _new(constructor, params)
函式內部可以使用new.target屬性。如果當前函式是new命令呼叫,new.target指向當前函式,否則為undefined。
function f()
f() // false
new f() // true
使用這個屬性,可以判斷函式呼叫的時候,是否使用new命令。
function f()
}f() // uncaught error: 請使用new命令呼叫!
建構函式作為模板,可以生成例項物件。但是有時候拿不到建構函式,只能拿到乙個現有的物件。我們希望以這個現有的物件為模板,生成新的例項物件,這時就可以使用object.create方法。
var person1 =
};var person2 = object.create(person1);
C 建立物件new與不new區別
記憶體的分配方式有三種 1.從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static 變數。2.在棧上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束後在將這些區域性變數的記憶體空間 在棧上分配記憶體空間效率很...
例項的初始化過程 new 物件
類的載入過程 1.jvm會先去方法區中找有沒有相對應類的.class存在。如果有就直接使用,如果沒有,則把相關類的.class 載入到方法區 2.在.class載入到方法區時,會分為兩部分載入 先載入非靜態內容,再載入靜態內容 3.載入非靜態內容 把.class中的所有非靜態內容載入到方法區下的非靜...
使用new和不使用new關鍵字例項化物件的區別
例 這裡的m物件進棧 movie movie1 new出來的物件進堆 不會自動 因此為了避免記憶體洩露,需要手動刪掉 movie movie2 new movie 哈哈 哈哈 100,哈哈 第一種方式是在程序虛擬位址空間中的棧中分配記憶體,而第二種使用了new,在堆中分配了記憶體,而棧中記憶體的分配...