0

我有一个没有公共方法的 js 类。我在构造函数中使用 var 来创建这些方法并使用 methodName() 调用它们。我应该改用 class.prototype.methodName 并使用 this.methodName() 在类中调用它们吗?两种方法的优点是什么?我知道原型方法会被复制到新实例中,因此速度更快。但是它们应该只用于类的 API 吗?

4

1 回答 1

1

JavaScript 没有私有变量,因此使用模拟它们的模式会导致一些开销(运行代码需要更多的 CPU 和内存)。带有私有的代码可能更难维护。

模拟私有成员的模式可以分为两种不同的类型:

  1. 实例特定成员
  2. 原型成员

特定实例可能是一个人的宗教,原型成员可能是 doSomethingDangerous 函数。在宗教返回值之前,您可能需要检查请求对象是否有权访问此私人信息。不应直接调用函数 doSomethingDangerous,因为您无法确定从外部 Person 调用时在执行此操作之前是否已采取正确的预防措施。

可以访问“私有”成员的方法是特权方法。如果他们需要访问特定于实例的成员,则需要位于构造函数主体中(即声明特定于实例的成员的位置)。如果他们需要访问特定于原型的成员,他们需要与声明“私有”的地方位于同一个主体中。

这是一个例子:

//constructor for Person
var Person = function(){//<=start body of constructor function
  //to properly use prototype and not cause your code to consume
  // more resources to simulate something that isn't supported
  // in JavaScript "private" variable names usually start with _
  // so other programmers know not to set, get or call this directly
  this._normalPrivate;
  var religion = undefined;//<=instance specific private
  this.religion = function(){//<=privileged function
    console.log(religion);//<=can access private instance here
  }
};
Person.prototype=(function(){//<=start body of function returning object for prototype
  //All person instances share this, it's not instance specific
  var doSomethingDangerous=function(){//<=private prototype
    // doing something dangerous, don't want this to be called directly               
  };
  return {
    doSomething:function(){//<=priviliged method, can access private prototype
      //we cannot access religion because it's defined in a different 
      //  function body
      //make sure we can do something dangerous
      doSomethingDangerous();
    }
  };
}());
Person.prototype.constructor=Person;
Person.prototype.anotherMethod=function(){
  //not a privileged method, cannot access doSomethingDangerous or religion
};

var ben = new Person();

我从不使用这种模式,因为 private 仅用于指示其他程序员不要直接访问这些成员。如以下示例所示,您不希望程序员(包括将来的您自己)执行以下操作:

ben._doSomethingDangerous();

为了向其他程序员(和未来的自己)表明 doSomethingDangerous 是私有的,您可以在它前面添加一个下划线:

Person.prototype._doSomethingDangerous=function(){...

更多关于原型、继承、混合在这里https://stackoverflow.com/a/16063711/1641941

于 2013-11-06T03:23:34.327 回答