構(gòu)造函數(shù)
var Vehicle = function() {
this.price = 1000;
}
構(gòu)造函數(shù)的特點(diǎn)有兩個(gè):
- 函數(shù)體內(nèi)部使用了this關(guān)鍵字,代表了所要生成的對象實(shí)例构舟。
- 生成對象的時(shí)候冰沙,必須使用new命令。
new 命令
1. 基本用法
new命令的作用炎辨,就是執(zhí)行構(gòu)造函數(shù),返回一個(gè)實(shí)例對象聪姿。
var Vehicle = function () {
this.price = 1000;
};
var v = new Vehicle();
v.price // 1000
var Vehicle = function (){
this.price = 1000;
};
var v = Vehicle();
v // undefined
price // 1000
上面代碼中碴萧,調(diào)用Vehicle構(gòu)造函數(shù)時(shí),忘了加上new命令末购。結(jié)果破喻,變量v變成了undefined,而price屬性變成了全局變量盟榴。因此低缩,應(yīng)該非常小心,避免不使用new命令曹货、直接調(diào)用構(gòu)造函數(shù)咆繁。
為了保證構(gòu)造函數(shù)必須與new命令一起使用,一個(gè)解決辦法是顶籽,構(gòu)造函數(shù)內(nèi)部使用嚴(yán)格模式玩般,即第一行加上use strict。這樣的話礼饱,一旦忘了使用new命令坏为,直接調(diào)用構(gòu)造函數(shù)就會(huì)報(bào)錯(cuò)究驴。
2. new 命令的原理
使用new命令時(shí),它后面的函數(shù)依次執(zhí)行下面的步驟匀伏。
- 創(chuàng)建一個(gè)空對象洒忧,作為將要返回的對象實(shí)例。
- 將這個(gè)空對象的原型够颠,指向構(gòu)造函數(shù)的prototype屬性熙侍。
- 將這個(gè)空對象賦值給函數(shù)內(nèi)部的this關(guān)鍵字。
- 開始執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼履磨。
3. Object.create() 創(chuàng)建實(shí)例對象
構(gòu)造函數(shù)作為模板蛉抓,可以生成實(shí)例對象。但是剃诅,有時(shí)拿不到構(gòu)造函數(shù),只能拿到一個(gè)現(xiàn)有的對象矛辕。我們希望以這個(gè)現(xiàn)有的對象作為模板,生成新的實(shí)例對象聊品,這時(shí)就可以使用Object.create()方法。
This
實(shí)質(zhì)
js 之所以有this的設(shè)計(jì)杨刨,跟內(nèi)存里面的數(shù)據(jù)結(jié)構(gòu)有關(guān)系
var obj = {foo: 5};
將一個(gè)對象賦值給obj晤柄。 Javascript會(huì)先在內(nèi)存里擦剑,生成一個(gè)對象 {foo: 5},然后把這個(gè)對象的內(nèi)存地址賦值給obj,也就是說obj是一個(gè)reference惠勒。后面要是要取obj.foo, 要先從obj中拿到內(nèi)存地址纠屋,然后再從該地址讀出原始的對象
var obj = { foo: function () {} };
這時(shí)涂臣,引擎會(huì)將函數(shù)單獨(dú)保存在內(nèi)存中,然后再將函數(shù)的地址賦值給foo屬性的value屬性
{
foo: {
[[value]]: 函數(shù)的地址
...
}
}
var f = function () {
console.log(this.x);
}
var x = 1;
var obj = {
f: f,
x: 2,
};
// 單獨(dú)執(zhí)行
f() // 1
// obj 環(huán)境執(zhí)行
obj.f() // 2
如果this所在的方法不在對象的第一層售担,這時(shí)this只是指向當(dāng)前一層的對象赁遗,而不會(huì)繼承更上面的層族铆。
var a = {
b: {
m: function() {
console.log(this.p);
},
p: 'Hello'
}
};
var hello = a.b.m;
hello() // undefined
var hello = a.b;
hello.m() // Hello
使用場合
1. 全局環(huán)境
全局環(huán)境使用this,它指的就是頂層對象window
this === window //true
function() {
console.log(this === window);
}
2. 構(gòu)造函數(shù)
構(gòu)造函數(shù)中的this剖煌,指的是實(shí)例對象
var Obj = function (p) {
this.p = p;
};
``
這樣的結(jié)構(gòu)是很清晰的,問題在于屬性的值可能是一個(gè)函數(shù)
3. 對象的方法
如果對象的方法里面包含this耕姊,this的指向就是方法運(yùn)行時(shí)所在的對象。該方法賦值給另一個(gè)對象茉兰,就會(huì)改變this的指向。
var obj = {
foo: function() {
console.log(this);
}
}
obj.foo(); //obj
但是下面的這幾種方法安吁,都會(huì)改變this的指向
(obj.foo = obj.foo)() //window
上面代碼中燃辖,obj.foo就是一個(gè)值。這個(gè)值真正調(diào)用的時(shí)候黔龟,運(yùn)行環(huán)境已經(jīng)不是obj了,而是全局環(huán)境氏身,所以this不再指向obj