var self =这个?
使用实例方法作为事件处理程序的回调函数将其范围从“我的实例”更改为“无论何时只是称为回调” 。 所以我的代码看起来像这样
function MyObject() { this.doSomething = function() { ... } var self = this $('#foobar').bind('click', function(){ self.doSomethng() // this.doSomething() would not work here }) }
它的工作原理,但这是最好的办法吗? 我看起来很奇怪
这个问题不是特定于jQuery,而是一般的JavaScript。 核心问题是如何在嵌入式函数中“引导”一个变量。 这是一个例子:
var abc = 1; // we want to use this variable in embedded functions function xyz(){ console.log(abc); // it is available here! function qwe(){ console.log(abc); // it is available here too! } ... };
这种技术依赖于使用闭包。 但是它不起作用,因为this
是一个伪变量,可能会动态地从范围变为范围:
// we want to use "this" variable in embedded functions function xyz(){ // "this" is different here! console.log(this); // not what we wanted! function qwe(){ // "this" is different here too! console.log(this); // not what we wanted! } ... };
我们可以做什么? 将其分配给某个变量并通过别名使用它:
var abc = this; // we want to use this variable in embedded functions function xyz(){ // "this" is different here! --- but we don't care! console.log(abc); // now it is the right object! function qwe(){ // "this" is different here too! --- but we don't care! console.log(abc); // it is the right object here too! } ... };
this
在这方面并不是唯一的: arguments
是另一个应该以同样方式对待的伪变量 – 通过别名。
是的,这似乎是一个共同的标准。 一些编码员使用自己,其他人使用我。 它被用作回到“真实”对象而不是事件的参考。
这是我花了一段时间才真正得到的,起初看起来很奇怪。
我通常在我的对象顶部这样做(原谅我的演示代码 – 它比其他任何东西都更具概念性,并不是关于优秀编码技术的教训):
function MyObject(){ var me = this; //Events Click = onClick; //Allows user to override onClick event with their own //Event Handlers onClick = function(args){ me.MyProperty = args; //Reference me, referencing this refers to onClick ... //Do other stuff } }
如果你正在做ES2015或者做脚本和ES5,那么你可以在你的代码中使用箭头函数,而且你不会遇到这个错误,并且这个错误指向你实例中你想要的范围。
this.name = 'test' myObject.doSomething(data => { console.log(this.name) // this should print out 'test' });
var functionX = function() { var self = this; var functionY = function(y) { // If we call "this" in here, we get a reference to functionY, // but if we call "self" (defined earlier), we get a reference to function X. } }
编辑:尽管如此,对象中的嵌套函数将采用全局窗口对象而不是周围的对象。
我没有使用jQuery,但是在像Prototype这样的库中,可以将函数绑定到特定的作用域。 所以考虑到你的代码如下所示:
$('#foobar').ready('click', this.doSomething.bind(this));
bind方法返回一个新的函数,它调用原来的方法和你指定的范围。
解决这个问题的一个办法是用javascript的bind
方法将所有的回调绑定到你的对象。
你可以用一个命名的方法来做到这一点,
function MyNamedMethod() { // You can now call methods on "this" here } doCallBack(MyNamedMethod.bind(this));
或者用匿名回调
doCallBack(function () { // You can now call methods on "this" here }.bind(this));
这样做,而不是诉诸于var self = this
表明你明白var self = this
是如何绑定this
在javascript中的行为,并不依赖于封闭引用。
另外,ES6中的胖箭头操作符基本上是一个匿名函数调用.bind(this)
:
doCallback( () => { // You can reference "this" here now });
我想这实际上取决于你在doSomething
函数里面做什么。 如果你要使用这个关键字访问MyObject
属性,那么你必须使用它。 但是我认为如果你没有使用object(MyObject)
属性做任何特殊的事情,下面的代码片段也可以工作。
function doSomething(){ ......... } $("#foobar").ready('click', function(){ });
只是增加了这一点,在ES6因为箭头功能,你不应该这样做,因为他们捕获this
值。