在knockout.js视图模型中使用`var self = this`有什么好处 [英] What's the advantage of using `var self = this` in knockout.js view models

查看:122
本文介绍了在knockout.js视图模型中使用`var self = this`有什么好处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在几乎所有的knockout.js视图模型中都看到了行 var self = this ,然后所有局部变量都被引用为 self。 VARIABLENAME 。这比使用 this.variableName

I see in almost all examples of a knockout.js viewmodels the line var self = this and then all local variables are references as self.variableName. What is the advantage of this over using this.variableName?

推荐答案

有什么好处?通常,使用此方法的主要原因是使当前可用于子功能或闭包。例如:

Normally the main reason for using this approach is to make the current this available to subfunctions or closures. For example:

var myObject = {
  param: 123,
  method: function(){
    alert( this.param );
  },
  method2: function(){
    setTimeout(function(){
      alert( this.param );
    },100);
  }
}

在上面调用 myObject .method 会为您提供 123 的正确提示。但是,调用 myObject.method2 将为您提供 undefined 。这是因为与 setTimeout 一起使用的匿名函数中的不会引用 myObject ,取决于JavaScript解释器,它将指向不同的东西。但是,如果你有:

In the above calling myObject.method will give you the correct alert of 123. However calling myObject.method2 will give you undefined. This is because this inside the anonymous function used with setTimeout does not refer to myObject, depending on the JavaScript interpreter it will point to different things. However, if you have:

method2: function(){
  var self = this;
  setTimeout(function(){
    alert( self.param );
  },100);
}

这是因为的当前状态—在正确的位置—被捕获,并且将始终为可用的每个函数范围引用 myObject

This works because the current state of this — at the right point — is captured, and will always reference myObject for every function scope that it is available to.

问题不在仅限于使用 setTimeout 。在任何你有匿名函数,子函数或闭包的地方,这个技巧都会派上用场。有时候人们使用 self 或更具描述性的东西,具体取决于当前引用所代表的内容。

The problem is not limited to the use of setTimeout. At any point where you have anonymous functions, subfunctions or closures this trick will come in handy. Sometimes people use self, or that or something a bit more descriptive depending on what the current reference represents.


有一种替代方法可以使用 self 或任何其他变量来记住任何特定点的状态,这就是绑定你的匿名或子具有特定上下文的函数。许多现代解释器现在支持 Function.prototype.bind 方法,因此可以使用:

There is an alternative to using self or any other variable to "remember" the state of this at any particular point, and that is to "bind" your anonymous or sub functions with a particular context. Many modern interpreters now support the Function.prototype.bind method, which can be used thusly:

var method = function(){
  console.log(this);
};
var methodWithWindow = method.bind(window);
var methodWithDocument = method.bind(document);
var methodWithObject = method.bind({random:"object"});

依次调用每个绑定方法将为您提供以下控制台输出:

Calling each of the bound methods in turn would give you the following console output:

Window
Document
Object {random:"object"}

如果您希望支持旧浏览器,可以使用 polyfill ,或者如果您更喜欢更简单的实现,也不用担心绑定参数。绑定代码的基本内容如下:

If you wish to support older browsers you can use a polyfill, or if you prefer a much simpler implementation, one that doesn't worry about binding arguments as well. The basics of what the bind code does is the following:

!Function.prototype.bind && (Function.prototype.bind = function(context){
  var method = this;
  return function(){
    method.apply(context, arguments);
  }
})

那么,初始示例如何使用bind?

So, how would the initial example look using bind?

method2: function(){
  setTimeout((function(){
    console.log(this); // `this` will be the same as the `this` passed to bind.
  }).bind(this),100);
}

如上所示,一旦绑定,返回的函数(闭包)保留指定的背景;因此它可以在任何你想要的地方传递,并且仍然保持这个对你想要的对象的引用。这在 method2 示例中非常有用,因为我们将方法与当前上下文捆绑在一起并将其传递给 setTimeout 稍后执行绑定方法(在我们退出当前块执行之后很久)。

As you can see above, once bound, the returned function (closure) retains that specified context; so it can be passed around where ever you want and still keep a this reference to the object you want. This is useful in the method2 example because we bundle the method up with our current context and pass it to setTimeout which will execute the bound method later (long after we have exited the current block execution).

