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

資訊專欄INFORMATION COLUMN

不一樣的 this 問題

fizz / 2842人閱讀

摘要:的指向問題是老生常談的難點(diǎn)了。網(wǎng)上也有很多關(guān)于的文章了,本文就簡單說說,再聊點(diǎn)不一樣的。所以箭頭函數(shù)雖然好用,但是不要濫用哦箭頭函數(shù)還常用于數(shù)組的等循環(huán)方法中,比如

JS 的 this 指向問題是老生常談的難點(diǎn)了。我當(dāng)初從 Java 轉(zhuǎn)過來時(shí)極其不適應(yīng),花了好長時(shí)間才擺脫這個(gè)陰影。網(wǎng)上也有很多關(guān)于 this 的文章了,本文就簡單說說,再聊點(diǎn)不一樣的。

this 主要是在函數(shù)中使用,在函數(shù)外使用的話,一律指向全局對象
console.log(this)    // window

var o = {
  global: this       // window
}
在函數(shù)內(nèi)使用 this 時(shí),具體指向是由函數(shù)的調(diào)用方式?jīng)Q定,而不是根據(jù)函數(shù)定義方式?jīng)Q定
1. 函數(shù)作為普通函數(shù)運(yùn)行時(shí),可以看做是當(dāng)做全局對象的方法運(yùn)行,此時(shí) this 指向全局對象
function hello() {
  console.log(this)
}
hello()    // window 作為普通函數(shù)運(yùn)行
2. 函數(shù)作為對象的方法調(diào)用時(shí),函數(shù)內(nèi)的 this 指向該對象

所以上面一條,普通函數(shù)可以看做是全局對象的方法,所以 this 指向全局對象

var name = "global"

var obj = {
  name: "local",
  getName: function () {
    console.log(this.name)
  },
  outer: function () {
    function inner() {
      console.log(this.name) 
    }
    inner()      // 這是第 12 行代碼
  }
}

obj.getName()    // local 作為 obj 的方法調(diào)用,此時(shí) this 指向 obj
obj.outer()      // 打印什么?控制臺(tái)試試吧

這里提到了一個(gè)大家容易忽視的點(diǎn): 嵌套函數(shù)
還記得上面標(biāo)題說的嗎? this 的指向是由函數(shù)的調(diào)用方式來決定的

由于大多數(shù)嵌套函數(shù)是直接被調(diào)用的, 比如:第 12 行代碼,調(diào)用 inner()
這時(shí) inner 是被當(dāng)做普通函數(shù)調(diào)用的,也可以看做是 window.inner() ,所以此時(shí) inner 內(nèi)部的 this 指向 window,打印 global

常見的解決方案如下:

var obj = {
  name: "local",
  outer: function () {
    var that = this
    function inner() {
      console.log(that.name) 
    }
    inner()
  }
}

// 聲明變量 that ,在 inner 內(nèi)部用 that 代替 this
obj.outer()    // local

還有個(gè)問題

var name = "global"
var obj = {
  name: "local",
  getName: function () {
    console.log(this.name)
  }
}

obj.getName()    // local
var getName = obj.getName
getName()     // ?

直接調(diào)用 getName() 會(huì)打印 global
還是前面說的,雖然 obj.getName() 在聲明的時(shí)候是作為 obj 的方法
但是把它賦值給 getName, 再調(diào)用 getName() 和 obj.getName() 的調(diào)用方式已經(jīng)不同了

3. apply call bind 改變 this 指向

這個(gè)沒啥還說的,強(qiáng)制改變 this 的指向,bind 的優(yōu)先級最高。

var name = "global"
var obj = {
  name: "local",
  getName: function () {
    console.log(this.name)
  }
}

var obj2 = {
  name: "xiaoming"
}

var obj3 = {
  name: "laowang"
}

obj.getName()     // local
obj.getName.call(obj2)    // xiaoming

var getName = obj.getName.bind(obj3)    // 將 getName 內(nèi)部的 this 綁定到 obj3
getName()     // laowang 不再是 window

getName.call(obj2)    // laowang
                      // bind 不會(huì)受到 apply 和 call 影響
4. 定時(shí)器設(shè)置的函數(shù),this 會(huì)指向全局
var name = "global"
var obj = {
  name: "local",
  getName: function () {
    console.log(this.name)
  }
}

var obj3 = {
  name: "laowang"
}

setTimeout(obj.getName, 1000)            // global
setTimeout(obj.getName.bind(obj3), 2000) // laowang

bind 強(qiáng)制綁定優(yōu)先級最高,不受定時(shí)器影響
正確調(diào)用方式如下:
外面包一層匿名函數(shù)

