Javascript 什么';在knockout.js视图模型中使用'var self=this'的优点是什么
在几乎所有的knockout.js视图示例中,我都看到行Javascript 什么';在knockout.js视图模型中使用'var self=this'的优点是什么,javascript,knockout.js,Javascript,Knockout.js,在几乎所有的knockout.js视图示例中,我都看到行var self=this,然后所有局部变量都是引用self.variableName。与使用this.variableName相比,这种方法的优点是什么?Self用于确保将原始this保存在对象中 这在使用事件处理程序等时非常方便 你可以阅读更多关于这方面的内容 第一个答案基本上涵盖了这一点,也显示了一个很好的链接。请查看。通常使用此方法的主要原因是使当前的this可用于子函数或闭包。例如: var myObject = { para
var self=this
,然后所有局部变量都是引用self.variableName
。与使用this.variableName
相比,这种方法的优点是什么?Self
用于确保将原始this
保存在对象中
这在使用事件处理程序等时非常方便
你可以阅读更多关于这方面的内容
第一个答案基本上涵盖了这一点,也显示了一个很好的链接。请查看。通常使用此方法的主要原因是使当前的
this
可用于子函数或闭包。例如:
var myObject = {
param: 123,
method: function(){
alert( this.param );
},
method2: function(){
setTimeout(function(){
alert( this.param );
},100);
}
}
在上面的调用中,myObject.method
将为您提供123
的正确警报。但是,调用myObject.method2
将为您提供未定义的。这是因为与setTimeout
一起使用的匿名函数中的This
没有引用myObject
,这取决于JavaScript解释器,它将指向不同的东西。但是,如果您有:
method2: function(){
var self = this;
setTimeout(function(){
alert( self.param );
},100);
}
这是因为捕获了位于正确点的此
的当前状态,并将始终为每个可用的功能范围引用myObject
问题不限于使用setTimeout
。在任何有匿名函数、子函数或闭包的地方,这个技巧都会派上用场。有时人们使用self
,或that
或更具描述性的东西,具体取决于当前引用所代表的内容
而不是作为变量存储
除了使用self
或任何其他变量“记住”任何特定点的状态外,还有一种替代方法,即使用特定上下文“绑定”匿名函数或子函数。许多现代口译员现在支持Function.prototype.bind
方法,该方法可用于:
var method = function(){
console.log(this);
};
var methodWithWindow = method.bind(window);
var methodWithDocument = method.bind(document);
var methodWithObject = method.bind({random:"object"});
依次调用每个绑定方法将获得以下控制台输出:
Window
Document
Object {random:"object"}
如果您希望支持较旧的浏览器,您可以使用一个,或者如果您更喜欢一个更简单的实现,一个不担心绑定参数的实现。绑定代码的基本功能如下:
!Function.prototype.bind && (Function.prototype.bind = function(context){
var method = this;
return function(){
method.apply(context, arguments);
}
})
那么,使用bind时最初的示例会是什么样子呢
method2: function(){
setTimeout((function(){
console.log(this); // `this` will be the same as the `this` passed to bind.
}).bind(this),100);
}
如上所述,一旦绑定,返回的函数(闭包)将保留指定的上下文;因此,它可以在任何你想要的地方传递,并且仍然保留对你想要的对象的引用。这在method2
示例中很有用,因为我们将该方法与当前上下文捆绑在一起,并将其传递给setTimeout
,后者稍后将执行绑定方法(在我们退出当前块执行很久之后)
当使用self
或任何其他变量时,也会发生同样的情况。变量将被捕获到函数的作用域链中,并且在函数最终被再次调用时仍然可以访问。使用bind
的好处是,如果愿意,您可以轻松重写上下文,您必须编写自己的特定方法来重写self
变量
警告:值得注意的是,绑定函数时,会返回一个新函数。如果将绑定函数与事件侦听器混合使用,然后尝试使用原始函数而不是绑定版本删除侦听器,则可能会导致混乱的情况
另外,由于绑定返回一个新函数,如果绑定一个绑定函数,实际上就是在用另一个函数将一个函数包装到一个函数中。您应该意识到这一点,因为它会影响性能,而且在避免内存泄漏方面,管理起来会更加棘手。我首选的绑定方法是使用闭包和它们自己的解构方法(即依靠self,但确保有方法取消它的内容),但这需要更多的前瞻性思考,在较小的JS项目中不太相关;或一次性函数绑定-特别是如果绑定方法从未在任何引用中捕获
没有自我约束?
还值得一提的是,有时您可以在根本不使用bind
的情况下获得相同的结果,而是使用apply
——这应该在您可以选择使用的任何内容中本机可用。主要区别在于,函数中没有任何内容,调用apply实际上是在那里执行函数,然后使用不同的上下文(传递给apply的第一个参数)执行函数
var externalMethod = function(){
console.log(this); // will output myObject when called below
};
var myObject = {
method2: function(){
externalMethod.apply(this);
}
};
这是什么?
在删除最近的评论之前,请详细说明此答案,并提供有关此
的更多详细信息<代码>此
将引用以下四项之一,具体取决于您在其中使用的函数的调用方式:
myObject.method()
除非方法
应用了.bind(context)
操作,否则上面将有一个this
的myObject
。在这种情况下,此
将是最后绑定的上下文
unattachedFunction()
anyFunction.apply(otherObject)
将有一个全局上下文的此
(在浏览器环境中通常是窗口
),除非unattachedFunction
应用了.bind(context)
操作。在这种情况下,此
将是最后绑定的上下文
unattachedFunction()
anyFunction.apply(otherObject)
或
两者都将始终具有this
的otherObject
,因为以这种方式调用将覆盖任何绑定
new myObject()
将有一个this
引用myObject
的新实例,这将覆盖任何绑定
new myObject()
简单思维实验
考虑到以上所有因素,该
将包含哪些内容<