Javascript 为方便确定范围而引用此内容是好主意还是坏主意?
我有时会将this指针指定给一个var。这样做的好处是我不会在匿名回调函数中失去作用域。这是个好主意还是个坏主意 例如:Javascript 为方便确定范围而引用此内容是好主意还是坏主意?,javascript,jquery,scope,Javascript,Jquery,Scope,我有时会将this指针指定给一个var。这样做的好处是我不会在匿名回调函数中失去作用域。这是个好主意还是个坏主意 例如: var Foo = (function($) { var Foo = function() { var self; self = this; this.init = function() { $('#foo').click(function(e) { self.onClick(); }); };
var Foo = (function($) {
var Foo = function() {
var self;
self = this;
this.init = function() {
$('#foo').click(function(e) {
self.onClick();
});
};
this.onClick = function() {
console.log(this);
};
this.init();
};
return function() {
return new Foo();
};
})(jQuery);
谢谢大家!{Jim}这既不是个好主意,也不是个坏主意。这是保持对外部作用域/上下文的引用的唯一机会
有人向我询问更多细节,我们开始:
此
值是一个特殊对象,它与执行上下文
相关。因此,您可以说它是一个上下文对象(激活执行上下文的上下文对象)
- 在全局上下文中,
这是全局对象本身
- 对于函数上下文,
可能不同。在每个函数调用中的此
是在输入上下文时确定的,如果使用功能代码,则每次的值都可能完全不同此
甚至这也是整个主题的一个非常简短的总结。但是希望您能够理解为什么需要存储对
此值的引用
以从另一个函数上下文访问它。如果您需要对包含范围的此
值的引用(这当然是一个合理的要求),这一定是一个好主意,尤其是在您无法控制函数调用(如事件处理程序函数)的情况下,它是您的唯一选项。这不是一个坏主意。这是否是一个好主意主要取决于风格
编写代码的另一种方法是在闭包中保存对onClick
函数的引用。但是,以这种方式调用时,this
不会绑定到onClick
函数。例如:
var Foo = (function($) {
var Foo = function() {
this.init = function() {
$('#foo').click(function(e) {
onClick();
});
};
var self = this; // Or use ES5's Function.prototype.bind
var onClick = this.onClick = function() {
console.log(self);
};
this.init();
};
return function() {
return new Foo();
};
})(jQuery);
var self;
self = this;
如果对象的方法都在闭包中(如您的情况),我更喜欢使用
self
(或that
或您选择的任何名称)。这似乎是保留范围引用的唯一方法。但不要这样做(从您的示例中):
而是将它们合并为一行:
var self = this;
这样做并没有什么错,除非如果范围嵌套深入到一个级别以上,您可能必须为“this”和“self”想出更多的同义词。挂起特定“this”值的首选方法是使用,它是ECMAScript 5规范的一部分,现在正在浏览器中实现。到目前为止,据我所知,只有谷歌Chrome本机支持它,但我已经做了一段时间了,用polyfill很容易就能把它固定下来。我不知道这是不是一个好主意,但是我一直都在这样做。这在我们必须通过其他函数或迭代过程的情况下是很有用的,因为我们可能会失去作用域
这个不指“作用域”,也许在顶级上下文中除外。我已经给出了+1,但我希望修改包括this
:PYes的“动态”性质,但是为什么this
与属性/变量wrt不同呢。scopes?@pst:你是想让我解释一下这个是如何工作的吗?我不确定它是否需要解释:这个问题表明OP非常了解它,知道嵌套函数中的this
不一定与其包含范围中的this
的值相同。这看起来就像使用了另一个closured变量。但是围绕这个的闭包的功能用法仍然存在。@pst,这是正确的。这种模式的目标是用更优雅的语言(闭包)取代this
的使用。我同意,jQuery和大多数框架都模拟bind。在大多数浏览器中,MDC上还有一个代码片段需要重新创建绑定:但是编译器再次将“var self;”放在顶部,我错了吗?@Jim:var self没有什么内在的错误;self=这个代码>,尽管没有理由不将其缩短为var self=this代码>。事实上,如果它是函数中的第一条语句(如问题中所述),var self;self=这个代码>实际上是代码执行时发生的事情:在变量实例化阶段,使用undefined
的值创建并初始化self
变量,这发生在任何语句实际执行之前。这发生在运行时而不是编译时。