11

考虑到具有私有属性的对象创建模式,一种方法是:

function MyStack (){
    var list = [],
        index = 0;

    this.push =  function(val){ 
        return list[index++] = val;
    };
    this.pop = function(){// ...}
}

var stack1 = new MyStack();       stack1.push(5);
var stack2 = new MyStack();       stack2.push(11);

问题在于:Stack 的每个实例都有自己的方法“push”和“pop”的副本。

实现构造方法的另一种方法是:

function MyStack(){ 
    this.list = []; 
    this.index = 0;
}
MyStack.prototype = {
    insert: function(val){
            return this.list[this.index++] = val;
        },
    pop:function(){//...}
}

这里的问题:我们失去了列表和索引的隐私。

有没有办法让我们可以在实例之间重用方法和属性的隐私?

我知道我们可以将这个用于不对对象的任何状态进行操作的方法,但我更多地谈论的是那些对状态进行操作的方法。

4

4 回答 4

1

您应该查看 John Resig 的Simple Javascript Inheritance。这是一本很好的读物,并且已经扩展为提供对私有的支持,恰当地称为Privates.js

于 2012-10-09T23:36:15.213 回答
1

是的。我已经编辑了这段代码,所以它实际上完全可以按照您的预期工作。这对我来说似乎有点多余,但是,它确实为您提供了提供公共接口的能力,但让您的变量保持私有并控制用户与它们交互的方式。

function MyStack(){ 
    var list = []; 
    var index = 0;

    this.getIndex = function(){
        return index;
    }
    this.setIndex = function(val){
        index = val;
    }
    this.list = function(val){
        if(val){
           // setter if a value was provided. Illustrating how you can control
           // index, which I assume is the point of having these things private 
           // to begin with
           return list[this.setIndex(this.getIndex() + 1)] = val;
        }

        // always return list - acts like a getter
        return list;
    }
}
MyStack.prototype = {
    insert: function(val){
            return this.list(val);
        },
    pop:function(){}
}

var stack1 = new MyStack();       
stack1.insert(5);
var stack2 = new MyStack();       
stack2.insert(11);
于 2012-11-26T02:34:00.353 回答
1

构造函数可以返回任何对象(不一定是this)。可以创建一个构造函数,它返回一个代理对象,其中包含对“真实”实例对象的“真实”方法的代理方法。这听起来可能很复杂,但事实并非如此;这是一个代码片段:

var MyClass = function() {
    var instanceObj = this;
    var proxyObj = {
        myPublicMethod: function() {
            return instanceObj.myPublicMethod.apply(instanceObj, arguments);
        }
    }
    return proxyObj;
};
MyClass.prototype = {
    _myPrivateMethod: function() {
        ...
    },
    myPublicMethod: function() {
        ...
    }
};

好处是代理创建可以自动化,如果我们定义一个命名受保护方法的约定。我创建了一个这样做的小库:http: //idya.github.com/oolib/

于 2012-11-26T02:09:16.027 回答
0

我认为在您提到的两种方法中,当使用构造函数模式创建对象时,属性将被复制到其对象中。您提到的第一种方法是值得关注的。我觉得同样适用于第二种方法以及您对这种方法的关注。

当我们想将“MyStack”的属性扩展到其他类时,我们通常会使用您提到的第二种方法。

假设我想将您的类 MyStack 扩展到 MyTest,如下所示

var dummy = function();
dummy.prototype = MyStack.prototype;
var MyTest = function(){
};
MyTest.prototype = new dummy(); // Assigning MyStack properties to MyTest
var obj = new MyTest();
于 2012-10-02T09:43:16.210 回答