在 Javascript 中,"this.something" 是否查找 "something" 的作用域链?
In Javascript, does "this.something" look up the scope chain for "something"?
这就是我的意思。我正在练习我的面向对象 Javascript(我从实践中学习),创建了以下内容 class 为了好玩
function Funcstack ( )
{
this.stack = []; // stack/array of functions w/ no params
this.pushFunction = function ( f )
{
// f: function w/ no params
this.stack.push(f);
}
this.popFunction = function ( f )
{
// f: function w/ no params
var n = this.stack.length;
if (n > 0) this.stack.splice(n - 1, 1);
}
this.executeFunctions = function ( )
{
// execute functions from top to bottom of stack
for ( var i = (this.stack.length - 1); i >= 0; --i )
{
var thisfunc = this.stack[i];
thisfunc();
}
}
}
var fs = new Funcstack();
fs.pushFunction(function() { console.log('z'); });
fs.pushFunction(function() { console.log('y'); });
fs.pushFunction(function() { console.log('x'); });
fs.executeFunctions(); // should print 'xyz'
并对它的工作感到惊讶。主要原因是因为我认为,例如,在
this.pushFunction = function ( f )
{
// f: function w/ no params
this.stack.push(f);
}
函数体无法识别 this.stack
,因为 this
在特定上下文中指的是调用函数 pushFunction
,它没有名为 [=18] 的成员=]!那么我认为它查找了作用域链是否正确?这似乎与 this
的整个想法相矛盾,但是......它有什么意义?
它起作用的原因是调用上下文。
this.stack = []; // <--- is an instance property ( member ) of any instance of Funstack
当您调用 "pushFunction" 使用 "fs"(实例引用)来引用
"this"(上下文)变成任何 "fs" 对象是..
如果仍然不清楚,请尝试阅读更多关于 javascript 的 "calling context"。
简短的回答是 "No"。执行上下文的 this 总是在当前执行上下文中解析,因此它与范围无关。对于宽箭头函数,它被设置为与外部执行上下文相同的值。
函数的 this 由调用函数的方式或通过 bind 设置来设置。它不是按词法设置的(调用在代码中的位置)或调用函数的位置。
其中 this 是一个对象(总是在非严格模式下)然后它的属性被解析的方式与解析任何对象的属性的方式相同,首先是它自己,然后是它的[[Prototype]]
链。将函数作为对象的方法调用的地方:
fs.executeFunctions();
然后 基础对象 (fs) 在函数内被设置为 this。因此,当解析 this.stack.length 时,this 引用 fs 实例并且 executeFunctions 被解析为 fs.
的 属性
当您说:var fs = new Funcstack();
时,您声明的对象是 class Funcstack
的一个实例。请注意,在 constructor
中,您正在声明它的一些属性和方法。
因此,所有这些方法中的关键字 this
将引用您创建的对象。如果需要,您可以随时使用 call
, apply
or bind
更改上下文。
请注意,您是在声明 pushFunction
为 class 的成员,方法是:this.pushFunction = function(f) { /* (...) */ }
。因此,您正在为 class 创建一个方法。这就是为什么 this
关键字引用作为 class.
实例的对象的原因
如果您将函数声明为 var pushf = function(f) { /* (...) */ }
,然后在 class Funcstack
的某个方法中调用该函数,您将得到错误:
TypeError: this.stack is undefined
看看下面的例子。
function Funcstack() {
this.stack = []; // stack/array of functions w/ no params
var pushf = function _pushFunction(f) {
this.stack.push(f);
}
this.pushFunction = function(f) {
// f: function w/ no params
pushf(f);
}
this.popFunction = function(f) {
// f: function w/ no params
var n = this.stack.length;
if (n > 0) this.stack.splice(n - 1, 1);
}
this.executeFunctions = function() {
// execute functions from top to bottom of stack
for (var i = (this.stack.length - 1); i >= 0; --i) {
var thisfunc = this.stack[i];
thisfunc();
}
}
}
var fs = new Funcstack();
fs.pushFunction(function() {
console.log('z');
});
fs.pushFunction(function() {
console.log('y');
});
fs.pushFunction(function() {
console.log('x');
});
fs.executeFunctions(); // should print 'xyz'
这就是我的意思。我正在练习我的面向对象 Javascript(我从实践中学习),创建了以下内容 class 为了好玩
function Funcstack ( )
{
this.stack = []; // stack/array of functions w/ no params
this.pushFunction = function ( f )
{
// f: function w/ no params
this.stack.push(f);
}
this.popFunction = function ( f )
{
// f: function w/ no params
var n = this.stack.length;
if (n > 0) this.stack.splice(n - 1, 1);
}
this.executeFunctions = function ( )
{
// execute functions from top to bottom of stack
for ( var i = (this.stack.length - 1); i >= 0; --i )
{
var thisfunc = this.stack[i];
thisfunc();
}
}
}
var fs = new Funcstack();
fs.pushFunction(function() { console.log('z'); });
fs.pushFunction(function() { console.log('y'); });
fs.pushFunction(function() { console.log('x'); });
fs.executeFunctions(); // should print 'xyz'
并对它的工作感到惊讶。主要原因是因为我认为,例如,在
this.pushFunction = function ( f )
{
// f: function w/ no params
this.stack.push(f);
}
函数体无法识别 this.stack
,因为 this
在特定上下文中指的是调用函数 pushFunction
,它没有名为 [=18] 的成员=]!那么我认为它查找了作用域链是否正确?这似乎与 this
的整个想法相矛盾,但是......它有什么意义?
它起作用的原因是调用上下文。
this.stack = []; // <--- is an instance property ( member ) of any instance of Funstack
当您调用 "pushFunction" 使用 "fs"(实例引用)来引用
"this"(上下文)变成任何 "fs" 对象是..
如果仍然不清楚,请尝试阅读更多关于 javascript 的 "calling context"。
简短的回答是 "No"。执行上下文的 this 总是在当前执行上下文中解析,因此它与范围无关。对于宽箭头函数,它被设置为与外部执行上下文相同的值。
函数的 this 由调用函数的方式或通过 bind 设置来设置。它不是按词法设置的(调用在代码中的位置)或调用函数的位置。
其中 this 是一个对象(总是在非严格模式下)然后它的属性被解析的方式与解析任何对象的属性的方式相同,首先是它自己,然后是它的[[Prototype]]
链。将函数作为对象的方法调用的地方:
fs.executeFunctions();
然后 基础对象 (fs) 在函数内被设置为 this。因此,当解析 this.stack.length 时,this 引用 fs 实例并且 executeFunctions 被解析为 fs.
的 属性当您说:var fs = new Funcstack();
时,您声明的对象是 class Funcstack
的一个实例。请注意,在 constructor
中,您正在声明它的一些属性和方法。
因此,所有这些方法中的关键字 this
将引用您创建的对象。如果需要,您可以随时使用 call
, apply
or bind
更改上下文。
请注意,您是在声明 pushFunction
为 class 的成员,方法是:this.pushFunction = function(f) { /* (...) */ }
。因此,您正在为 class 创建一个方法。这就是为什么 this
关键字引用作为 class.
如果您将函数声明为 var pushf = function(f) { /* (...) */ }
,然后在 class Funcstack
的某个方法中调用该函数,您将得到错误:
TypeError: this.stack is undefined
看看下面的例子。
function Funcstack() {
this.stack = []; // stack/array of functions w/ no params
var pushf = function _pushFunction(f) {
this.stack.push(f);
}
this.pushFunction = function(f) {
// f: function w/ no params
pushf(f);
}
this.popFunction = function(f) {
// f: function w/ no params
var n = this.stack.length;
if (n > 0) this.stack.splice(n - 1, 1);
}
this.executeFunctions = function() {
// execute functions from top to bottom of stack
for (var i = (this.stack.length - 1); i >= 0; --i) {
var thisfunc = this.stack[i];
thisfunc();
}
}
}
var fs = new Funcstack();
fs.pushFunction(function() {
console.log('z');
});
fs.pushFunction(function() {
console.log('y');
});
fs.pushFunction(function() {
console.log('x');
});
fs.executeFunctions(); // should print 'xyz'