亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

針對還沒搞懂javascript中this關鍵字的同學

Riddler / 3624人閱讀

摘要:雖然方法定義在對象里面,但是使用方法后,將方法里面的指向了。本文都是在非嚴格模式下的情況。在構造函數內部的內的回調函數,始終指向實例化的對象,并獲取實例化對象的的屬性每這個屬性的值都會增加。否則最后在后執(zhí)行函數執(zhí)行后輸出的是

本篇文章主要針對搞不清this指向的的同學們!不定期更新文章都是我學習過程中積累下的經驗,還請大家多多關注我的文章以幫助更多的同學,不對的地方還望留言支持改進!

首先,必須搞清楚在JS里面,函數的幾種調用方式:
1.普通函數調用
2.作為方法來調用
3.作為構造函數來調用
4.使用apply/call方法來調用
5.Function.prototype.bind方法
6.es6箭頭函數
要點:不管函數以何種方式來調用,誰調用這個函數或方法,this關鍵字就指向誰,牢記這一點。!important

下面我將對每個方法進行實例講解!

1.普通函數調用
(function fun(){
        this.name="segmentfault";
        console.log(this);  //window
        console.log(this.name);  //segmentfault        
})()
console.log(window.name);  //segmentfault  由此可見name屬性屬于window的屬性。

在這段代碼中fun函數作為普通函數調用,實際上fun是作為全局對象window的一個方法來進行調用的(這點大家應該都知道),即window.fun();所以這個地方是window對象調用了fun方法,那么fun函數當中的this即指window,同時window還擁有了另外一個屬性name,值為segmentfault.

2.作為方法來調用

var name="segmentfault";
var fun={

name:"segmentfault-A",
showName:function(){
    console.log(this.name);  //輸出  segmentfault-A
}

}
fun.showName();
//這里是fun對象調用showName方法,很顯然this關鍵字是指向fun對象的,所以會輸出name

var funA = fun.showName;
funA(); //輸出 segmentfault
//這里將fun.showName方法賦給funA變量,此時funA變量相當于window對象的一個屬性,因此showNameA()執(zhí)行的時候相當于window.funA(),即window對象調用funA這個方法,所以this關鍵字指向window
換種方式看看:

var funA={
    name:"segmentfault",
    showName:function(){
        console.log(this.name);
    }
}
var funB={
    name:"segmentfault-A",
    sayName:funA.showName
}

funB.sayName();  //輸出 segmentfault-A
//雖然showName方法是在funA這個對象中定義,但是調用的時候卻是在funB這個對象中調用,因此this對象指向funB
3.作為構造函數來調用
function fun(name){
    this.name=name;
}
var funA = fun("segmentfault");   
console.log(funA.name); // 輸出  undefined
console.log(window.name);//輸出  segmentfault
//上面代碼沒有進行new操作,相當于window對象調用fun("segmentfault")方法,那么this指向window對象,并進行賦值操作window.name="segmentfault".

var funB=new fun("segmentfault");
console.log(funB.name);// 輸出 segmentfault
4.call/apply方法的調用

在JS里函數也是對象,因此函數也有方法。從Function.prototype上繼承到Function.prototype.call/Function.prototype.apply方法
call/apply方法最大的作用就是能改變this關鍵字的指向.

Obj.method.apply(AnotherObj,arguments);

var name="segmentfault-A";
var fun={
    name:"segmentfault",
    showName:function(){
        console.log(this.name);
    }
}
fun.showName.call(); //輸出 "segmentfault-A"
//這里call方法里面的第一個參數為空,默認指向window。
//雖然showName方法定義在fun對象里面,但是使用call方法后,將showName方法里面的this指向了window。因此最后會輸出"segmentfault-A";
function FruitA(n1,n2){
    this.n1=n1;
    this.n2=n2;
    this.change=function(x,y){
        this.n1=x;
        this.n2=y;
    }
}

var fruitA = new FruitA("cheery","banana");
var FruitB={
    n1:"apple",
    n2:"orange"
};
fruitA.change.call(FruitB,"pear","peach");

console.log(FruitB.n1); //輸出 pear
console.log(FruitB.n2);// 輸出 peach

FruitB調用fruitA的change方法,將fruitA中的this綁定到對象FruitB上。

5.Function.prototype.bind()方法
 var name="segmentfault-A";
