欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中this詳解

 更新時(shí)間:2015年09月01日 17:26:16   投稿:mrr  
都說 JavaScript 是一種很靈活的語言,這其實(shí)也可以說它是一個(gè)混亂的語言。它把函數(shù)式編程和面向?qū)ο缶幊挑酆弦黄?,再加上?dòng)態(tài)語言特性,簡直強(qiáng)大無比,下面小編給大家介紹Javascript中this詳解,需要的小伙伴可以來參考下

這里的主題是 this ,不扯遠(yuǎn)了。this 本身原本很簡單,總是指向類的當(dāng)前實(shí)例,this 不能賦值。這前提是說 this 不能脫離 類/對象 來說,也就是說 this 是面向?qū)ο笳Z言里常見的一個(gè)關(guān)鍵字。說的極端點(diǎn),如果你編寫的 JS 采用函數(shù)式寫法,而不是面向?qū)ο笫?,你所有的代碼里 this 會(huì)少很多,甚至沒有。記住這一點(diǎn),當(dāng)你使用 this 時(shí),你應(yīng)該是在使用對象/類 方式開發(fā),否則 this 只是函數(shù)調(diào)用時(shí)的副作用。

JavaScript中的this總是讓人迷惑,應(yīng)該是js眾所周知的坑之一。 個(gè)人也覺得js中的this不是一個(gè)好的設(shè)計(jì),由于this晚綁定的特性,它可以是全局對象,當(dāng)前對象,或者…有人甚至因?yàn)榭哟蠖挥胻his。

其實(shí)如果完全掌握了this的工作原理,自然就不會(huì)走進(jìn)這些坑。來看下以下這些情況中的this分別會(huì)指向什么:

1.全局代碼中的this

alert(this)
//window

全局范圍內(nèi)的this將會(huì)指向全局對象,在瀏覽器中即使window。

2.作為單純的函數(shù)調(diào)用

function fooCoder(x) {
 this.x = x;
}
fooCoder(2);
alert(x);
// 全局變量x值為2

這里this指向了全局對象,即window。在嚴(yán)格模式中,則是undefined。

3.作為對象的方法調(diào)用

var name = "clever coder";
var person = {
 name : "foocoder",
 hello : function(sth){
  console.log(this.name + " says " + sth);
 }
}
person.hello("hello world");

輸出 foocoder says hello world。this指向person對象,即當(dāng)前對象。

4.作為構(gòu)造函數(shù)

new FooCoder();

函數(shù)內(nèi)部的this指向新創(chuàng)建的對象。

5.內(nèi)部函數(shù)

var name = "clever coder";
var person = {
 name : "foocoder",
 hello : function(sth){
  var sayhello = function(sth) {
   console.log(this.name + " says " + sth);
  };
  sayhello(sth);
 }
}
person.hello("hello world");
//clever coder says hello world

在內(nèi)部函數(shù)中,this沒有按預(yù)想的綁定到外層函數(shù)對象上,而是綁定到了全局對象。這里普遍被認(rèn)為是JavaScript語言的設(shè)計(jì)錯(cuò)誤,因?yàn)闆]有人想讓內(nèi)部函數(shù)中的this指向全局對象。一般的處理方式是將this作為變量保存下來,一般約定為that或者self:

var name = "clever coder";
var person = {
 name : "foocoder",
 hello : function(sth){
  var that = this;
  var sayhello = function(sth) {
   console.log(that.name + " says " + sth);
  };
  sayhello(sth);
 }
}
person.hello("hello world");
//foocoder says hello world

6.使用call和apply設(shè)置this

person.hello.call(person, "world");

apply和call類似,只是后面的參數(shù)是通過一個(gè)數(shù)組傳入,而不是分開傳入。兩者的方法定義:

call( thisArg [,arg1,arg2,… ] ); 
// 參數(shù)列表,arg1,arg2,...
apply(thisArg [,argArray] );  
// 參數(shù)數(shù)組,argArray

兩者都是將某個(gè)函數(shù)綁定到某個(gè)具體對象上使用,自然此時(shí)的this會(huì)被顯式的設(shè)置為第一個(gè)參數(shù)。

簡單地總結(jié)

簡單地總結(jié)以上幾點(diǎn),可以發(fā)現(xiàn),其實(shí)只有第六點(diǎn)是讓人疑惑的。

其實(shí)就可以總結(jié)為以下幾點(diǎn):

1.當(dāng)函數(shù)作為對象的方法調(diào)用時(shí),this指向該對象。

2.當(dāng)函數(shù)作為淡出函數(shù)調(diào)用時(shí),this指向全局對象(嚴(yán)格模式時(shí),為undefined)

3.構(gòu)造函數(shù)中的this指向新創(chuàng)建的對象

4.嵌套函數(shù)中的this不會(huì)繼承上層函數(shù)的this,如果需要,可以用一個(gè)變量保存上層函數(shù)的this。

再總結(jié)的簡單點(diǎn),如果在函數(shù)中使用了this,只有在該函數(shù)直接被某對象調(diào)用時(shí),該this才指向該對象。

obj.foocoder();
foocoder.call(obj, ...);
foocoder.apply(obj, …);

更進(jìn)一步

我們可能經(jīng)常會(huì)寫這樣的代碼:

