在javascript中,是否有一种完美的方式来定义类



我正在寻找一个完美的方式来定义类。"perfect"在这里的意思是:

  1. create instances将不会创建方法的副本。
  2. 公共函数可以很容易地(不太麻烦)访问私有变量

例如,方式一:

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

将不符合上述规则1。

另一个例子,方式二:
 function Foo2() {
      var private2;
    }
 Foo2.prototype.Method2 = function() {//cannot access private2}

不符合上述规则2。

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

在JavaScript中更多的是关于约定。私有属性或方法首先用下划线定义,比如_private。使用一些帮助程序,您可以轻松地创建类。我发现这个设置很容易,所有你需要的是一个助手inherits来扩展类,而不是使用多个参数,你在一个对象props中传递,并简单地调用"超级"与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+"

关于私有变量"issue",只要遵守实例属性的约定,并在需要时使用闭包来处理其他私有变量

function Foo3() {
    this.private = {};
}
Foo3.prototype.set_x = function (x) {
    this.private.x = x;
};

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

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

下面是一个基本的例子:

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() );

我建议你使用原型

相关内容

最新更新