基本上,我使用一个名为Joose的元类框架用于Javascript,它允许我使用更优雅的类语法 - 但我不知道如何引用对象的范围来自更深层次的类声明方法。我还使用require.js进行dependemcy管理...
这是一个示例类定义:
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调用的范围 - 没问题。但是,我发现自己在我的班级声明中几乎每一个方法都这样做!如何以干净有效的方式在所有方法中引用self?我知道你可以通过设置一个参数来使用AJAX中的范围,假设它不仅仅是AJAX,而是将范围关闭到外部的其他函数。
感谢。
答案 0 :(得分:2)
每次嵌套函数时,都必须考虑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()
->
发挥正常作用。但是胖箭=>
将保留函数内外this
的值。它在实例方法中的回调非常方便。当编译为JS时,它基本上为你做了self = this
别名,每次在内部函数中使用self
来引用this
。它很漂亮。
在简单的JS中,最常见的模式只是self = this
,坚持下去。
答案 1 :(得分:1)
答案是使用this
。你只需要创建一个闭包(当你有一个将被称为对象外部的函数时,你可以用var self = this;
创建一个闭包。(正如你在这里用ajax调用返回的那样)。
没有其他方法可以创建闭包。
要清楚(因为有些人会在任何轻微的技术手上挥动),你不需要“创造”闭合。但我认为你应该 - JavaScript设计用于闭包,它们运行良好,并且其他JavaScript程序员也很好理解。
答案 2 :(得分:0)
我发现自己在我的班级声明中几乎每一个方法都这样做了!如何以干净有效的方式在所有方法中引用自我?
你做不到。 self
的值(this
引用的实例)仅在调用方法时才知道。
如果您在构造函数(您的self
方法中)声明了这个变量并且在那里创建了所有回调函数,那么您只能解决这个问题并使用一个常见的init
变量。但是,可能不是最节省内存的方法:
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);
},
// …
}
});
答案 3 :(得分:0)
除了始终将MyClass的所有实例保留在范围内(或作为全局变量)之外,我没有看到任何解决方案。但是,您可以通过使用self
:
Function.prototype.bind
$.get('ajax/test.html', function(response) {
this.someVarToBeSetUsingAjax = response.value;
}.bind(this));
这不仅限于$ .get(),您可以在使用回调函数的任何地方使用它。