javascript是一門腳本語言,所以好多人認(rèn)為javascript比較簡單易懂好學(xué)。
哈哈,那你就錯(cuò)了。javascript支持函數(shù)式編程、閉包、基于原型鏈繼承等等這些高級功能。
今天為大家剖析這門面向?qū)ο骿avascript入門檻this關(guān)鍵字。你必須了解弄透,才算真正入門javascript。其實(shí)this就一句話,誰調(diào)用就屬于誰!,javascript中的this對象含義有好幾種。
this對象它可以指全局對象(window)、當(dāng)前對象、或者任意的對象。
this的調(diào)用分別下面這4種:
作為一個(gè)函數(shù)調(diào)用。
作為一個(gè)方法調(diào)用。
作為構(gòu)造函數(shù)調(diào)用。
使用call或apply調(diào)用。
1、作為一個(gè)函數(shù)調(diào)用在全局作用域(對象)內(nèi)調(diào)用函數(shù),this綁定到全局對象中去,也就是說this指向window示例:var name = 'this window';
function getName() {
? ? alert(this.name); // this window
? ? alert(this.name === window.name); // true
}
getName();
由于在全局作用域內(nèi)調(diào)用,所以this指向window作為一個(gè)函數(shù)調(diào)用就這么簡單!
2、作為一個(gè)方法調(diào)用示例:var name = 'this window';
var obj = {
? ? name: 'my object',
? ? getName: function() {
? ? ? ?alert(this.name);? // 'my boject'
? ? ? ?alert(obj.name === this.name); // true
? ?}
};
obj.getName();
咦~~怎么示例一和示例二都是執(zhí)行一個(gè)名叫g(shù)etName的function,怎么一個(gè)叫函數(shù)一個(gè)叫方法呢?
你是否有這個(gè)疑惑呢?
客官莫急!老司機(jī)給你講講,先上車再說吧~~
在javascript中,函數(shù)也是對象,所以函數(shù)可以作為一個(gè)對象的屬性存在,那么這個(gè)時(shí)候就稱之為該對象的方法!
例如:上面中的obj對象有一個(gè)叫g(shù)etName的屬性,并且getName還是一個(gè)function,所以getName是obj的一個(gè)方法。
換句話來說,凡是一個(gè)以function作為對象屬性存在的,我們就稱它為方法!
結(jié)論: 一個(gè)函數(shù)作為一個(gè)方法調(diào)用,該this指向該調(diào)用對象!
例如:上面的getName就是作為obj的方法調(diào)用,所以該方法內(nèi)的this.name就是指向obj對象。
3、作為構(gòu)造函數(shù)調(diào)用示例:
function Person(name, age) {
? ? this.name = name;
? ? this.age = age;
this.msg = function() {
console.log(this);
return "姓名:" + this.name + "," + '年齡:' + this.age
}
}
var oldDriver = new Person('老司機(jī)', 26);
var laowang = new Person('老王', 40);
alert(oldDriver.msg()); // 姓名:老司機(jī),年齡:16
alert(laowang.msg()); // 姓名:老王,年齡:40
// console.log(this)
結(jié)論:this指向新創(chuàng)建的實(shí)例(對象)!
4、使用 apply 或 call 調(diào)用示例:var name = 'this window';
var obj = {
name: 'my object',
getName: function() {
return function() {
alert(this.name);
}
}
};
假如我們想得出那個(gè)alert框的this.name的值怎么做呢?
相信機(jī)智的未來司機(jī)肯定obj.getName()(),
記得有兩個(gè)括號的哦,只有一個(gè)括號代表的是執(zhí)行這個(gè)getName函數(shù)然后return 一個(gè)匿名函數(shù),要想執(zhí)行這個(gè)匿名函數(shù)再加多一個(gè)括號,好那我們就運(yùn)行。
然后彈出:“this window”!
有人肯定問:剛才你不是說getName函數(shù)作為一個(gè)對象屬性存在,然后調(diào)用這個(gè)方法,this就指向這個(gè)對象嗎?
應(yīng)該是“my object”才對呀!
怎么會(huì)變成“this window”的老鄉(xiāng)!這個(gè)不一樣呀,里面還多了return function() {}的匿名函數(shù)呀。
這里面就構(gòu)成了一個(gè)閉包呀!咦~閉包什么鬼?其實(shí)閉包在javascript里面可以簡單的理解為一個(gè)函數(shù)里面嵌套著另外一個(gè)函數(shù),并且外部的函數(shù)將嵌套的函數(shù)對象作為一個(gè)返回值返出?。o論這個(gè)被返回的函數(shù)對象是否匿名)大概有點(diǎn)懂了吧!不懂沒關(guān)系,我們可以先alert(obj.getName())看看是什么東西
哦,原來是
function() {
alert(this.name);
}
所以剛才的obj.getName()();就等于一個(gè)匿名的自執(zhí)行函數(shù)(自動(dòng)立馬執(zhí)行的函數(shù),作用域是window)被window調(diào)用了(function(){
alert(this.name);
})();
所以obj.getName()()運(yùn)行, this指向window!
老司機(jī),老司機(jī),我可是想讓里面的this.name 變成“my object”,你有辦法嗎?
我再一次重申,在 JavaScript 中函數(shù)也是對象,對象則有方法,apply 和 call 就是函數(shù)對象的方法。這兩個(gè)方法異常強(qiáng)大,他們允許切換函數(shù)執(zhí)行的上下文環(huán)境(context),即 this 綁定的對象。很多 JavaScript 中的技巧以及類庫都用到了該方法。通俗的說:
你首先要知道call和apply是Function的方法,他的第一個(gè)參數(shù)是this,第二個(gè)是Function的參數(shù)。
比如你的方法里寫了this、window、undefined、null,普通調(diào)用這個(gè)方法這個(gè)this是window。
而如果你用了call或者apply,第一個(gè)參數(shù)就是this,第二個(gè)參數(shù)就是這個(gè)Function的參數(shù)(參數(shù)選填)
語法:Function.call(obj,arg); Function.apply(obj,[arg1,arg2..]);我們可以用obj.getName().call(obj);或者obj.getName.apple(obj);var obj = {
name: 'my object',
getName: function() {
return function() {
alert(this.name);
}
}
};
obj.getName().call(obj); // 'my object'
// obj.getName().apply(obj); // 'my object'
意思就是:obj.getName()運(yùn)行返回的匿名函數(shù),this指向obj。所以函數(shù)自執(zhí)行時(shí) “this.name”相當(dāng)于“obj.name”,所以是'my object'.