摘要:的指向問題是老生常談的難點了。網(wǎng)上也有很多關(guān)于的文章了,本文就簡單說說,再聊點不一樣的。所以箭頭函數(shù)雖然好用,但是不要濫用哦箭頭函數(shù)還常用于數(shù)組的等循環(huán)方法中,比如
JS 的 this 指向問題是老生常談的難點了。我當(dāng)初從 Java 轉(zhuǎn)過來時極其不適應(yīng),花了好長時間才擺脫這個陰影。網(wǎng)上也有很多關(guān)于 this 的文章了,本文就簡單說說,再聊點不一樣的。
console.log(this) // window var o = { global: this // window }在函數(shù)內(nèi)使用 this 時,具體指向是由函數(shù)的調(diào)用方式?jīng)Q定,而不是根據(jù)函數(shù)定義方式?jīng)Q定
function hello() { console.log(this) } hello() // window 作為普通函數(shù)運行
所以上面一條,普通函數(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)用,此時 this 指向 obj obj.outer() // 打印什么?控制臺試試吧
這里提到了一個大家容易忽視的點: 嵌套函數(shù)
還記得上面標(biāo)題說的嗎? this 的指向是由函數(shù)的調(diào)用方式來決定的
由于大多數(shù)嵌套函數(shù)是直接被調(diào)用的, 比如:第 12 行代碼,調(diào)用 inner()
這時 inner 是被當(dāng)做普通函數(shù)調(diào)用的,也可以看做是 window.inner() ,所以此時 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
還有個問題
var name = "global" var obj = { name: "local", getName: function () { console.log(this.name) } } obj.getName() // local var getName = obj.getName getName() // ?
直接調(diào)用 getName() 會打印 global
還是前面說的,雖然 obj.getName() 在聲明的時候是作為 obj 的方法
但是把它賦值給 getName, 再調(diào)用 getName() 和 obj.getName() 的調(diào)用方式已經(jī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 不會受到 apply 和 call 影響
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 強制綁定優(yōu)先級最高,不受定時器影響
正確調(diào)用方式如下:
外面包一層匿名函數(shù)
setTimeout(function () { obj.getName() }, 1000) // local
ES6 推出了箭頭函數(shù),詳細教程可以參考阮一峰老師的教程
箭頭函數(shù)沒有自己的 this 和 arguments, 因此在箭頭函數(shù)內(nèi)部使用 this 和 argments, 其實使用的是外層的 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ù)外部的 this,指向全局 obj.outer() // local
作為函數(shù)的方法,最好不要用箭頭函數(shù),因為箭頭函數(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://systransis.cn/yun/86575.html
摘要:所以構(gòu)造函數(shù)里的指的就是將要被出來的新對象。希望看完這篇文章之后,再有人問指向的問題,你可以嘴角微微上揚,冷笑一聲不要再問我的指向問題了。 this的指向已經(jīng)是一個老生常談的問題,每逢面試都要去復(fù)習(xí)復(fù)習(xí),近來鞏固js的基礎(chǔ),決心徹底掌握這個知識點,一勞永逸。說明一下,為了不影響大家的思考過程,下面的代碼都不會去注釋答案,想知道答案,只需要去控制臺執(zhí)行一下。 四類場景逐一擊破 首先,分析...
摘要:在構(gòu)造函數(shù)的內(nèi)部,的指向是新創(chuàng)建的對象。如果構(gòu)造函數(shù)沒有顯式的表達式,則會隱式的返回新創(chuàng)建的對象對象。原型模式在構(gòu)造函數(shù)模式中提到每次之后創(chuàng)建的新的對象是互相獨立的,是獨享的。 1.構(gòu)造函數(shù)模式 JavaScript中的構(gòu)造函數(shù)是通過new調(diào)用的,也就是說,通過new關(guān)鍵字調(diào)用的函數(shù)都被認為是構(gòu)造函數(shù)。 在構(gòu)造函數(shù)的內(nèi)部,this的指向是新創(chuàng)建的對象Object。 如果構(gòu)造函數(shù)沒有顯式...
摘要:有了原型鏈,就有了繼承,繼承就是一個對象像繼承遺產(chǎn)一樣繼承從它的構(gòu)造函數(shù)中獲得一些屬性的訪問權(quán)。這里其實就是一個原型鏈與繼承的典型例子,開發(fā)中可能構(gòu)造函數(shù)復(fù)雜一點,屬性定義的多一些,但是原理都是一樣的。 作用域、原型鏈、繼承與閉包詳解 注意:本章講的是在es6之前的原型鏈與繼承。es6引入了類的概念,只是在寫法上有所不同,原理是一樣的。 幾個面試常問的幾個問題,你是否知道 insta...
摘要:有了原型鏈,就有了繼承,繼承就是一個對象像繼承遺產(chǎn)一樣繼承從它的構(gòu)造函數(shù)中獲得一些屬性的訪問權(quán)。這里其實就是一個原型鏈與繼承的典型例子,開發(fā)中可能構(gòu)造函數(shù)復(fù)雜一點,屬性定義的多一些,但是原理都是一樣的。 作用域、原型鏈、繼承與閉包詳解 注意:本章講的是在es6之前的原型鏈與繼承。es6引入了類的概念,只是在寫法上有所不同,原理是一樣的。 幾個面試常問的幾個問題,你是否知道 insta...
閱讀 962·2019-08-30 14:24
閱讀 1001·2019-08-30 14:13
閱讀 1807·2019-08-29 17:21
閱讀 2696·2019-08-29 13:44
閱讀 1667·2019-08-29 11:04
閱讀 453·2019-08-26 10:44
閱讀 2573·2019-08-23 14:04
閱讀 917·2019-08-23 12:08