箭頭函式this指向的陷阱
箭頭函式沒有this
!
箭頭函式沒有this
!!
箭頭函式沒有this
!!!
重要的事情說三遍!
那你可能要問我在箭頭函式中明明可以取到this啊!
function foo() {
this.a = 1
let b = () => console.log(this.a)
b()
}
foo() // 1
以上箭頭函式中的
this
其實是父級作用域中的this
,箭頭函式引用了父級作用域的變數,構成了一個閉包。
以上程式碼等價於:
function foo() {
this.a = 1
let self = this
let b = () => console.log(self.a)
b()
}
foo() // 1
箭頭函式不僅沒有this
,常用的arguments
也沒有。如果你能獲取到arguments
,那它一定是來自於父級作用域。
function foo() {
return () => console.log(arguments[0])
}
foo(1, 2)(3, 4) // 1
如果箭頭函式有arguments
,就應該輸出3而不是1。
一個常犯的錯誤是使用箭頭函式定義物件的方法,如:
let a = {
foo: 1,
bar: () => console.log(this.foo)
}
a.bar() //undefined
以上程式碼中,箭頭函式中的this
指向並不是指向a
這個物件。物件a
並不能構成一個作用域,所以再往上到達全域性作用域,this
就指向全域性作用域。如果我們使用普通函式的定義方法,輸出結果就能符合預期,這是因為a.bar()
函式執行時作用域繫結到了a
物件。
let a = {
foo: 1,
bar: function() { console.log(this.foo) }
}
a.bar() // 1
以上文章提到了this
指向和作用域概念,這裡進一步介紹下。
this指向
首先必須要說的是,this
的指向在函式定義時是確定不了的,只有函式執行時才能確定,實際上this
最終指向的是呼叫它的物件。
在函式沒有呼叫時,this的值無法確定。
還是拿例子來說明,
function a(){
var user = "追夢子";
console.log(this.user); //undefined
console.log(this); //Window
}
a();
因為this
最終指向的是呼叫它的物件,函式a
實際上是被window
呼叫的。
再來個例子。
var o = {
user:"追夢子",
fn:function(){
console.log(this.user); //追夢子
}
}
o.fn();
這裡this
指向o
,好像沒什麼好說的,最終指向呼叫它的物件。
好了,看到這裡還不要驕傲,下面幾個例子才有真正的坑。
var o = {
a:10,
b:{
// a:12,
fn:function(){
console.log(this.a); //undefined
}
}
}
o.b.fn();
這是因為this
指向的是上一級呼叫的物件,而不能一級一級往上尋找。
作用域
剛才講到普通函式的this指向是執行時確定的,然而,不同的是,
JavaScript中的作用域是的巢狀關係是定義時確定的。
也就是說,JavaScript的作用域是靜態作用域,又叫詞法作用域,這是因為作用域的巢狀關係在語法分析時就可以確定,而不是在執行時確定。
例如,
var scope = 'top';
var f1 = function() {
console.log(scope);
};
f1(); // 輸出 top
var f2 = function() {
var scope = 'f2';
f1();
};
f2(); // 輸出 top`
參考
https://jingsam.github.io/2016/12/08/things-you-should-know-about-arrow-functions.html
https://segmentfault.com/a/1190000004589779
https://juejin.im/entry/589be5b1b123db16a3bec5c2
https://juejin.im/post/5aa1eb056fb9a028b77a66fd
https://segmentfault.com/a/1190000018119191
相關文章
- 箭頭函式的this指向(二)函式
- 箭頭函式this指向詳解函式
- ES6 箭頭函式下的this指向函式
- setTimeout和箭頭函式巢狀中的this指向函式巢狀
- 教辨別this指向問題 包括箭頭函式函式
- 也談箭頭函式的 this 指向問題及相關函式
- javascript基礎修煉(8)——指向FP世界的箭頭函式JavaScript函式
- 箭頭函式函式
- 箭頭函式中的this函式
- es6學習_箭頭函式解決this指向問題函式
- JavaScript 箭頭函式JavaScript函式
- TypeScript 箭頭函式TypeScript函式
- javascript箭頭函式JavaScript函式
- JS箭頭函式JS函式
- vue2專案中 箭頭函式和普通函式里面 this的指向有何不同?Vue函式
- setTimeout中的this指向問題和箭頭函式結合的區別函式
- 有關箭頭函式函式
- 箭頭函式詳解函式
- 箭頭函式與普通函式的區別函式
- # 普通函式和箭頭函式的區別函式
- JS中的箭頭函式與thisJS函式
- 箭頭函式、簡寫函式、普通函式的區別函式
- 箭頭函式與普通函式區別函式
- ES6箭頭函式函式
- [譯]箭頭函式 vs .bind()函式
- ES6箭頭函式的使用函式
- 從一道面試題中總結JS作用域,this 指向和箭頭函式面試題JS函式
- 詳解箭頭函式和普通函式的區別以及箭頭函式的注意事項、不適用場景函式
- 箭頭函式和普通函式的10個區別函式
- 面試題:箭頭函式和普通函式的區別面試題函式
- 簡述箭頭函式和普通函式的區別函式
- JavaScript(ES6)—箭頭函式JavaScript函式
- JavaScript初學者必看“箭頭函式”JavaScript函式
- 從settTimeout到匿名函式、箭頭函式之() => {}函式
- ES 6 中的箭頭函式及用法函式
- javaES6箭頭函式的全新特性Java函式
- Javascript ES6中的箭頭函式JavaScript函式
- PHP 7.4 新特性之箭頭函式PHP函式