使用 self 或任何其他变量。该变量将在函数的作用域链中捕获,并且在最终再次调用该函数时仍然可以进行访问。然而,使用 bind 的好处是,如果您愿意,可以轻松覆盖上下文,您必须编写自己的特定方法来覆盖 self 变量。

The same does occur for when using self or any other variable. The variable would be captured within the function's scope chain, and would still be there for access when the function is eventually called again. The benefit of using bind however is that you can override the context easily if you so wish, you would have to code your own specific methods to do so to override a self variable.


警告:值得注意的是绑定函数时,将返回一个新函数。如果将绑定函数与事件侦听器混合,然后尝试使用原始函数而不是绑定版本删除侦听器,则会导致混乱情况。

WARNING: It is worth noting here that when you bind a function, a new function is returned. This can cause confusing situations if you mix bound functions with event listeners and then attempt to remove the listeners using the original function rather than the bound version.

此外,因为绑定返回一个新函数,如果你绑定一个绑定函数,你实际上是在一个函数中包含一个函数,与另一个函数。您应该意识到这一点,因为它会影响性能,并且在避免内存泄漏方面会更难管理。我首选的绑定方法是使用带有自己的解构方法的闭包(即依赖self,但确保你有方法来取消它的内容),但这确实需要更多的前瞻性思维,并且在较小的JS项目中并不那么重要;或一次性功能绑定—特别是如果绑定方法永远不会被任何引用捕获。

Also, because binding returns a new function, if you bind a bound function you are in fact wrapping a function in a function, with another function. You should be aware of this because it affects performance and will prove trickier to manage in terms of avoiding memory leaks. My preferred approach to binding is to use closures with their own deconstruction methods (i.e. rely on self, but make sure you have methods to nullify it's content), but this does take more forward thinking and is not so relevant in smaller JS projects; or one off function bindings — especially if the bound method is never caught in any reference.


值得一提的是,有时你可以在不使用 bind ,而是使用 apply —哪些应该是您可以选择使用的本地可用。主要区别在于没有任何东西被函数包含,而调用apply实际上执行了那里的函数,然后使用不同的上下文—传递给apply的第一个参数。

It is also worth mentioning that sometimes you can achieve the same result without using bind at all, and instead use apply — which should be natively available in anything you may choose to use. The major difference being that nothing is wrapped up with the function, and calling apply actually executes the function there and then with a different context — the first argument passed to apply.

var externalMethod = function(){
  console.log(this); // will output myObject when called below
};

var myObject = {
  method2: function(){
    externalMethod.apply(this);
  }
};


只是详细说明这个—在最近的评论被删除之前。 将引用以下四种内容之一,具体取决于您在其中使用该函数的方式:

Just to elaborate this answer with further detail about this — before the recent comments get deleted. this will refer to one of four things, depending on how the function you are using it within was called:

myObject.method()

以上将有 myObject ,除非方法 .bind(context)应用了操作。在这种情况下这个将是最后一个绑定的上下文。

The above will have a this of myObject, unless method has had a .bind(context) operation applied. In which case this will be whatever the last bound context was.

unattachedFunction()

全局上下文(通常在浏览器环境中窗口),除非 unattachedFunction 有一个 .bind (上下文)应用了操作。在这种情况下这个将是最后一个绑定的上下文。

Will have a this of the global context (usually window in browser environments), unless unattachedFunction has had a .bind(context) operation applied. In which case this will be whatever the last bound context was.

anyFunction.apply(otherObject)

anyFunction.call(otherObject)

两者总是有一个 otherObject ,因为以这种方式调用将覆盖任何绑定。

Both will always have a this of otherObject, because calling in this way will override any binding.

new myObject()

将有一个引用 myObject 的新实例,这将覆盖任何绑定。

Will have a this that refers to a new instance of myObject, this will override any binding.


考虑以上所有因素什么这个 referencesMethod

Taking all the above into account, what would this be inside referencedMethod?

var referencedMethod = myObject.method;
referencedMethod();




正确!这将是全球背景。这就是为什么如果你想与其他对象或代码共享方法—但仍保留原始所有者作为上下文—你真的需要绑定,或保持与其所有者对象捆绑的功能,以便你可以打电话或申请。

Correct! it will be the global context. This is why if you want to share methods with other objects or code — but still retain the original owner as context — you really need to either bind, or keep the function bundled with its owner object so you can call or apply.

这篇关于在knockout.js视图模型中使用`var self = this`有什么好处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