我无法理解这个问题。 我知道范围链,javascript中的回调,回调中 this 的值,因此箭头函数。
在javascript中,闭包可以通过作用域链访问封闭函数的变量。那么为什么关闭不能访问'这个'通过Function.prototype.bind绑定到闭包的父函数?变量'这个'不是范围链的一部分?
在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
答案 0 :(得分:3)
这和闭包是JS中的两种不同机制,不应该混合使用。 这在外部函数中与内部函数完全分离。
在你的例子中,你期望内部函数具有来自外部函数的词法范围,而这不是它的工作方式。如果您使用箭头功能,它就像那样工作,因为这将是词法,并将从外部函数指向这个。 如果你将内部函数更改为箭头函数,你可以观察到这个行为// this.a是1而this.b是3
const inner =()=> {
的console.log(this.a is ${this.a} and this.b is ${this.b}
);
};
如果你想了解这是怎么表现我强烈推荐Kyle Simpson的书,它在github this & object prototypes
上免费从书中。
要理解这种绑定,我们必须了解call-site:调用函数的代码中的位置(而不是声明它的位置)。我们必须检查呼叫网站以回答这个问题:这是什么引用?
所以你可以看到内部函数的位置与这将绑定的内容无关。 rules that defines how this will be bound
阅读上面的链接后,你应该对JS有更多的了解。
答案 1 :(得分:0)
变量'这个'不是范围链的一部分?
是的,确切地说。 this
不是变量,而是特殊关键字。它会在每个函数调用中设置,在您的情况inner()
中。 this
范围内outer
的内容并不重要。
但是有一个例外,其中函数可以选择退出此行为:箭头函数。他们确实在词汇上查找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})
答案 2 :(得分: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