国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

你還沒(méi)搞懂this?

linkin / 751人閱讀

摘要:一前言關(guān)鍵字是中最復(fù)雜的機(jī)制之一。對(duì)于那些沒(méi)有投入時(shí)間學(xué)習(xí)機(jī)制的開(kāi)發(fā)者來(lái)說(shuō),的指向一直是一件非常令人困惑的事。隨著函數(shù)使用場(chǎng)合的不同,的值會(huì)發(fā)生變化。還可以傳值,在嚴(yán)格模式下和非嚴(yán)格模式下,得到值不一樣。

一、前言

this關(guān)鍵字是JavaScript中最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在所有函數(shù)的作用域中。對(duì)于那些沒(méi)有投入時(shí)間學(xué)習(xí)this機(jī)制的JavaScript開(kāi)發(fā)者來(lái)說(shuō),this的指向一直是一件非常令人困惑的事。

二、了解this

學(xué)習(xí)this的第一步是明白this既不指向函數(shù)自身也不指向函數(shù)的詞法作用域,你也許被這樣的解釋誤導(dǎo)過(guò),但其實(shí)它們都是錯(cuò)誤的。隨著函數(shù)使用場(chǎng)合的不同,this的值會(huì)發(fā)生變化。但總有一條原則就是JS中的this代表的是當(dāng)前行為執(zhí)行的主體,在JS中主要研究的都是函數(shù)中的this,但并不是說(shuō)只有在函數(shù)里才有this,this實(shí)際上是在函數(shù)被調(diào)用時(shí)發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用。如何的區(qū)分this呢?

三、this到底是誰(shuí)

這要分情況討論,常見(jiàn)有五種情況:

1、函數(shù)執(zhí)行時(shí)首先看函數(shù)名前面是否有".",有的話(huà),"."前面是誰(shuí),this就是誰(shuí);沒(méi)有的話(huà)this就是window
function fn(){
  console.log(this);
}
var obj={fn:fn};
fn();//this->window
obj.fn();//this->obj
function sum(){
     fn();//this->window
}
sum();
var oo={
 sum:function(){
 console.log(this);//this->oo
       fn();//this->window
  }
};
oo.sum();
2、自執(zhí)行函數(shù)中的this永遠(yuǎn)是window
  (function(){ //this->window })();
  ~function(){ //this->window }();
3、給元素的某一個(gè)事件綁定方法,當(dāng)事件觸發(fā)的時(shí)候,執(zhí)行對(duì)應(yīng)的方法,方法中的this是當(dāng)前的元素,除了IE6~8下使用attachEvent(IE一個(gè)著名的bug)

DOM零級(jí)事件綁定

  oDiv.onclick=function(){
     //this->oDiv
  };

DOM二級(jí)事件綁定

  oDiv.addEventListener("click",function(){
     //this->oDiv
  },false);

在IE6~8下使用attachEvent,默認(rèn)的this就是指的window對(duì)象

  oDiv.attachEvent("click",function(){
       //this->window
  });

我們大多數(shù)時(shí)候,遇到事件綁定,如下面例子這種,對(duì)于IE6~8下使用attachEvent不必太較真

function fn(){
  console.log(this);
}
document.getElementById("div1").onclick=fn;//fn中的this就是#divl
document.getElementById("div1").onclick=function(){
console.log(this);//this->#div1
fn();//this->window
};
4、在構(gòu)造函數(shù)模式中,類(lèi)中(函數(shù)體中)出現(xiàn)的this.xxx=xxx中的this是當(dāng)前類(lèi)的一個(gè)實(shí)例
function CreateJsPerson(name,age){
//瀏覽器默認(rèn)創(chuàng)建的對(duì)象就是我們的實(shí)例p1->this
this.name=name;//->p1.name=name
this.age=age;
this.writeJs=function(){
console.log("my name is"+this.name +",i can write Js");
   };
//瀏覽器再把創(chuàng)建的實(shí)例默認(rèn)的進(jìn)行返回
}
var p1=new CreateJsPerson("尹華芝",48);

必須要注意一點(diǎn):類(lèi)中某一個(gè)屬性值(方法),方法中的this需要看方法執(zhí)行的時(shí)候,前面是否有".",才能知道this是誰(shuí)。大家不妨看下接下來(lái)的這個(gè)例子,就可明白是啥意思。

function Fn(){
this.x=100;//this->f1
this.getX=function(){
console.log(this.x);//this->需要看getX執(zhí)行的時(shí)候才知道
   }
}
var f1=new Fn;
f1.getX();//->方法中的this是f1,所以f1.x=100
var ss=f1.getX;
ss();//->方法中的this是window ->undefined
5.call、apply和bind

我們先來(lái)看一個(gè)問(wèn)題,想在下面的例子中this綁定obj,怎么實(shí)現(xiàn)?

var obj={name:"浪里行舟"};
function fn(){
console.log(this);//this=>window
}
fn();
obj.fn();//->Uncaught TypeError:obj.fn is not a function

如果直接綁定obj.fn(),程序就會(huì)報(bào)錯(cuò)。這里我們應(yīng)該用fn.call(obj)就可以實(shí)現(xiàn)this綁定obj,接下來(lái)我們?cè)敿?xì)介紹下call方法:

call方法的作用:

①首先我們讓原型上的call方法執(zhí)行,在執(zhí)行call方法的時(shí)候,我們讓fn方法中的this變?yōu)榈谝粋€(gè)參數(shù)值obj;然后再把fn這個(gè)函數(shù)執(zhí)行。