setTimeout(function () {
  obj.getName()
}, 1000)            // local
5. ES6 箭頭函數(shù)

ES6 推出了箭頭函數(shù),詳細(xì)教程可以參考阮一峰老師的教程
箭頭函數(shù)沒有自己的 this 和 arguments, 因此在箭頭函數(shù)內(nèi)部使用 this 和 argments, 其實(shí)使用的是外層的 this 和 arguments

var name = "global"
var obj = {
  name: "local",
  getName: () => console.log(this.name),
  outer: function () {
    var inner = () => console.log(this.name)
    inner()
  }
}
obj.getName()    // global 由于箭頭函數(shù)沒有自己的 this,所以 getName 內(nèi)部的 this 其實(shí)是函數(shù)外部的 this,指向全局
obj.outer()      // local

作為函數(shù)的方法,最好不要用箭頭函數(shù),因?yàn)榧^函數(shù)內(nèi)部的 this 不再指向該對象。
所以箭頭函數(shù)雖然好用,但是不要濫用哦

箭頭函數(shù)還常用于數(shù)組的 forEach/map/some/every/filter/reduce 等循環(huán)方法中,比如

var arr = [1, 2, 3].map(item => item * 2)

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

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/86575.html

相關(guān)文章

  • 要再問我this指向問題

    摘要:所以構(gòu)造函數(shù)里的指的就是將要被出來的新對象。希望看完這篇文章之后,再有人問指向的問題,你可以嘴角微微上揚(yáng),冷笑一聲不要再問我的指向問題了。 this的指向已經(jīng)是一個(gè)老生常談的問題,每逢面試都要去復(fù)習(xí)復(fù)習(xí),近來鞏固js的基礎(chǔ),決心徹底掌握這個(gè)知識(shí)點(diǎn),一勞永逸。說明一下,為了不影響大家的思考過程,下面的代碼都不會(huì)去注釋答案,想知道答案,只需要去控制臺(tái)執(zhí)行一下。 四類場景逐一擊破 首先,分析...

    nifhlheimr 評論0 收藏0
  • JavaScript之對象創(chuàng)建

    摘要:在構(gòu)造函數(shù)的內(nèi)部,的指向是新創(chuàng)建的對象。如果構(gòu)造函數(shù)沒有顯式的表達(dá)式,則會(huì)隱式的返回新創(chuàng)建的對象對象。原型模式在構(gòu)造函數(shù)模式中提到每次之后創(chuàng)建的新的對象是互相獨(dú)立的,是獨(dú)享的。 1.構(gòu)造函數(shù)模式 JavaScript中的構(gòu)造函數(shù)是通過new調(diào)用的,也就是說,通過new關(guān)鍵字調(diào)用的函數(shù)都被認(rèn)為是構(gòu)造函數(shù)。 在構(gòu)造函數(shù)的內(nèi)部,this的指向是新創(chuàng)建的對象Object。 如果構(gòu)造函數(shù)沒有顯式...

    Michael_Lin 評論0 收藏0
  • Js基礎(chǔ)知識(shí)(二) - 原型鏈與繼承精彩講解

    摘要:有了原型鏈,就有了繼承,繼承就是一個(gè)對象像繼承遺產(chǎn)一樣繼承從它的構(gòu)造函數(shù)中獲得一些屬性的訪問權(quán)。這里其實(shí)就是一個(gè)原型鏈與繼承的典型例子,開發(fā)中可能構(gòu)造函數(shù)復(fù)雜一點(diǎn),屬性定義的多一些,但是原理都是一樣的。 作用域、原型鏈、繼承與閉包詳解 注意:本章講的是在es6之前的原型鏈與繼承。es6引入了類的概念,只是在寫法上有所不同,原理是一樣的。 幾個(gè)面試常問的幾個(gè)問題,你是否知道 insta...

    mrcode 評論0 收藏0
  • Js基礎(chǔ)知識(shí)(二) - 原型鏈與繼承精彩講解

    摘要:有了原型鏈,就有了繼承,繼承就是一個(gè)對象像繼承遺產(chǎn)一樣繼承從它的構(gòu)造函數(shù)中獲得一些屬性的訪問權(quán)。這里其實(shí)就是一個(gè)原型鏈與繼承的典型例子,開發(fā)中可能構(gòu)造函數(shù)復(fù)雜一點(diǎn),屬性定義的多一些,但是原理都是一樣的。 作用域、原型鏈、繼承與閉包詳解 注意:本章講的是在es6之前的原型鏈與繼承。es6引入了類的概念,只是在寫法上有所不同,原理是一樣的。 幾個(gè)面試常問的幾個(gè)問題,你是否知道 insta...

    lingdududu 評論0 收藏0

發(fā)表評論

0條評論

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