如何使用Object.create()而不是新建私有成员创建对象 [英] How to create an object with private members using Object.create() instead of new
问题描述
感谢Bergi。
pubPrivExample =(function(){
return {
init:function(){
var private;
this.setPrivate = function(p){
private = p;
};
this.getPrivate = function(){
return private;
};
},
public:这是public\ n
};
}());
var a;
a = Object.create(pubPrivExample);
a.init();
a.setPrivate(This is private);
document.write(a.getPrivate());
编辑:似乎我的问题的答案是切断的。我真的对工厂不感兴趣,实际上宁愿不使用。我的问题是关于私人国家。从Bergi的答案和评论我想我可以拉一些东西。
要继续...
编辑Bergi已经开始回答下面的问题了,但没有把私人国家的最重要的部分。
我有时间思考这个想法,但是在没有某种工厂的情况下,仍然无法使用Object.create()实现私有状态。但是我想错了,而且Bergi提到了一个解决方案...随便以Bergi的答案为出发点。
ORIGINAL:我的追求,以避免 new
在javascript中引导我走到一个特殊的地方。我想要私有对象成员,但我不想放弃 Object.create()
。
这里是代码。
var trackQueue = {};
trackQueue.factory = function(){
var that,queue;
that = this;
queue = [];
that.push = function(item){
queue.push(item);
};
that.work = function(){
document.write(queue +< br />);
};
return {
work:that.work,
push:that.push
};
};
var a = Object.create(trackQueue.factory());
a.push(a);
a.push(b);
a.push(c);
var b = Object.create(trackQueue.factory());
b.push(d);
b.push(e);
b.push(f);
a.work();
b.work();
和jsfiddle
http://jsfiddle.net/dsjbirch/Wj6cp/10/
将 init
成为工厂的更为惯用/适当的名称
方法?
这是疯狂吗?
要善良 - javascript不是我的第一种语言。
是的,原型上的init方法可能是一个更合适的名称:
code> var proto = {
init:function(args){
//设置private-scoped vars,
var example = args;
//特权方法
this.accessPrivate = function(){return example; };
//和其他东西
this.public = 5;
},
prop:defaultvalue,
...
}
var instance = Object.create(proto);
instance.init();
然而,绝对没有理由不使用具有新关键字的古典构造函数,它优雅地结合 Object.create
和 init
call。
请注意,您绝对没有使用 Object.create
。您的工厂模式(完全有效的应用)返回良好的对象。不需要为继承自他们的每个创建新对象。只要做:
var instance = trackQueue.factory();
如果您喜欢方法名称创建的声音,则可以使用更为惯用的名称你的工厂:
trackQueueFactory.create = function(args){...}
编辑:您的想法将工厂模式与原型继承没有错。然而,所有制造的对象从其继承的原始对象需要是静态的,而不是在每个调用上创建一个新的对象。您的代码可能如下所示:
var factory = {
proto:{
...
},
create:function(args){
var product = Object.create(this.proto);
//设置私有变量范围到创建函数
//特权方法
product.doSomethingSpecial = function(){...};
//和其他东西
}
};
var a = factory.create(...);
EDIT: I figured it out from Bergi's answer in the end.
Thanks Bergi.
pubPrivExample = (function () {
return {
init : function () {
var private;
this.setPrivate = function (p) {
private = p;
};
this.getPrivate = function () {
return private;
};
},
public : "This is public\n"
};
}());
var a;
a = Object.create(pubPrivExample);
a.init();
a.setPrivate("This is private");
document.write(a.getPrivate());
EDIT: It seems the answers to my question are off at a tangent. I'm really not interested in a factory and actually would rather not use if. My question is about private state. From Bergi's answers and comments I think I can pull something together.
To be continued...
EDIT: Bergi has started to answer the question below, but left out the most important part - the private state.
I have had time to think about the idea more, but am still unable to achieve private state using Object.create() without some kind of factory. But I want to be wrong, and Bergi alluded to a solution... Feel free to take Bergi's answer as a starting point.
ORIGINAL: My quest to avoid new
in javascript has lead me to a peculiar place. I want private object members, but I don't want to give up Object.create()
.
Here's the code.
var trackQueue = {};
trackQueue.factory = function () {
var that, queue;
that = this;
queue = [];
that.push = function (item) {
queue.push(item);
};
that.work = function () {
document.write(queue + "<br />");
};
return {
work : that.work,
push : that.push
};
};
var a = Object.create( trackQueue.factory() );
a.push("a");
a.push("b");
a.push("c");
var b = Object.create( trackQueue.factory() );
b.push("d");
b.push("e");
b.push("f");
a.work();
b.work();
And a jsfiddle
http://jsfiddle.net/dsjbirch/Wj6cp/10/
Would init
be a more idiomatic / appropriate name for the factory
method?
Is this insane?
Be kind - javascript isn't my first language.
Yes, a init method on the prototype might be a more appropriate name:
var proto = {
init: function(args) {
// setting up private-scoped vars,
var example = args;
// privileged methods
this.accessPrivate = function(){ return example; };
// and other stuff
this.public = 5;
},
prop: "defaultvalue",
...
}
var instance = Object.create(proto);
instance.init();
However, there is absolutely no reason not to use the classical constructor with the new keyword, which elegantly combines the Object.create
and init
call.
And note that you are using Object.create
with absolutely no use. Your factory pattern (perfectly valid applied) returns good objects. No need to create new objects for each one that inherit from them. Just do:
var instance = trackQueue.factory();
If you like the sound of the method name "create", you might use a more idiomatic name for your factory:
trackQueueFactory.create = function(args) {...};
EDIT: Your idea to combine the factory pattern with prototype inheritance is not so wrong. Yet, the proto object from which all the fabricated objects inherit needs to be static, instead of creating a new one on each invocation. Your code might look like this:
var factory = {
proto: {
...
},
create: function(args) {
var product = Object.create(this.proto);
// set up private vars scoped to the create function
// privileged methods
product.doSomethingSpecial = function(){ ... };
// and other stuff
}
};
var a = factory.create(...);
这篇关于如何使用Object.create()而不是新建私有成员创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!