②call還可以傳值,在嚴(yán)格模式下和非嚴(yán)格模式下,得到值不一樣。

//在非嚴(yán)格模式下
var obj={name:"浪里行舟 "};
function fn(num1,num2){
console.log(num1+num2);
console.log(this);
}
fn.call(100,200);//this->100 num1=200 num2=undefined
fn.call(obj,100,200);//this->obj num1=100 num2=200
fn.call();//this->window
fn.call(null);//this->window
fn.call(undefined);//this->window
//嚴(yán)格模式下 
fn.call();//在嚴(yán)格模式下this->undefined
fn.call(null);// 在嚴(yán)格模式 下this->null
fn.call(undefined);//在嚴(yán)格模式下this->undefined

**apply和call方法的作用是一模一樣的,都是用來(lái)改變方法的this關(guān)鍵字并且把方法

執(zhí)行,而且在嚴(yán)格模式下和非嚴(yán)格模式下對(duì)于第一個(gè)參數(shù)是null/undefined這種情況的規(guī)
律也是一樣的。**

兩者唯一的區(qū)別:call在給fn傳遞參數(shù)的時(shí)候,是一個(gè)個(gè)的傳遞值的,而apply不是一個(gè)個(gè)傳,而是把要給fn傳遞的參數(shù)值統(tǒng)一的放在一個(gè)數(shù)組中進(jìn)行操作。但是也相當(dāng)子一個(gè)個(gè)的給fn的形參賦值。總結(jié)一句話(huà):call第二個(gè)參數(shù)開(kāi)始接受一個(gè)參數(shù)列表,apply第二個(gè)參數(shù)開(kāi)始接受一個(gè)參數(shù)數(shù)組

fn.call(obj,100,200);
fn.apply(obj,[100,200]);

bind:這個(gè)方法在IE6~8下不兼容,和call/apply類(lèi)似都是用來(lái)改變this關(guān)鍵字的,但是和這兩者有明顯區(qū)別:

fn.call(obj,1,2);//->改變this和執(zhí)行fn函數(shù)是一起都完成了
fn.bind(obj,1,2);//->只是改變了fn中的this為obj,并且給fn傳遞了兩個(gè)參數(shù)值1、2,
                     但是此時(shí)并沒(méi)有把fn這個(gè)函數(shù)執(zhí)行
var tempFn=fn.bind(obj,1,2);
tempFn(); //這樣才把fn這個(gè)函數(shù)執(zhí)行

bind體現(xiàn)了預(yù)處理思想:事先把fn的this改變?yōu)槲覀兿胍慕Y(jié)果,并且把對(duì)應(yīng)的參數(shù)值也準(zhǔn)備好,以后要用到了,直接的執(zhí)行即可。

call和apply直接執(zhí)行函數(shù),而bind需要再一次調(diào)用。

  var a ={
        name : "Cherry",
        fn : function (a,b) {
            console.log( a + b)
        }
    }
  var b = a.fn;
  b.bind(a,1,2)

上述代碼沒(méi)有執(zhí)行,bind返回改變了上下文的一個(gè)函數(shù),我們必須要手動(dòng)去調(diào)用:

 b.bind(a,1,2)() //3

必須要聲明一點(diǎn):遇到第五種情況(call apply和bind),前面四種全部讓步。

四、箭頭函數(shù)this指向

箭頭函數(shù)正如名稱(chēng)所示那樣使用一個(gè)“箭頭”(=>)來(lái)定義函數(shù)的新語(yǔ)法,但它優(yōu)于傳統(tǒng)的函數(shù),主要體現(xiàn)兩點(diǎn):更簡(jiǎn)短的函數(shù)并且不綁定this

var obj = {
    birth: 1990,
    getAge: function () {
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - this.birth; // this指向window或undefined
        };
        return fn();
    }
};

現(xiàn)在,箭頭函數(shù)完全修復(fù)了this的指向,箭頭函數(shù)沒(méi)有自己的this,箭頭函數(shù)的this不是調(diào)用的時(shí)候決定的,而是在定義的時(shí)候處在的對(duì)象就是它的this

換句話(huà)說(shuō),箭頭函數(shù)的this看外層的是否有函數(shù),如果有,外層函數(shù)的this就是內(nèi)部箭頭函數(shù)的this,如果沒(méi)有,則this是window

    
    
    

