我刚刚在 JavaScript 中遇到了一个有趣的情况。我有一个类,其方法使用对象文字表示法定义多个对象。在这些对象中,this正在使用指针。从程序的行为中,我推断出this指针指的是调用方法的类,而不是由字面量创建的对象。
this
这似乎是任意的,尽管这是我期望它工作的方式。这是定义的行为吗?跨浏览器安全吗?是否有任何理由说明为什么它超出了“规范所说的”(例如,它是一些更广泛的设计决策/哲学的结果)?精简代码示例:
// 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 }
从我的另一篇文章中蚕食,这里比你想知道的还要 多 。
在开始之前,请记住关于 Javascript 的最重要的事情,并在没有意义时对自己重复一遍。Javascript 没有类(ES6class是ES2015 (ES6) class 语法有什么好处?)。如果某些东西看起来像一个类,这是一个聪明的把戏。Javascript 有 对象 和 函数 。(这不是 100% 准确,函数只是对象,但有时将它们视为独立的事物会有所帮助)
class
this 变量附加到函数。每当你调用一个函数时, 它 都会被赋予一个特定的值,这取决于你调用函数的方式。这通常称为调用模式。
在javascript中有四种调用函数的方法。您可以将函数作为 方法 、 函数 、 构造函数 和 apply 调用。
方法是附加到对象的函数
var foo = {}; foo.someMethod = function(){ alert(this); }
当作为方法调用时, this 将绑定到函数/方法所属的对象。在此示例中,这将绑定到 foo。
如果你有一个独立的函数, this 变量将绑定到“全局”对象,几乎总是浏览器上下文中的 窗口 对象。
var foo = function(){ alert(this); } foo();
这可能是让你绊倒的原因 ,但不要难过。许多人认为这是一个糟糕的设计决定。由于回调是作为函数而不是作为方法调用的,这就是为什么您会看到看似不一致的行为。
许多人通过做类似的事情来解决这个问题,嗯,这个
var foo = {}; foo.someMethod = function (){ var that=this; function bar(){ alert(that); } }
您定义一个 指向 this 的 变量。闭包(它自己的一个主题)保留 了它 ,所以如果你调用 bar 作为回调,它仍然有一个引用。
注意:在use strict模式下,如果用作函数,this则不绑定到全局。(它是undefined)。
use strict
undefined
您还可以调用函数作为构造函数。根据您使用的命名约定 (TestObject),这也 可能是您正在做的事情,也是让您绊倒的事情 。
您使用 new 关键字将函数作为构造函数调用。
function Foo(){ this.confusing = 'hell yeah'; } var myObject = new Foo();
当作为构造函数调用时,将创建一个新对象,并将 this 绑定到该对象。同样,如果您有内部函数并且它们被用作回调,您将把它们作为函数调用,并且 this 将绑定到全局对象。使用那个 var that = 这个技巧/模式。
有些人认为constructor/new关键字是Java/传统OOP程序员用来创建类似于类的东西的一种方式。
最后,每个函数都有一个名为“apply”的方法(是的,函数是 Javascript 中的对象)。Apply 可以让你确定 this 的值是什么,还可以让你传入一个参数数组。这是一个无用的例子。
function foo(a,b){ alert(a); alert(b); alert(this); } var args = ['ah','be']; foo.apply('omg',args);