What is the best design pattern for achieving the following (which doesn't work)?
实现以下目标的最佳设计模式是什么(哪些不起作用)?
var obj = (function() {
// code defining private variables and methods
var _obj = {
property: value,
method1: function() {
// do stuff
},
method2: function() {
// use property
var prop = _obj.property; // obviously doesn't work
// call method1
obj.method1(); // "obj" not finished being defined yet!
}
};
// obviously now I could do...
var prop = _obj.property;
return _obj;
})();
// and I could now do...
obj.method1();
A variation which I think should work is
我认为应该有的变化是
var obj = (function() {
var property = value,
method1 = function() {
// do stuff
},
method2 = function() {
// use property
var prop = property;
// call method1
method1();
},
_obj = {
property: property,
method1: method1,
method2: method2
};
return _obj;
})();
Similarly, how does it work for objects meant to be created with the new
operator? Within the constructor function itself you can write this.method()
. But what if you want to keep the constructor small, only defining those things which will likely be customized upon creation, and then defining the rest in the prototype? (This seems to be the common pattern.) Can the properties / methods within the prototype interact in any way?
同样,它如何用于使用new运算符创建的对象?在构造函数本身中,您可以编写this.method()。但是,如果你想保持构造函数较小,只定义那些可能在创建时自定义的东西,然后在原型中定义其余的东西呢? (这似乎是常见的模式。)原型中的属性/方法可以以任何方式进行交互吗?
var MyObj = function(name) {
this.name = name;
};
var obj = new MyObj('Bob');
MyObj.prototype = {
called_often: function() {
// lots more code than just the following
return document.getElementById('someID').value;
},
global_default: 'value', // can be changed, so need to pull value when run
does_stuff: function(value) {
var str = global_default + value, // can't access global_default on its own
input = MyObj.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
name = this.name; // 'this' used in the prototype doesn't work
// even within a created object
return name + input + str;
}
};
I'm sure there's better ways to achieve my result whenever I run into this problem. This code isn't situation specific and just illustrates the general problem. So you won't be able to give me an alternative for those specific situations I run into. But maybe you can help my overall thinking.
我确信每当遇到这个问题时,有更好的方法来实现我的结果。此代码不是特定于具体情况,只是说明了一般问题。因此,您无法为我遇到的特定情况提供替代方案。但也许你可以帮我整体思考。
2 个解决方案
#1
33
Well, from your first example:
好吧,从你的第一个例子:
var _obj = {
property: value,
method1: function() {
// do stuff
},
method2: function() {
// use property
var prop = this.property;
// call method1
this.method1();
}
};
That's what the this
value is for.
这就是这个值的用途。
Now, what you cannot do is refer to a property of an "under construction" object from elsewhere in the object literal syntax. (It's hard to give an example because it's just not syntactically possible.) In cases where you want to do that, you do need one or more separate assignment statements.
现在,你不能做的是从对象文字语法的其他地方引用“正在构造”对象的属性。 (很难给出一个例子,因为它在语法上是不可能的。)如果你想这样做,你需要一个或多个单独的赋值语句。
#2
9
Guess what? You are making simple stuff complex. Pointy's answer is good, but the prototype way is better for several reasons. That's why I am describing (rather, making corrections in) the last method. Check this fiddle.
你猜怎么了?你正在制作复杂的简单东西。 Pointy的答案很好,但由于几个原因原型方法更好。这就是我在最后一种方法中描述(而不是纠正)的原因。检查这个小提琴。
var MyObj = function(name) {
this.name = name;
};
MyObj.prototype = {
called_often: function() {
// lots more code than just the following
return 'VALUE'; //document.getElementById('someID').value;
},
global_default: 'value', // can be changed, so need to pull value when run
does_stuff: function(value) {
var str = this.global_default + value, // can't access global_default on its own
input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
name = this.name; // 'this' used in the prototype doesn't work
// even within a created object
return name + input + str;
}
};
var obj = new MyObj('Bob');
#1
33
Well, from your first example:
好吧,从你的第一个例子:
var _obj = {
property: value,
method1: function() {
// do stuff
},
method2: function() {
// use property
var prop = this.property;
// call method1
this.method1();
}
};
That's what the this
value is for.
这就是这个值的用途。
Now, what you cannot do is refer to a property of an "under construction" object from elsewhere in the object literal syntax. (It's hard to give an example because it's just not syntactically possible.) In cases where you want to do that, you do need one or more separate assignment statements.
现在,你不能做的是从对象文字语法的其他地方引用“正在构造”对象的属性。 (很难给出一个例子,因为它在语法上是不可能的。)如果你想这样做,你需要一个或多个单独的赋值语句。
#2
9
Guess what? You are making simple stuff complex. Pointy's answer is good, but the prototype way is better for several reasons. That's why I am describing (rather, making corrections in) the last method. Check this fiddle.
你猜怎么了?你正在制作复杂的简单东西。 Pointy的答案很好,但由于几个原因原型方法更好。这就是我在最后一种方法中描述(而不是纠正)的原因。检查这个小提琴。
var MyObj = function(name) {
this.name = name;
};
MyObj.prototype = {
called_often: function() {
// lots more code than just the following
return 'VALUE'; //document.getElementById('someID').value;
},
global_default: 'value', // can be changed, so need to pull value when run
does_stuff: function(value) {
var str = this.global_default + value, // can't access global_default on its own
input = this.called_often(), // doesn't work; MyObj.prototype.called_often() DOES
name = this.name; // 'this' used in the prototype doesn't work
// even within a created object
return name + input + str;
}
};
var obj = new MyObj('Bob');