使用实例变量的简单JavaScript继承

时间:2014-02-06 09:33:55

标签: javascript inheritance private-members

我正在尝试使用: Simple Javascript Inheritance by John Resig

我发现真正有限的是变量不是对象实例的私有。 这个简单的事实是一个人选择采用这种方法的关键因素之一。

我在链接页面的评论中看到有人建议如下:

init: function() {
  // Private var
  var _div = $( div );
  // Priviledged method accesses private var
  this.getDiv = function () { return _div; }
  this.setDiv = function (div) { _div = div; }
  // other initialization stuff
}

我对这种方法有些怀疑:

  1. 在我宣布的课程中,我是否需要始终通过setter和getter访问这些变量?
  2. 如何在内部函数的定义中使用此变量?
  3. 比如说:

    node.append("title").text(function(d) { /* use private variable */ });
    

    有人克服了这个限制吗?

    谢谢和最好的问候

    塞尔吉奥

2 个答案:

答案 0 :(得分:0)

Javascript确实没有很好地执行私有实例变量。它可以装备,但它很毛茸茸。为了真正做到这一点,你必须在初始化器中创建所有方法。

var Foo = function() {
  var bar = 9;

  this.squarePrivate = function() {
    return bar * bar;
  };
}

new Foo().squarePrivate() //=> 81

这意味着必须在实例构造函数的范围内创建每个函数,因此它可以访问这些本地变量。因此实例化对象的速度较慢。

如果您使用基于类或原型样式的方法,那么真的 可以很好地执行私有实例变量。

使用在构造函数中创建的getter / setter方法可以工作,但那些getter和setter是公共的,所以它不允许你隐藏值,只包含它的get和set逻辑。如果你保留了getter和setter,就没有必要将它们设为私有。

一个常见的约定是使用下划线为私有属性添加前缀,这可以告诉人们不要弄乱它。但是,如果暴露数据是一个安全问题,这显然是一个坏主意。

init: function() {
  this._bar = 9; // people will see instance._bar, but get the hint not to touch
},
squarePrivate: function() {
  return this._bar * this._bar;
}

但回答你的问题:

  

在我宣布的课程中,我是否需要始终通过setter和getter访问这些变量?

是。只有init函数才能访问局部变量,因此在该范围内创建的setter和getter函数也可以访问该局部变量。但是那个局部变量不能在别处访问,所以你必须使用getters / setter。

  

如何在内部函数的定义中使用此变量?

这就是整个问题。如果您使用 public getter,请调用它们,但这意味着数据实际上是公开的。或者如果你使用我的第一个例子,只需引用本地var。或者,如果您使用下划线属性,请引用它。

答案 1 :(得分:0)

首先,谢谢Alex的回复。我花了一些时间来消化你通过我的所有事情。

我想回答我的问题,因为我有特殊的需求,我觉得这个问题最初没有提出来。

我们还要补充一点,数据隔离不是问题,因为在我的应用程序中,我将创建层次结构的实例并在其上调用方法。人们最终需要提供“root”对象的新实现,我的应用程序将在需要时使用它们。

我实际做了一些测试,并确保在init方法中声明的变量如下:

this._instanceVar

实际上由实例本身拥有。在类中声明的其他方法中,我可以通过简单地引用它们来访问它们。

对于第二点而言,我找到了一个解决方案,它不会完全吸引我,但我会坚持下去。重点是将 this 复制到关于我声明的方法的闭包的本地变量中。这个变量允许我将内容传递给内部函数:

例如:

var Person = Class.extend({
    init: function() {
        this._name;
    },
    printNameOnClick: function() {
        var thiz = this;
        document.getElementById('nameDiv').addEventListener("click", function() {
            document.getElementById('nameDiv').innerHTML = thiz.name;
        });
    }
}

或者whaterver。

这一点的全部意义虽然是能够在动态上实现一个特定对象的实例,在该实例上可以调用单个方法。 分层模型允许我确保在列表中将调用顶级类中的函数。

致以最诚挚的问候,

塞尔吉奥