2017-06-15 65 views
0

我很难找到我的头。 我知道范围链接,javascript中的回调函数,其值为这个中的回调函数和箭头函数。javascript这个封闭的外部函数有一个绑定'this'

在JavaScript中,闭包可以通过作用域链访问封闭函数的变量。那么为什么闭包不能通过Function.prototype.bind访问'this'的绑定函数?变量“this”不是范围链的一部分吗?

冉铬控制台中下面的代码:

a = 4; 
b = 6; 
function outer(){ 
    function inner(){ 
     console.log(`this.a is ${this.a} and this.b is ${this.b}`); 
    } 
    inner(); 
} 
outer.bind({a:1,b:3})() 

和控制台掀开:

this.a is 4 and this.b is 6 
+0

这是因为你有全局变量! inner内部的'this'仍然是访问全局变量的'window'。 – Li357

+0

@AndrewLi好吧,我明白了,不应该内部访问外部的绑定a和b,因为它是一个闭包? – basum

+0

不,因为你在封闭中访问'this'。它与外部功能无关。 – Li357

回答

0

是变量“这”不是一个范围链的一部分?

是的,正好。 this不是一个变量,而是一个特殊的关键字。它确实设置为,每调用函数,在你的情况下inner()outer范围内的this是什么都没有关系。

虽然函数可以选择退出此行为,但有一个例外:箭头函数。他们确实查this词汇,而忽略从调用值:

function outer(){ 
    const inner =() => { 
     console.log(`this.a is ${this.a} and this.b is ${this.b}`); 
    } 
    inner(); 
} 
outer.call({a:1,b:3}) 
+0

所以解释器在内部首先检查函数调用是“方法”还是“正常函数调用”,在前一种情况下,这是该方法附加到的obj,而在后者中,即使是全局对象该函数是一个闭包,并不附加到全局对象[当然,在非严格模式]。 ? ? – basum

+0

是的,这就是它检查的内容。请注意,它不会将全局对象传递给'inner()',它会传递'undefined' - 它不会像你说的那样附加到任何东西上。这只是马虎模式函数,它将这个参数未定义为全局对象,就像箭头函数或者边界函数选择忽略该值一样。 (总是尝试严格模式:D!) – Bergi

0

正如评论所说,这是一个contextual reference,它能够基于你如何调用该函数(或定义它,如果我们认为箭头功能)。看看你的代码的修改版本,显示此上下文行为:

var a = 4; 
var b = 6; 
function outer(){ 
    document.write(`<p>[outer] this.a is ${this.a} and this.b is ${this.b}</p>`); 

    function inner(msg){ 
     document.write(`<p>[${msg}] this.a is ${this.a} and this.b is ${this.b}</p>`); 
    } 
    inner('inner'); 
    this.inner = inner; 
    this.inner('this.inner'); 
} 
outer.bind({a:1,b:3})(); 

这将输出:

[outer] this.a is 1 and this.b is 3 

[inner] this.a is 4 and this.b is 6 

[this.inner] this.a is 1 and this.b is 3 

工作演示here

1

这和封锁是JS和2个不同的机制应不要混在一起。 这个在外部函数中与内部函数完全分离。

在你的例子中,你期望内部函数具有这个来自外部函数的词法范围,这不是这是如何工作的。如果你正在使用箭头函数,它就是这样工作的,因为这样做会是词法,并且会从外部函数指向这个。 如果你改变内部函数箭头功能你可以观察到的行为// this.a是1和this.b是3

常量内=()=> { 的console.log(this.a is ${this.a} and this.b is ${this.b}); };如果你想了解这是怎么表现我非常凯尔 - 辛普森建议书,它是免费的在GitHub上this & object prototypes

从书

为了理解这个绑定,我们必须理解call-site:调用函数的代码中的位置(不是声明它的地方)。我们必须检查呼叫站点来回答这个问题:这是什么这是一个参考?

所以就像你可以看到内部函数的位置与这将绑定到什么无关。 rules that defines how this will be bound

阅读上面的链接后,你应该对JS有更多的了解。

相关问题