如何使用Object.create()而不是新建私有成员创建对象 [英] How to create an object with private members using Object.create() instead of new

查看:122
本文介绍了如何使用Object.create()而不是新建私有成员创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我从Bergi的答案中得出结论。



感谢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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