我有JavaScript组件,具有以下架构:
var MyComponent = function(params)
{
setup(params);
this.doSomething()
{
// doing something
};
function setup(params)
{
// Setup
// Interaction logic
var _this = this; // "this" points to DOMWindow, not to created object
$(".some-element").click(function(){
_this.doSomething(); // it craches here, because of above
});
}
};
当由交互逻辑控制的事情发生时,有时我必须将执行转发给组件的“公共”方法。
在这种情况下,我对“this”指针有疑问。
示例代码演示了它:
var Item = function()
{
this.say = function()
{
alert("hello");
};
this.sayInternal = function()
{
_sayInternal();
};
function _sayInternal()
{
this.say();
};
};
要测试它,
var o = new Item();
o.say(); // alerts "hello"
o.sayInternal();
我收到错误:
TypeError:表达式'this.say'[undefined]的结果不是函数。
我认为,这样的行为发生了,因为_sayInternal()函数是声明(并没有分配给对象,比如“this.say = function()”)。这样,它在所有创建的对象之间共享,并且像C ++中的静态函数一样。
这是真的吗?
答案 0 :(得分:3)
不,sayInternal
不在创建的对象之间共享。但是你是对的,创建的对象无法访问sayInternal
,因为它没有分配给它们。此函数仅对构造函数本地。
this
始终引用调用函数的上下文。如果您将其称为func()
,则this
引用全局对象(window
in浏览器)。如果您将该函数设置为对象的属性并使用obj.func()
进行调用,则this
将引用obj
。
如果为变量分配“绑定”函数并调用它:
var method = obj.func;
method();
然后this
将再次引用全局对象。在JavaScript中,函数与任何其他值一样,它们与分配给它们的对象没有特殊的关系。
var MyComponent = function(params)
{
setup.call(this, params); // <- using `call`
this.doSomething()
{
// doing something
};
function setup(params)
{
// Setup
// Interaction logic
var _this = this; // "this" to new created object
$(".some-element").click(function(){
_this.doSomething();
});
}
};
或在你的其他例子中:
var Item = function()
{
this.say = function()
{
alert("hello");
};
this.sayInternal = function()
{
_sayInternal.call(this);
};
function _sayInternal()
{
this.say();
};
};
也就是说,这种向对象分配函数的方法并不好,因为每个实例都有自己的this.sayInternal
函数。因此,对于上面的Item
代码,每个实例的创建都涉及创建三个函数,这会浪费内存。
使用prototype inheritance会更好:
var Item = function() {
};
Item.prototype = (function() {
function _sayInternal() {
this.say();
};
return {
say: function() {
alert("hello");
},
sayInternal: function(){
_sayInternal.call(this);
}
}
}());
这样,_sayInternal
只创建一次并且所有实例都继承(引用)原型,因此say
和sayInternal
也只存在一次。使用立即功能的“技巧”只能_sayInternal
和say
访问sayInternal
。