引用外部对象的Javascript作用域



基本上,我使用了一个名为Joose for Javascript的元类框架,它允许我使用更优雅的类语法,但我不知道如何从类声明的深层方法中引用对象的范围。我还使用require.js进行依赖性管理。。。

下面是一个类定义示例:

   define([
      'jquery',
      'handlebars',
   ], function($, Handlebars){
      var MyClass = Class("MyClass", {
         //inheritance         
         isa: SuperClass,
         //instance vars
         has: {
            hello:{
               is: 'r',
               init: 'Hi There!',
            },
            someVarToBeSetUsingAjax:{
               is: 'rw',
               init: false,
            },
         },
         //methods
         methods: {
            init: function () {
               var self = this;
               self.getAjaxVar();
            },
            getAjaxVar: function() {
               var self = this;
               //HOW CAN I REFERENCE 'self' THROUGHOUT MY OBJECT?
               $.get('ajax/test.html', function(response) {
                 self.someVarToBeSetUsingAjax = response.value;
               });
            },
            //lots more methods...
         }
    });
   return MyClass;
});

好吧,所以我的问题是——在AJAX函数中,我必须编写var self=this,才能将我的对象放入AJAX调用的范围内——没问题。但是,我发现自己对类声明中的几乎每一个方法都这样做!我如何才能在所有的方法中以一种干净有效的方式参考自我?我知道你可以通过设置一个参数来使用AJAX中的作用域,假设它不仅仅是AJAX,还有其他函数将作用域关闭到外部。

谢谢。

每次嵌套函数时,都必须考虑this。但是,如果你不嵌套一个函数,或者该函数不使用this,你就不需要考虑它

        init: function () {
           var self = this;
           self.getAjaxVar();
        },

所以在这种情况下没有必要。这是完全一样的:

        init: function () {
           this.getAjaxVar();
        },

但是这里:

        getAjaxVar: function() {
           var self = this;
           $.get('ajax/test.html', function(response) {
             self.someVarToBeSetUsingAjax = response.value;
           });
        },

您创建了一个内部函数,并且希望引用this的原始值,因此必须将this别名为self才能访问它。

没有办法将this固定为类中任何位置的值。


也就是说,你确实有一些选择。

Function.prototype.bind()可以提供帮助。

var func = function() { return this.name };
var obj = { name: 'Bob' };
var boundFunc = func.bind(obj);
boundFunc(); // 'Bob'

bind将返回一个新函数,其中this始终设置为特定对象。

因此:

        getAjaxVar: function() {
           $.get('ajax/test.html', function(response) {
             this.someVarToBeSetUsingAjax = response.value;
           }.bind(this));
        },

请注意,并非所有浏览器都支持此功能,您可能需要为旧浏览器添加一个填充程序。

或者只是习惯self = this


我还想对coffeescript稍微点赞,因为它支持在运行时不更改上下文的函数声明。

obj = {
  name: "bob"
  sayHello: ->
    doSomeAjax({
      success: =>
        alert "successfully made " + this.name + " say hello!"
    })
}
obj.sayHello()

CCD_ 11起正常作用。但是胖箭头=>将在函数内外保留this的值。它在实例方法内的回调中非常方便。当编译到JS时,它基本上为您做了一个self = this别名,每次都在内部函数中使用self来引用this。它很光滑。

然而,在普通的JS中,最常见的模式只是self = this,请坚持它。

答案是使用this。您只需要创建一个闭包(当您有一个将在对象外部调用的函数时,您可以使用var self = this;来创建闭包。

没有其他方法可以创建闭包。


要明确的是(因为有些人会在任何轻微的技术挥手时跳起来(,你不需要创建一个闭包。但我认为你应该——JavaScript是为处理闭包而设计的,它们工作得很好,其他JavaScript程序员也很理解它们。

我发现自己对类声明中的几乎每一个方法都这样做!我如何才能在所有的方法中以一种干净有效的方式参考自我?

你不能。this引用的实例self的值只有在调用该方法时才知道。

如果您在构造函数(您的init方法?(中声明了一个公共self变量,并在那里创建了所有回调函数,那么您只能绕过这个问题并使用它。不过,可能不是内存效率最高的方法

return Class("MyClass", {
     // …
     methods: {
         init: function () {
             var self = this;
             this.ajaxVarCallback = function(response) {
                 self.someVarToBeSetUsingAjax = response.value;
             };
             // and other functions that use "self"
             this.getAjaxVar();
         },
         getAjaxVar: function() {
             $.get('ajax/test.html', this.ajaxVarCallback);
         },
         // …
     }
});

除了始终将MyClass的所有实例保留在作用域中(或作为全局变量(之外,我看不到任何解决方案。但是,您可以通过使用Function.prototype.bind:来避免在任何地方声明self

$.get('ajax/test.html', function(response) {
  this.someVarToBeSetUsingAjax = response.value;
}.bind(this));

这并不局限于$.get((,您可以在任何使用回调函数的地方使用它。

相关内容

  • 没有找到相关文章

最新更新