Javascript类范围

时间:2011-03-18 23:46:14

标签: javascript jquery

我无法从Post.success函数中调用this.RenderDeals()。我认为这与范围有关?有人可以解决这个问题,并可能建议一个解决方法。我试过使用原型和模块模式,两者都没有运气。

FYI Post是一个$ .ajax包装器,它返回一个jQuery Deferred对象。

    function Deals() {
        this.template = '#trTemplate';
        this.container = '#containerTable';
        this.GetDeals = function () {
            Post('Deal.svc/GetDeals')
            .success(function (result) {
                this.RenderDeals(result);
            });
        };
        this.RenderDeals = function (deals) {
            $(this.template).tmpl(deals).appendTo(this.container);
        }
    }


    var deal = new Deals();
    deal.GetDeals();

更新:

好的,所以我在GetDeals函数上方添加了以下行:

var me = this;

而是打电话

me.RenderDeals(result);

似乎正常工作,但我不确定原因。

5 个答案:

答案 0 :(得分:5)

“成功”功能中的this引用几乎肯定不是您认为的那样。试试这个改变:

function Deals() {
    var instance = this;

    this.template = '#trTemplate';
    this.container = '#containerTable';
    this.GetDeals = function () {
        Post('Deal.svc/GetDeals')
        .success(function (result) {
            instance.RenderDeals(result);
        });
    };
    this.RenderDeals = function (deals) {
        $(this.template).tmpl(deals).appendTo(this.container);
    }
}

通过在“instance”变量中隐藏对this的引用,您的处理程序在调用其他函数(“RenderDeals”)时将有一种保证返回相关实例的方法。

答案 1 :(得分:2)

首先,javascript中没有类,只有对象。这可能听起来很奇怪,但你仍然可以在javascript中没有它们做OOP :)我建议你阅读这篇文章。

您对范围问题是正确的,this关键字有一些奇怪的行为。请阅读this了解更多信息。

查看使用任何函数对象的prototype属性。我更喜欢以下列方式进行javascript OOP:

function Deals(){
    //this is your constructor
    var me = this;
    //this way you can avoid having to search the DOM every time you want to reference
    //your jquery objects.
    me.template = $('#trTemplate');
    me.container = $('#containerTable');
}
Deals.prototype.getDeals = function(){
    var me = this;
    Post('Deal.svc/GetDeals')
    .success(function (result) {
        me.RenderDeals(result);
    })
}
Deals.prototype.renderDeals = function(){
    var me = this;
     me.template.tmpl(deals).appendTo(me.container);
}

通过在每个原型函数的顶部声明var me = this;,您创建一个引用感兴趣对象的闭包,甚至在回调内部:)

答案 2 :(得分:0)

为什么不在Deals()之外定义RenderDeals()?

    function RenderDeals(dealsObj, dealsData) {
        $(dealsObj.template).tmpl(dealsData).appendTo(dealsObj.container);
    }

然后代替:

this.RenderDeals(result);

这样做:

RenderDeals(this, result);

答案 3 :(得分:0)

试试这个:

var Deals = {
    template: $('#trTemplate'),
    container: $('#containerTable'),
    init: function (){
        return Deals;
    }
    GetDeals: function () {
        Post('Deal.svc/GetDeals')
        .success(function (result) {
            Deals.RenderDeals(result);
        })
    },
    RenderDeals = function (deals) {
        Deals.template.tmpl(deals).appendTo(Deals.container);
    }
}

var deal = Deals.init();
deal.GetDeals();

答案 4 :(得分:0)

你是对的,这是一个范围问题。 Pointy有正确的答案,但我想我可以填写一些正在发生的事情。

javascript中的

this是一个隐式变量,默认设置为函数附加到的任何值(如果没有附加到任何东西,则设置为全局对象)。当您将函数作为参数传递给Post#success时,它不会附加到任何实例,更不用说当前的Deals事件。

Pointy在这里有最好的答案,他正在做的是创建一个显式变量来捕获this交易的隐含变量。 javascript最酷的特性之一是函数定义范围内的所有内容也都在函数调用的范围内,因此通过创建该变量,您可以在以后再次访问它,无论何时匿名函数是调用。