0

我正在寻找一种完美的方式来定义类。“完美”在这里意味着:`

  1. 创建实例不会创建方法的副本。
  2. 公共功能可以轻松(不麻烦)访问私有变量

例如方式一:

function Foo1() {
  var private1;
  this.publicMethod1 = function() {//create instance will create copy of this function}
}

将不符合上述第 1 条规则。

另一个例子,方式2:

 function Foo2() {
      var private2;

    }
 Foo2.prototype.Method2 = function() {//cannot access private2}

将不符合上述第 2 条规则。

那么是否有可能同时满足这两个规则呢?谢谢。

4

4 回答 4

1

在 JavaScript 中,它更多的是关于约定。私有属性或方法首先使用下划线定义,例如_private. 使用一些助手,您可以轻松地制作课程。我发现这个设置很简单,你只需要一个inherits扩展类的助手,而不是使用多个参数,你传入一个对象props并简单地在继承的类上调用“super” arguments。例如,使用模块模式:

Function.prototype.inherits = function(parent) {
  this.prototype = Object.create(parent.prototype);
};

var Person = (function PersonClass() {

  function Person(props) {
    this.name = props.name || 'unnamed';
    this.age = props.age || 0;
  }

  Person.prototype = {
    say: function() {
      return 'My name is '+ this.name +'. I am '+ this.age +' years old.';
    }
  };

  return Person;

}());

var Student = (function StudentClass(_super) {

  Student.inherits(_super);      

  function Student(props) {
    _super.apply(this, arguments);
    this.grade = props.grade || 'untested';
  }

  Student.prototype.say = function() {
    return 'My grade is '+ this.grade +'.'; 
  };

  return Student;

}(Person));

var john = new Student({
  name: 'John',
  age: 25,
  grade: 'A+'
});

console.log(JSON.stringify(john)); //=> {"name":"John","age":25,"grade":"A+"}
console.log(john.say()); //=> "My grade is A+"

关于私有变量“问题”,只需遵守实例属性的约定,并在需要其他所有私有内容时使用闭包。

于 2013-03-05T07:03:41.223 回答
0

一个基本的例子如下:

Foo = function(id)
{
    // private instances.
    var _id;
    var _self = this;

    // constructor
    _id = id;

    // private method
    function _get()
    {
        return _id;
    };

    // public function
    _self.set = function(id)
    {
        _id = id;
    };
    _self.get = function()
    {
        return _get();
    };
};

var bar = Foo(100);
console.log( bar.get() );
bar.set(1000);
console.log( bar.get() );

我建议你使用原型

于 2013-03-05T07:28:24.560 回答
0

长话短说:不,不是。您不能使用可以访问private变量的方法来扩展原型。至少如果这些私有变量通过closure.

虽然,在 javascript 中使用下划线标记私有字段是一种惯例,例如_myPrivateField. 这些仍然是公开的,但我已经看到这个解决方案在许多图书馆中使用,我也更喜欢这种风格来满足你的第一条规则。

于 2013-03-05T06:51:38.497 回答
0
function Foo3() {
    this.private = {};
}

Foo3.prototype.set_x = function (x) {
    this.private.x = x;
};
于 2013-03-05T06:50:20.763 回答