javascript这个闭包的外部函数有一个界';这';

javascript这个闭包的外部函数有一个界';这';,javascript,ecmascript-6,ecmascript-5,Javascript,Ecmascript 6,Ecmascript 5,我很难理解这一点。 我知道范围链接、javascript中的回调、回调中的this值以及箭头函数 在javascript中,闭包可以通过作用域链访问封闭函数的变量。那么,为什么闭包不通过Function.prototype.bind访问闭包父函数的“this”绑定呢?变量“this”不是作用域链的一部分吗 在chrome控制台中运行以下代码: a = 4; b = 6; function outer(){ function inner(){ console.log(`th

我很难理解这一点。 我知道范围链接、javascript中的回调、回调中的this值以及箭头函数

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

在chrome控制台中运行以下代码:

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
变量“this”不是作用域链的一部分吗

是的,没错。不是一个变量,而是一个特殊的关键字。它确实在每次函数调用时被设置,在您的例子中是
internal()
。在
外部
的范围内,这个是什么并不重要

不过也有一个例外,函数可以选择退出这种行为:箭头函数。他们确实会从词汇上查找
,并忽略调用中的值:

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

正如在注释中提到的,这是一个函数,它可以根据您调用函数的方式(或定义函数,如果我们考虑箭头函数)进行更改。查看显示此上下文行为的代码的修改版本:

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})();

工作演示

这和闭包在JS中是两种不同的机制,不应该混合使用。 这个外在的功能和这个内在的功能是完全分离的

在您的示例中,您希望内部函数具有来自外部函数的这个词法范围,而这不是它的工作方式。如果您使用的是arrow函数,它就是这样工作的,因为这将是词法的,并且将从外部函数指向它。 如果将内部函数更改为箭头函数,则可以观察到该行为//this.a为1,this.b为3

常量内部=()=>{ log(
this.a是${this.a},this.b是${this.b}
); };

若你们想知道这是怎么回事,我强烈推荐Kyle Simpson的书,它在github上是免费的

从书上看

要理解这个绑定,我们必须了解调用站点:调用函数的代码中的位置(而不是在声明的地方)。我们必须检查呼叫站点以回答以下问题:这是指什么?

所以你们可以看到,内部函数的位置和它所绑定的东西无关


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

那是因为你有全局变量
inside
inside
仍然是访问全局变量的
window
。@Andrewi好的,我明白了,inside不应该访问外部的绑定a和b,因为它是闭包吗?不,因为您正在闭包中访问
this
。它与外部功能无关。所以你的意思是说“这”与范围链无关?@AndrewLi,好的,那么你的意思是说,当我定义函数时,这是通过函数范围内的引擎在内部分配的?因此,解释器首先在内部检查函数调用是“方法”还是“正常函数调用”,在前一种情况下,这是方法附加到的obj,在后一种情况下,全局对象,即使函数是闭包且未附加到全局对象[当然,在非严格模式下]?是的,这就是它检查的内容。请注意,它不会将全局对象传递到
internal()
,而是传递
未定义的
——它没有像您所说的那样附加到任何对象。只有邋遢模式函数才会将未定义的此参数强制转换为全局对象,就像箭头函数或绑定函数选择忽略该值一样。(始终尝试严格模式:D!)
[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