function fun(name){
    this.name=name;
    this.sayName=function(){
        setTimeout(function(){
            console.log("my name is "+this.name);
        },50)
    }
}
var funA = new fun("segmentfault");
funA.sayName()  //輸出  “my name is segmentfault-A”;
//這里的setTimeout()定時函數,相當于window.setTimeout(),由window這個全局對象對調用,因此this的指向為window, 則this.name則為segmentfault-A

下面用bind()方法就可以輸出segmentfault

var name="segmentfault";
function fun(name){
    this.name=name;
    this.sayName=function(){
        setTimeout(function(){
            console.log("my name is "+this.name);
        }.bind(this),50)  //注意這個地方使用的bind()方法,綁定setTimeout里面的匿名函數的this一直指向fun對象
    }
}
var funA = new fun("segmentfault");
funA.sayName()  //輸出  “my name is segmentfault”;
//這里的setTimeout()定時函數,相當于window.setTimeout(),由window這個全局對象對調用,因此this的指向為window, 則this.name則為segmentfault

這里setTimeout(function(){console.log(this.name)}.bind(this),50);,匿名函數使用bind(this)方法后創(chuàng)建了新的函數,這個新的函數不管在什么地方執(zhí)行,this都指向的fun,而非window,因此最后的輸出為"my name is segmentfault"而不是"my name is segmentfault-A"

另外幾個需要注意的地方:
setTimeout/setInterval/匿名函數執(zhí)行的時候,this默認指向window對象,除非手動改變this的指向。在《javascript高級程序設計》當中,寫到:“超時調用的代碼(setTimeout)都是在全局作用域中執(zhí)行的,因此函數中的this的值,在非嚴格模式下是指向window對象,在嚴格模式下是指向undefined”。本文都是在非嚴格模式下的情況。

6.Eval函數

該函數執(zhí)行的時候,this綁定到當前作用域的對象上

var name="segmentfault-A";
var fun = {
    name:"segmentfault",
    showName:function(){
        eval("console.log(this.name)");
    }
}

fun.showName();  //輸出  "segmentfault"

var a = fun.showName;
a();  //輸出  "segmentfault-A"
7.箭頭函數

es6里面this指向固定化,始終指向外部對象,因為箭頭函數沒有this,因此它自身不能進行new實例化,同時也不能使用call, apply, bind等方法來改變this的指向。

 function Timer() {
    this.seconds = 0;
    setInterval( () => this.seconds ++, 1000);
} 

var timer = new Timer();

setTimeout( () => console.log(timer.seconds), 3000);

// 3
   // 在構造函數內部的setInterval()內的回調函數,this始終指向實例化的對象,并獲取實例化對象的seconds的屬性,每1s這個屬性的值都會增加1。否則最后在3s后執(zhí)行setTimeOut()函數執(zhí)行后輸出的是0
   

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

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/108297.html

相關文章

  • 還沒搞懂this?

    摘要:一前言關鍵字是中最復雜的機制之一。對于那些沒有投入時間學習機制的開發(fā)者來說,的指向一直是一件非常令人困惑的事。隨著函數使用場合的不同,的值會發(fā)生變化。還可以傳值,在嚴格模式下和非嚴格模式下,得到值不一樣。 一、前言 this關鍵字是JavaScript中最復雜的機制之一。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。對于那些沒有投入時間學習this機制的JavaScript開...

    dance 評論0 收藏0
  • 還沒搞懂this?

    摘要:一前言關鍵字是中最復雜的機制之一。對于那些沒有投入時間學習機制的開發(fā)者來說,的指向一直是一件非常令人困惑的事。隨著函數使用場合的不同,的值會發(fā)生變化。還可以傳值,在嚴格模式下和非嚴格模式下,得到值不一樣。 一、前言 this關鍵字是JavaScript中最復雜的機制之一。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。對于那些沒有投入時間學習this機制的JavaScript開...

    linkin 評論0 收藏0
  • 如果你還沒搞懂LSTM 網絡,那本文絕對值得一看

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

    shadowbook 評論0 收藏0
  • this學習筆記

    摘要:但是有一個總的原則,那就是指的是,調用函數的那個對象作為函數調用在函數被直接調用時綁定到全局對象。這一過程分為三步創(chuàng)建類的實例。這步是把一個空的對象的屬性設置為。函數被傳入參數并調用,關鍵字被設定為該實例。 this 的值到底是什么?一次說清楚你怎么還沒搞懂 this?this、apply、call、bind 一、Whats this? 由于運行期綁定的特性,JavaScript 中的...

    nanfeiyan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<