Javascript 此指针来自内部函数

Javascript 此指针来自内部函数,javascript,scope,Javascript,Scope,我有JavaScript组件,具有以下体系结构: var MyComponent = function(params) { setup(params); this.doSomething() { // doing something }; function setup(params) { // Setup // Interaction logic var _this = thi

我有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=新项目()

  • 这很好:
o.say();//提醒“您好”

  • 这导致:
o.sayinteral()

我得到一个错误:

TypeError:表达式“this.say”[undefined]的结果不是函数

我认为,之所以会发生这种行为,是因为_sayinteral()函数是声明的(并且没有分配给object,比如“this.say=function()”)。这样,它就可以在所有创建的对象之间共享,并且像C++中的静态函数一样运行。
这是真的吗?

不,
sayinteral
在创建的对象之间不共享。但是您是对的,创建的对象没有访问
sayinteral
的权限,因为它没有分配给它们。此函数仅是构造函数的局部函数

始终引用调用函数的上下文。如果像
func()
那样调用它,则
引用全局对象(在浏览器中为
窗口
)。如果将函数设置为对象的属性,并使用
obj.func()
调用它,则
将引用
obj

如果将“绑定”函数指定给变量并调用它:

var method = obj.func;
method();
然后,
将再次引用全局对象。在JavaScript中,函数与任何其他值一样,它们与分配给它们的对象没有特殊关系


您可以使用或显式设置上下文:


也就是说,这种将函数分配给对象的方法并不好,因为每个实例都有自己的
this.sayinteral
函数。因此,对于上面的
代码,每次创建一个实例都需要创建三个函数,这是对内存的浪费

更好的方法是利用:

var Item = function() {
};

Item.prototype = (function() {
    function _sayInternal() {
        this.say();
    };

    return {
        say: function() {
            alert("hello");
        },
        sayInternal: function(){
            _sayInternal.call(this);
        }
    }
}());
这样,
\u sayinteral
只创建一次,所有实例都继承(引用)原型,因此
say
sayinteral
也只存在一次。带有即时功能的“技巧”使
\u sayinteral
只能通过
say
sayinteral
访问

var Item = function()
{
    this.say = function()
    {
        alert("hello");
    };
    this.sayInternal = function()
    {
        _sayInternal.call(this);
    };
    function _sayInternal()
    {
        this.say();
    };
};
var Item = function() {
};

Item.prototype = (function() {
    function _sayInternal() {
        this.say();
    };

    return {
        say: function() {
            alert("hello");
        },
        sayInternal: function(){
            _sayInternal.call(this);
        }
    }
}());