什么是创建JavaScript类的最佳方式? [重复](What's the best

2019-08-02 06:03发布

可能重复:
在JavaScript中使用“原型”与“本”的?
在Javascript面向对象的问题

能否请您推荐以下哪个是最好的或者他们的优点和缺点?

方法1

function User() {

    this.name = "my name";
    this.save = function() {

    };
}

方法2

function User() {

    this.name = "my name";
}

User.prototype.save = function() {

}

Answer 1:

从Java和PHP背景的到来,我最初挣扎在JavaScript整个“类”的概念。 以下是考虑几件事情。

施工

首先,因为你很可能会被定义你的类作为..

Customer = function () {}
Customer.prototype = new Person();

你最终会运行到各种代码的噩梦,如果你正在施工中定义的属性和方法。 的原因是,内容片段,例如代码Customer.prototype = new Person(); 要求该人在客户构造真正的继承被称为..否则,你会最终不得不知道原来一个设置在任何时候。 看看下面的例子:

Person = function (name) {
    this.name = name;
    this.getName = function () {return this.name}
}
Customer = function (name) {
    this.name = name;
}
Customer.prototype = new Person();

现在,我们要更新的人也设置无论是“新”:

Person = function (name, isNew) {
    this.name = name;
    this.isNew = isNew;
    this.getName = function () {return (this.isNew ? "New " : "") + this.name; }
}

现在,在任何“类”是从人继承,则必须更新构造遵循形式。 你可以做这样的事情得到解决的是:

Customer = function () {
    Person.apply(this, arguments);
}

这将调用新的“客户”的范围“人”,让你不必知道的人建设。

速度

看看这些基准测试: http://jsperf.com/inherited-vs-assigned 。
基本上,我试图在这里证明的是,如果你是集体创建这些对象,最好的途径是在原型创建它们。 他们创造这样的:

Person = function (name) {
    this.name = name;
    this.getName = function () {return this.name}
}

是很慢的,因为每一个对象的创建,它创建了一个新的功能 -它不是简单地查找原型链中已经存在的一个。 相反,如果你有这些方法都极为称为经常在只有几个对象,定义它们与本地通过查找原型链失去了速度帮助。

共享属性

这总是让我。 比方说,你已经得到的东西像下面这样:

Person = function () {
    this.jobs = {};
    this.setJob = function (jobTitle, active) {this.jobs[jobTitle] = active; }
}

Employee = function () {}
Employee.prototype = new Person();

var bob = new Employee();
bob.setJob('janitor', true);

var jane = new Employee();
console.log(jane.jobs);

你猜怎么着? 珍是个看门的! 可不是闹着玩的! 这里的原因。 既然你没有定义this.jobs作为对员工的实例化一个新的对象,它现在只是查找原型链,直到找到“工作”和按原样使用它。 有趣吧?

所以,如果你想跟踪的实例,这是有用的,但在大多数情况下,你会发现它非常令人沮丧。 您可以通过执行以下绕开这个问题:

Employee = function () { Person.apply(this); }

这迫使“人”来创建一个新的“this.jobs”。

私有变量

由于没有任何东西在JavaScript是真正的“私人”,就可以得到私有变量的唯一方法就是在构造函数来创建它们,然后作出任何依赖它们初始化在构造函数中。

Person = function () {
    var jobs = {};
    this.setJob = function (jobTitle, active) {jobs[jobTitle] = active; }
    this.getJob = function (jobTitle) { return jobs[jobTitle]; }
}

然而,这也意味着你必须调用构造函数继承的类的实例每次。


建议

http://ejohn.org/blog/simple-javascript-inheritance/

这是一个超级基本类设置。 这很简单。 有用。 它会做你需要做的90%的时间,而不必处理所有疯狂的JavaScript所提供的:)

</rant>



Answer 2:

最好是一个非常主观的术语。

方法1给出了真正的私有变量的可能性。 例如:

function User() {
   var name = "fred";
   this.getName = function () { return name;};
}

方法2将使用较少的内存,作为一个单一的保存功能由所有用户对象共享。

“最佳”将您的具体要求来确定。



Answer 3:

JavaScript是一种“基于对象”的语言,而不是“基于类的”语言。 共享行为,这是类的概念,通过连接原型实现。

方法1不创建一个类。 每次你调用它的时候,你创建的定义和它们不与其他“实例”共享的属性和功能。 如果更换this.save那么只有一个实例将有行为改变。

方法2个实现共享行为。 因此,这是什么人用类和实例相关联。 如果更换this.save枝条不同的功能,那么所有衍生的实例会立即有新的行为。

如果“最佳”是指不消耗内存的功能,重新定义和分享共同的行为(这是基于编程往往等同于什么类)的方法2是要走的路。



Answer 4:

正如其他人所说,有两个主要的不同:

  • 方法1将创建一个新的功能,用于用户的每个实例
  • 方法1将能够访问在构造函数的范围局部变量

下面就来证明这些的例子:

function User() {

    var name = "my name";

    this.foo = function() {
        // one function per User instance
        // can access 'name' variable
    };
}

User.prototype.bar = function() {
    // one function shared by all User instances
    // cannot access 'name' variable
};

var a = new User();
var b = new User();

console.log(a.foo === b.foo); // false; each instance has its own foo()
console.log(a.bar === b.bar); // true; both instances use the same bar()


文章来源: What's the best way to create JavaScript classes? [duplicate]