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