javascript是一門腳本語(yǔ)言车要,所以好多人認(rèn)為javascript比較簡(jiǎn)單易懂好學(xué)榆俺。
哈哈,那你就錯(cuò)了跪削。javascript支持函數(shù)式編程谴仙、閉包、基于原型鏈繼承等等這些高級(jí)功能碾盐。
今天為大家剖析這門面向?qū)ο骿avascript入門檻this關(guān)鍵字晃跺。你必須了解弄透,才算真正入門javascript毫玖。其實(shí)this就一句話掀虎,誰(shuí)調(diào)用就屬于誰(shuí)凌盯!,javascript中的this對(duì)象含義有好幾種烹玉。
this對(duì)象它可以指全局對(duì)象(window)驰怎、當(dāng)前對(duì)象、或者任意的對(duì)象二打。
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)用在全局作用域(對(duì)象)內(nèi)調(diào)用函數(shù)瑞信,this綁定到全局對(duì)象中去厉颤,也就是說(shuō)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)用就這么簡(jiǎn)單凡简!
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ī)給你講講筐眷,先上車再說(shuō)吧~~
在javascript中挖函,函數(shù)也是對(duì)象,所以函數(shù)可以作為一個(gè)對(duì)象的屬性存在浊竟,那么這個(gè)時(shí)候就稱之為該對(duì)象的方法!
例如:上面中的obj對(duì)象有一個(gè)叫g(shù)etName的屬性津畸,并且getName還是一個(gè)function振定,所以getName是obj的一個(gè)方法。
換句話來(lái)說(shuō)肉拓,凡是一個(gè)以function作為對(duì)象屬性存在的后频,我們就稱它為方法!
結(jié)論: 一個(gè)函數(shù)作為一個(gè)方法調(diào)用暖途,該this指向該調(diào)用對(duì)象卑惜!
例如:上面的getName就是作為obj的方法調(diào)用,所以該方法內(nèi)的this.name就是指向obj對(duì)象驻售。
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í)例(對(duì)象)征峦!
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ī)智的未來(lái)司機(jī)肯定obj.getName()()栏笆,
記得有兩個(gè)括號(hào)的哦,只有一個(gè)括號(hào)代表的是執(zhí)行這個(gè)getName函數(shù)然后return 一個(gè)匿名函數(shù)臊泰,要想執(zhí)行這個(gè)匿名函數(shù)再加多一個(gè)括號(hào)蛉加,好那我們就運(yùn)行。
然后彈出:“this window”!
有人肯定問(wèn):剛才你不是說(shuō)getName函數(shù)作為一個(gè)對(duì)象屬性存在缸逃,然后調(diào)用這個(gè)方法针饥,this就指向這個(gè)對(duì)象嗎?
應(yīng)該是“my object”才對(duì)呀察滑!
怎么會(huì)變成“this window”的老鄉(xiāng)打厘!這個(gè)不一樣呀,里面還多了return function() {}的匿名函數(shù)呀贺辰。
這里面就構(gòu)成了一個(gè)閉包呀户盯!咦~閉包什么鬼?其實(shí)閉包在javascript里面可以簡(jiǎn)單的理解為一個(gè)函數(shù)里面嵌套著另外一個(gè)函數(shù)饲化,并且外部的函數(shù)將嵌套的函數(shù)對(duì)象作為一個(gè)返回值返出Cа肌(無(wú)論這個(gè)被返回的函數(shù)對(duì)象是否匿名)大概有點(diǎn)懂了吧!不懂沒關(guān)系吃靠,我們可以先alert(obj.getName())看看是什么東西
哦硫眨,原來(lái)是
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ù)也是對(duì)象棚品,對(duì)象則有方法,apply 和 call 就是函數(shù)對(duì)象的方法廊敌。這兩個(gè)方法異常強(qiáng)大铜跑,他們?cè)试S切換函數(shù)執(zhí)行的上下文環(huán)境(context),即 this 綁定的對(duì)象骡澈。很多 JavaScript 中的技巧以及類庫(kù)都用到了該方法锅纺。通俗的說(shuō):
你首先要知道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ù)選填)
語(yǔ)法: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'.