$("#some-ele").click = obj.handler;

如果在handler中用了this,this會(huì)綁定在obj上么?顯然不是,賦值以后,函數(shù)是在回調(diào)中執(zhí)行的,this會(huì)綁定到$(“#some-div”)元素上。這就需要理解函數(shù)的執(zhí)行環(huán)境。本文不打算長篇贅述函數(shù)的執(zhí)行環(huán)境,可以參考《javascript高級程序設(shè)計(jì)》中對執(zhí)行環(huán)境和作用域鏈的相關(guān)介紹。這里要指出的時(shí),理解js函數(shù)的執(zhí)行環(huán)境,會(huì)更好地理解this。

那我們?nèi)绾文芙鉀Q回調(diào)函數(shù)綁定的問題?ES5中引入了一個(gè)新的方法,bind():

fun.bind(thisArg[, arg1[, arg2[, ...]]])
 thisArg

當(dāng)綁定函數(shù)被調(diào)用時(shí),該參數(shù)會(huì)作為原函數(shù)運(yùn)行時(shí)的this指向.當(dāng)使用new 操作符調(diào)用綁定函數(shù)時(shí),該參數(shù)無效.

arg1, arg2, ...

當(dāng)綁定函數(shù)被調(diào)用時(shí),這些參數(shù)加上綁定函數(shù)本身的參數(shù)會(huì)按照順序作為原函數(shù)運(yùn)行時(shí)的參數(shù).
該方法創(chuàng)建一個(gè)新函數(shù),稱為綁定函數(shù),綁定函數(shù)會(huì)以創(chuàng)建它時(shí)傳入bind方法的第一個(gè)參數(shù)作為this,傳入bind方法的第二個(gè)以及以后的參數(shù)加上綁定函數(shù)運(yùn)行時(shí)本身的參數(shù)按照順序作為原函數(shù)的參數(shù)來調(diào)用原函數(shù).

顯然bind方法可以很好地解決上述問題。

$("#some-ele").click(person.hello.bind(person));
//相應(yīng)元素被點(diǎn)擊時(shí),輸出foocoder says hello world

其實(shí)該方法也很容易模擬,我們看下Prototype.js中bind方法的源碼:

Function.prototype.bind = function(){
 var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift();
 return function(){
 return fn.apply(object,
  args.concat(Array.prototype.slice.call(arguments)));
 };
};

相信看完全文以后,this不再是坑~,大家都明白了嗎,欲了解更多請點(diǎn)擊腳本之家的網(wǎng)站學(xué)習(xí)。

相關(guān)文章

  • javascript 對象比較實(shí)現(xiàn)代碼

    javascript 對象比較實(shí)現(xiàn)代碼

    js對象比較實(shí)現(xiàn)代碼。
    2009-04-04
  • js的閉包的一個(gè)示例說明

    js的閉包的一個(gè)示例說明

    js中 某個(gè)函數(shù)的內(nèi)部函數(shù)在該函數(shù)執(zhí)行結(jié)束后仍然可以訪問這個(gè)函數(shù)中定義的變量,這稱為閉包(Closure)
    2008-11-11
  • Express結(jié)合Webpack的全棧自動(dòng)刷新

    Express結(jié)合Webpack的全棧自動(dòng)刷新

    現(xiàn)在,webpack可以說是最流行的模塊加載器一方面,它為前端靜態(tài)資源的組織和管理提供了相對較完善的解決方案,另一方面,它也很大程度上改變了前端開發(fā)的工作流程。下面小編來和大家一起學(xué)習(xí)
    2019-05-05
  • es6 filter() 數(shù)組過濾方法總結(jié)

    es6 filter() 數(shù)組過濾方法總結(jié)

    這篇文章主要介紹了es6 filter() 數(shù)組過濾方法總結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • js中作用域的實(shí)例解析

    js中作用域的實(shí)例解析

    本文主要通過幾個(gè)實(shí)例對js中作用域進(jìn)行詳細(xì)解析,具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • javaScript實(shí)現(xiàn)網(wǎng)頁版的彈球游戲

    javaScript實(shí)現(xiàn)網(wǎng)頁版的彈球游戲

    這篇文章主要為大家詳細(xì)介紹了javaScript實(shí)現(xiàn)網(wǎng)頁版的彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • js實(shí)現(xiàn)旋轉(zhuǎn)木馬效果

    js實(shí)現(xiàn)旋轉(zhuǎn)木馬效果

    本文主要介紹了js實(shí)現(xiàn)旋轉(zhuǎn)木馬效果的實(shí)例。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • swiper插件自定義切換箭頭按鈕

    swiper插件自定義切換箭頭按鈕

    這篇文章主要為大家詳細(xì)介紹了swiper插件自定義切換箭頭按鈕,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • JS之延時(shí)器和定時(shí)器執(zhí)行示例詳解

    JS之延時(shí)器和定時(shí)器執(zhí)行示例詳解

    這篇文章主要為大家介紹了JS之延時(shí)器和定時(shí)器執(zhí)行示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • 淺談window對象的scrollBy()方法

    淺談window對象的scrollBy()方法

    本文給大家介紹的是windows對象中的scrollBy()的定義和使用方法,十分的細(xì)致全面,有需要的小伙伴可以參考下。
    2015-07-07

最新評論