在我喋喋不休地谈论魔法之前,快速提供有关最佳实践的建议this多变的。如果您希望 Javascript 中的面向对象编程 (OOP) 能够密切反映更传统/经典的继承模式,请选择一个框架,了解其怪癖,并且不要试图变得聪明。如果你想变得聪明,就将 javascript 作为一种函数式语言来学习,并避免考虑类之类的事情。
这提出了关于 Javascript 需要牢记的最重要的事情之一,并在没有意义时对自己重复一遍。 JavaScript 没有类。如果某个东西看起来像一个类,那么这是一个聪明的技巧。 JavaScript 有objects(不需要嘲笑的引用)和功能。 (这不是 100% 准确,函数只是对象,但有时将它们视为单独的事物会有所帮助)
The this变量附加到函数上。每当你调用一个函数时,this被赋予一定的值,具体取决于您调用该函数的方式。这通常称为调用模式。
JavaScript 中有四种调用函数的方法。您可以将该函数作为method, as a function, as a 构造函数, 与apply.
作为一种方法
方法是附加到对象的函数
var foo = {};
foo.someMethod = function(){
alert(this);
}
当作为方法调用时,this将绑定到函数/方法所属的对象。在此示例中,这将绑定到 foo。
作为函数
如果您有独立的功能,this变量将绑定到“全局”对象,几乎总是window浏览器上下文中的对象。
var foo = function(){
alert(this);
}
foo();
这可能就是让你绊倒的原因,但不要感觉不好。许多人认为这是一个糟糕的设计决策。由于回调是作为函数而不是方法调用的,因此您会看到看似不一致的行为。
许多人通过做类似的事情来解决这个问题
var foo = {};
foo.someMethod = function (){
var that=this;
function bar(){
alert(that);
}
}
你定义一个变量that这指向this。关闭(它自己的主题)保留that
周围,所以如果你调用 bar 作为回调,它仍然有一个引用。
作为建造者
您还可以调用函数作为构造函数。根据您使用的命名约定(TestObject
) 这也是可能是你正在做的事情并且是让你绊倒的原因.
您可以使用以下命令将函数作为构造函数调用new
关键词。
function Foo(){
this.confusing = 'hell yeah';
}
var myObject = new Foo();
当作为构造函数调用时,将创建一个新对象,并且this将绑定到该对象。同样,如果您有内部函数并且它们被用作回调,您将把它们作为函数调用,并且this将绑定到全局对象。用那个var that = this;
技巧/模式。
有些人认为 constructor/new 关键字是扔给 Java/传统 OOP 程序员的一块骨头,作为创建类似于类的东西的一种方式。
使用应用方法。
最后,每个函数都有一个名为的方法(是的,函数是 Javascript 中的对象)apply
。应用可以让您确定什么值this将会是,并且还允许您传递一个参数数组。这是一个无用的例子。
function foo(a,b){
alert(a);
alert(b);
alert(this);
}
var args = ['ah','be'];
foo.apply('omg',args);