上例中,由于箭頭函數(shù)不會(huì)創(chuàng)建自己的this,它只會(huì)從自己的作用域鏈的上一層繼承this。其實(shí)可以簡(jiǎn)化為如下代碼:

   let btn1 = document.getElementById("btn1");
        let obj = {
            name: "kobe",
            age: 39,
            getName: function () {
                console.log(this)
            }
        };
   obj.getName();

那假如上一層并不存在函數(shù),this指向又是誰(shuí)?

    
    
    

上例中,雖然存在兩個(gè)箭頭函數(shù),其實(shí)this取決于最外層的箭頭函數(shù),由于obj是個(gè)對(duì)象而非函數(shù),所以this指向?yàn)閃indow對(duì)象

由于this在箭頭函數(shù)中已經(jīng)按照詞法作用域綁定了,所以,用call()或者apply()調(diào)用箭頭函數(shù)時(shí),無(wú)法對(duì)this進(jìn)行綁定,即傳入的第一個(gè)參數(shù)被忽略

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2018); // 28

文章于2018.9.25重新修改,如果文章對(duì)你有些許幫助,歡迎在我的GitHub博客點(diǎn)贊和關(guān)注,感激不盡!

參考文章 廖雪峰的官方網(wǎng)站 JS中的箭頭函數(shù)與this this、apply、call、bind

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98355.html

相關(guān)文章

  • 你還沒(méi)搞懂this

    摘要:一前言關(guān)鍵字是中最復(fù)雜的機(jī)制之一。對(duì)于那些沒(méi)有投入時(shí)間學(xué)習(xí)機(jī)制的開(kāi)發(fā)者來(lái)說(shuō),的指向一直是一件非常令人困惑的事。隨著函數(shù)使用場(chǎng)合的不同,的值會(huì)發(fā)生變化。還可以傳值,在嚴(yán)格模式下和非嚴(yán)格模式下,得到值不一樣。 一、前言 this關(guān)鍵字是JavaScript中最復(fù)雜的機(jī)制之一。它是一個(gè)很特別的關(guān)鍵字,被自動(dòng)定義在所有函數(shù)的作用域中。對(duì)于那些沒(méi)有投入時(shí)間學(xué)習(xí)this機(jī)制的JavaScript開(kāi)...

    dance 評(píng)論0 收藏0
  • 如果你還沒(méi)搞懂LSTM 網(wǎng)絡(luò),那本文絕對(duì)值得一看

    摘要:有能力對(duì)元胞狀態(tài)添加或者刪除信息,這種能力通過(guò)一種叫門(mén)的結(jié)構(gòu)來(lái)控制。一個(gè)有個(gè)這種門(mén),來(lái)保護(hù)和控制元胞狀態(tài)。輸出將會(huì)基于目前的元胞狀態(tài),并且會(huì)加入一些過(guò)濾。同時(shí)也將元胞狀態(tài)和隱狀態(tài)合并,同時(shí)引入其他的一些變化。 循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)人們的每次思考并不都是從零開(kāi)始的。比如說(shuō)你在閱讀這篇文章時(shí),你基于對(duì)前面的文字的理解來(lái)理解你目前閱讀到的文字,而不是每讀到一個(gè)文字時(shí),都拋棄掉前面的思考,從頭開(kāi)始...

    shadowbook 評(píng)論0 收藏0
  • 針對(duì)還沒(méi)搞懂javascript中this關(guān)鍵字的同學(xué)

    摘要:雖然方法定義在對(duì)象里面,但是使用方法后,將方法里面的指向了。本文都是在非嚴(yán)格模式下的情況。在構(gòu)造函數(shù)內(nèi)部的內(nèi)的回調(diào)函數(shù),始終指向?qū)嵗膶?duì)象,并獲取實(shí)例化對(duì)象的的屬性每這個(gè)屬性的值都會(huì)增加。否則最后在后執(zhí)行函數(shù)執(zhí)行后輸出的是 本篇文章主要針對(duì)搞不清this指向的的同學(xué)們!不定期更新文章都是我學(xué)習(xí)過(guò)程中積累下的經(jīng)驗(yàn),還請(qǐng)大家多多關(guān)注我的文章以幫助更多的同學(xué),不對(duì)的地方還望留言支持改進(jìn)! ...

    Riddler 評(píng)論0 收藏0
  • java集合--Iterator接口

    摘要:其實(shí),來(lái)源于包,也是屬于集合框架中的一份子,不同于存放單一數(shù)據(jù)和存放具有映射關(guān)系的數(shù)據(jù),主要用于集合元素的迭代輸出,所以它的對(duì)象又被稱(chēng)為迭代器。 ????上一篇文章中我在集合元素的遍歷中已經(jīng)有涉及到Iterator的普遍使用方法,但是并沒(méi)有對(duì)此進(jìn)行解釋。????其實(shí),Iterator來(lái)源于java.util包,也是屬于Java集合框架中的一份子,不同于Collection(存放單一數(shù)據(jù)...

    xfee 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<