- 我在网上做了很多研究,阅读了很多帖子,包括MDN等等。
- 据我所知,对于传统定义的函数,函数中的“this”是由调用/调用它们的对象定义的(以及几种不同的情况,对象文字,新的构造函数,事件处理程序等)。
- 我知道对于箭头函数,“this”是按词法定义的,由
enclosing context/scope
,而不是通过对象调用它们(尽管我们可以使用传统定义的函数(例如 A)来包装箭头函数(例如 B),从而将对象引用首先传递给 A,然后传递给 B)
问题来了:
-
到底是什么enclosing context
?这更加复杂,因为 ES6 允许{}
成为一个块/范围/上下文。是{}
作为足够好的分隔符来定义“封闭上下文”,或者它必须在函数范围内。
-
一个具体的例子:
let EventEmitter = require('events').EventEmitter;
class Person extends EventEmitter {
constructor(name) {
super();
this.name = name;
}
}
let mary = new Person('mary');
mary.on('speak', (said) => {
console.log(`${this.name}: ${said}`);
});
mary.emit('speak', 'you may delay, but time will not');
它只是设置一个自定义事件并在触发自定义事件时添加回调函数。为什么这里的箭头功能不起作用?
“mary”是调用“on”函数的对象,应将“on”中的“this”设置为“mary”。最重要的是,箭头函数是在其参数位置的“on”函数中定义的(从词法上来说足够了,对吧?),为什么箭头函数无法从其“封闭上下文”中获取“this”值,即,这里的“on”功能???
-
同样的例子,使用传统的函数定义:
let EventEmitter = require('events').EventEmitter;
class Person extends EventEmitter {
constructor(name) {
super();
this.name = name;
}
}
let mary = new Person('mary');
mary.on('speak', function(s) {
console.log(this);
});
mary.emit('speak', 'you may delay, but time will not');
现在可以了。据我了解,鉴于旧的函数定义方式,console.log(this) 现在可以动态绑定到调用它的对象。但是等等,“mary”是对象,“on”是被调用的立即函数。 “on”不应该为其中的匿名函数形成一个闭包吗?我记得嵌套函数中的“this”无法访问其闭包的“this”(封闭上下文,呵呵),因此不应获得“mary”引用。为什么它在这里起作用?
-
当我们在函数中谈论某件事(例如 A)时,是否意味着 A 必须位于{}
函数的,或者 A 也可以在参数/参数区域中?那是,function(){A}
vs. function(A){}
.
-
类似地,如果箭头函数作为参数传递,例如function(()=>()) {}
,外部函数是否考虑了其封闭范围?或者在这种情况下,封闭范围将是外部函数的外部?
上面的话听起来可能非常愚蠢。非常感谢你的帮助。
我在这里可能没有准确地使用作用域这个词,但基本上只是将作用域视为变量名称到它们所引用的内存位置的映射;嵌套范围的名称/变量对shadow(覆盖)封闭(也称为父)范围内具有相同名称的关联。
function foo() { // this is the "enclosing scope" of bar
var a = 4 <-----------+
|
var b = a // refers to --+
function bar() {
var a = 7 <-----------+
|
var c = a // refers to --+
}
}
this
行为方式完全相同a
在上面的例子中就是这样做的。
function
范围隐式定义了一个引用this
但 ES2015 箭头函数作用域和块作用域没有。如果这些定义是明确的,它们将如下所示:
function foo() { // this is the enclosing scope of baz and the block below
var this = ... <-----------+--+
| |
var b = this // refers to --+ |
|
{ |
var q = this // refers to ---+
}
function bar() { // this is the enclosing scope of baz
var this = ... <-----------+--+
| |
var c = this // refers to --+ |
|
var baz = () => { |
var d = this // refers to ---+
}
}
}
实际上value在内存位置this
指在特定范围内未按词汇定义;它在运行时设置为调用函数的对象(的内存位置)。但是一个引用对另一个引用的遮蔽总是按词法定义的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)