“这"是怎么回事?关键字在函数中起作用?
我刚刚在 JavaScript 中遇到了一个有趣的情况.我有一个类,其方法使用对象文字表示法定义多个对象.在这些对象中,正在使用 this
指针.从程序的行为中,我推断出 this
指针指的是调用该方法的类,而不是由字面量创建的对象.
I just came across an interesting situation in JavaScript. I have a class with a method that defines several objects using object-literal notation. Inside those objects, the this
pointer is being used. From the behavior of the program, I have deduced that the this
pointer is referring to the class on which the method was invoked, and not the object being created by the literal.
这似乎是任意的,尽管这是我期望它工作的方式.这是定义的行为吗?跨浏览器安全吗?是否有任何理由说明为什么它超出了规范所说的"(例如,它是一些更广泛的设计决策/哲学的结果)?精简代码示例:
This seems arbitrary, though it is the way I would expect it to work. Is this defined behavior? Is it cross-browser safe? Is there any reasoning underlying why it is the way it is beyond "the spec says so" (for instance, is it a consequence of some broader design decision/philosophy)? Pared-down code example:
// inside class definition, itself an object literal, we have this function:
onRender: function() {
this.menuItems = this.menuItems.concat([
{
text: 'Group by Module',
rptletdiv: this
},
{
text: 'Group by Status',
rptletdiv: this
}]);
// etc
}
推荐答案
从我的另一个帖子中被蚕食,这里比你想知道的更多这个.
Cannibalized from another post of mine, here's more than you ever wanted to know about this.
在开始之前,请记住关于 Javascript 的最重要的事情,并在没有意义时重复给自己听.Javascript 没有类(ES6 class
是 语法糖).如果某些东西看起来像一个类,这是一个聪明的把戏.Javascript 有对象和函数.(这不是 100% 准确,函数只是对象,但有时将它们视为独立的事物会有所帮助)
Before I start, here's the most important thing to keep in mind about Javascript, and to repeat to yourself when it doesn't make sense. Javascript does not have classes (ES6 class
is syntactic sugar). If something looks like a class, it's a clever trick. Javascript has objects and functions. (that's not 100% accurate, functions are just objects, but it can sometimes be helpful to think of them as separate things)
this 变量附加到函数.每当你调用一个函数时,this 都会被赋予一个特定的值,这取决于你调用函数的方式.这通常称为调用模式.
The this variable is attached to functions. Whenever you invoke a function, this is given a certain value, depending on how you invoke the function. This is often called the invocation pattern.
在 javascript 中有四种调用函数的方法.您可以将函数作为方法、函数、构造函数和apply调用.
There are four ways to invoke functions in javascript. You can invoke the function as a method, as a function, as a constructor, and with apply.
方法是附加到对象的函数
A method is a function that's attached to an object
var foo = {};
foo.someMethod = function(){
alert(this);
}
当作为方法调用时,this 将绑定到函数/方法所属的对象.在本例中, this 将绑定到 foo.
When invoked as a method, this will be bound to the object the function/method is a part of. In this example, this will be bound to foo.
如果你有一个独立的函数,this 变量将绑定到全局"对象,在浏览器上下文中几乎总是 window 对象.
If you have a stand alone function, the this variable will be bound to the "global" object, almost always the window object in the context of a browser.
var foo = function(){
alert(this);
}
foo();
这可能是你的绊脚石,但不要难过.许多人认为这是一个糟糕的设计决定.由于回调是作为函数而不是方法调用的,这就是为什么您会看到似乎不一致的行为.
This may be what's tripping you up, but don't feel bad. Many people consider this a bad design decision. Since a callback is invoked as a function and not as a method, that's why you're seeing what appears to be inconsistent behavior.
许多人通过做类似的事情来解决这个问题,嗯,这个
Many people get around the problem by doing something like, um, this
var foo = {};
foo.someMethod = function (){
var that=this;
function bar(){
alert(that);
}
}
你定义了一个变量that,它指向this.闭包(它自己的一个主题)使 that 存在,所以如果你调用 bar 作为回调,它仍然有一个引用.
You define a variable that which points to this. Closure (a topic all it's own) keeps that around, so if you call bar as a callback, it still has a reference.
注意:在 use strict
模式下,如果用作函数,this
不会绑定到全局.(它是未定义
).
NOTE: In use strict
mode if used as function, this
is not bound to global. (It is undefined
).
您也可以将函数作为构造函数调用.根据您使用的命名约定 (TestObject),这也可能是您正在做的事情,并且是您的绊脚石.
You can also invoke a function as a constructor. Based on the naming convention you're using (TestObject) this also may be what you're doing and is what's tripping you up.
您使用 new 关键字作为构造函数调用函数.
You invoke a function as a Constructor with the new keyword.
function Foo(){
this.confusing = 'hell yeah';
}
var myObject = new Foo();
当作为构造函数调用时,将创建一个新对象,并且 this 将绑定到该对象.同样,如果您有内部函数并且它们被用作回调,那么您将作为函数调用它们,并且 this 将绑定到全局对象.使用那个 var that = 这个技巧/模式.
When invoked as a constructor, a new Object will be created, and this will be bound to that object. Again, if you have inner functions and they're used as callbacks, you'll be invoking them as functions, and this will be bound to the global object. Use that var that = this trick/pattern.
有些人认为constructor/new关键字是Java/传统OOP程序员用来创建类似于类的东西的一种方式.
Some people think the constructor/new keyword was a bone thrown to Java/traditional OOP programmers as a way to create something similar to classes.
最后,每个函数都有一个名为apply"的方法(是的,函数是 Javascript 中的对象).Apply 可以让您确定 this 的值是什么,还可以让您传入一个参数数组.这是一个无用的例子.
Finally, every function has a method (yes, functions are objects in Javascript) named "apply". Apply lets you determine what the value of this will be, and also lets you pass in an array of arguments. Here's a useless example.
function foo(a,b){
alert(a);
alert(b);
alert(this);
}
var args = ['ah','be'];
foo.apply('omg',args);
相关文章