English 中文(简体)
继承原型中的私人变量
原标题:Private variables in inherited prototypes
  • 时间:2010-09-01 10:35:23
  •  标签:
  • javascript

我认为,我误解了Javascript如何传承遗产。 具体而言,原型内部变量似乎在多个不同次级目标之间共享。 最容易用法典说明:

var A = function()
{
  var internal = 0;
  this.increment = function()
  {
    return ++internal;
  };
};

var B = function() {};
// inherit from A
B.prototype = new A;

x = new B;
y = new B;

$( #hello ).text(x.increment() + " - " + y.increment());​

这一产出<代码>1 - 2(在JSBin上测试),而我完全预计结果为1 - 1,因为我有两个不同的物体。

我如何确保<代码> A 物体在的多种情况下共有物体 B

rel=“noretinger”> 第条突出了一些问题:

问题是,每一种办法都用来制造私人变数,而这种变数是细劳的,也是在行动上,如果你改变一个标的私人变数,就会使所有人发生变化。 I.e. 它比实际的私人变数更像是一种私人固定财产。

因此,如果你想拥有一些私人东西,更像非公共不变,那么上述任何办法都是好的,但并非针对实际的私人变量。 私人变量仅与 Java本的单一吨物体有效。

<>Solution:按照BGerrissen的回答,修改B的声明,并按原样将原型工程留给:

var B = function() { A.apply(this, arguments); };
最佳回答

私人成员利用私生继承.。 一个人不能继承。 你们需要在每个建筑商中创造私人成员。 你们可以通过在子层中应用超级建筑商或创建矫正器来做到这一点。

决定因素:

function internalDecorator(obj){
    var internal = 0;
    obj.increment = function(){
        return ++internal;
    }
} 

var A = function(){
    internalDecorator(this);
}
A.prototype = {public:function(){/*etc*/}}

var B = function(){
    internalDecorator(this);
}
B.prototype = new A(); // inherits  public  but ALSO redundant private member code.

var a = new B(); // has it s own private members
var b = new B(); // has it s own private members

这只是超级建筑商呼吁的一种变式,因此,你也可以用<代码>的“实际超级建筑商”来做到这一点。

var B = function(){
    A.apply(this, arguments);
}

现在,通过<条码>B.prototype = 新的A()适用继承,请从<条码>中援引无必要建筑规范。 A。 避免这种情况的方法是使用Douglas Crockfords的植被方法:

Object.beget = function(obj){
    var fn = function(){}
    fn.prototype = obj;
    return new fn(); // now only its prototype is cloned.
}

您使用的是:

B.prototype = Object.beget(A.prototype);

当然,你可以完全放弃遗产,并很好地利用矫正器,至少在需要私人成员的情况下。

问题回答

你们需要忘记课堂的想法。 Java语中确实没有这样的东西作为B的例子。 您仅通过打造者B号功能而获得一些物体。 物体具有特性。 有些是“自有”的特性,另一些则通过搜索原型链而列入。

当你说<代码>新A时,你再造一个物体。 然后,你将其指定为B的原型,这意味着每打<代码>new B就会产生一个具有相同直接原型的新物体,从而产生相同的对应变量。

在Tim Down的回答中,有两种选择。 他的<代码>IncrementPublic使用继承法,但使对应变量公诸于世(即放弃资本)。 虽然increment Internal使反法成为私人,但通过将守则移至B(即放弃继承)。

你们想要的是三个方面:

  • inheritable behaviour - so it must be defined in A and require no code in B aside from setting the prototype
  • private data, stored in closure-local variables
  • per-instance data, stored in this.

问题是最后两点之间的矛盾。 我还要说,继承在联合材料中的价值有限。 最好将其作为一种实用语言对待:

// higher-order function, returns another function with counter state
var makeCounter = function() {
  var c = 0;
  return function() { return ++c; };
};

// make an object with an  increment  method:
var incrementable = {
  increment: makeCounter()
};

在个人方面,我往往避免大部分时间的建造和原型继承。 在联合调查中,他们比来自联络处背景的人所假定的有用程度要低得多。

我对你在最新发言表示不安:

Private variables only work really well with singleton objects in JavaScript.

实际情况并非如此。 物体只是一种特性的字典,其中任何一种可能具有功能。 因此,我们忘记了目标,思考了职能。 您可以根据某种模式,通过撰写恢复职能的职能,创造多种职能。 <代码>makeCounter, 这方面的例子只是一个简单的例子。 <代码>makeCounter不是“singleton Object” ,tn t必须限于在单一吨物体中使用。

原型的点是,它由多个物体(即由同一建筑功能产生的物体)共同使用。 如果你们需要不共享原型的物体的变量,那么,你们需要将这些变量保留在每一物体的构造功能之内。 只是利用原型分享方法。

举例来说,你可以完全使用原型。 这里是你可以做的。 参见Daniel Earwicker, 回答说,现在我在此重复一点。

var A = function() {};

A.prototype.incrementPublic = function()
{
    return ++this.publicProperty;
};

var B = function()
{
    this.publicProperty = 0;
    var internal = 0;
    this.incrementInternal = function()
    {
      return ++internal;
    };
};

B.prototype = new A();

var x = new B(), y = new B();
console.log(x.incrementPublic(), y.incrementPublic()); // 1, 1
console.log(x.incrementInternal(), y.incrementInternal()); // 1, 1

我刚刚找到了其他trick办法,没有向公共目标出口任何方法/工具。

function A(inherit) {
    var privates = { //setup private vars, they could be also changed, added in method or children
        a: 1,
        b: 2,
        c: 3
    };
    //setup public methods which uses privates
    this.aPlus = bindPlus("aPlus", this, privates); //pass method name as string!
    this.aGet = bindPlus("aGet", this, privates);
    if (inherit) {
        return privates;
    }
}
A.prototype.aPlus = function () {
    var args = getArgs(arguments),
        //self is "this" here 
        self = args.shift(),
        privates = args.shift(),
        //function real arguments
        n = args.shift();
    return privates.a += n;
};

A.prototype.aGet = function (n) {
    var args = getArgs(arguments),
        self = args.shift(),
        privates = args.shift();
    console.log(this, self, privates);
    return privates.a;
};

//utilites
function getArgs(arg) {
    return Array.prototype.slice.call(arg);
}

function bindPlus(funct, self, privates) {
    return function () {
        return Object.getPrototypeOf(self)[funct].bind(this, self, privates).apply(null, arguments);
    };
}

//inherited 
function B(inherit) {
    var privates = Object.getPrototypeOf(this).constructor.call(this, true);
    privates.d = 4;
    this.dGet = bindPlus("dGet", this, privates);
    if (inherit) {
        return privates;
    }
}

B.prototype = Object.create(A.prototype);
B.constructor = B;

B.prototype.aGet = function () {
    var args = getArgs(arguments),
        self = args.shift(),
        privates = args.shift();
    console.warn("B.aGet", this, privates);
    return privates.a;
};

B.prototype.dGet = function () {
    var args = getArgs(arguments),
        self = args.shift(),
        privates = args.shift();
    console.warn("B.dGet", this, privates);
    return privates.d;
};


// tests
var b = new B();
var a = new A();

//should be 223
console.log("223 ?",b.aPlus(222));

//should be 42
console.log("41",a.aPlus(222));

http://jsfiddle.net





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签