基本上,我使用了一个名为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((,您可以在任何使用回调函数的地方使用它。