创建JavaScript类的最佳方法是什么? [英] What's the best way to create JavaScript classes?

查看:96
本文介绍了创建JavaScript类的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
在Javascript中使用"prototype"还是"this"?
Javascript中的面向对象的问题

Possible Duplicate:
Use of ‘prototype’ vs. ‘this’ in Javascript?
Object Oriented questions in Javascript

您能推荐以下哪一项是最好的还是它们的优缺点?

Can you please recommend which of the following is the best or their pros and cons?

function User() {

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

    };
}

方法2

function User() {

    this.name = "my name";
}

User.prototype.save = function() {

}

推荐答案

出于Java和PHP的背景,我最初在JavaScript中尝试了整个类"概念.这是一些要考虑的事情.

Coming from a background in Java and PHP, I had initially struggled with the whole 'class' concept in JavaScript. Here are a few things to think about.

首先,由于您可能会将类定义为..

First, since you're likely going to be defining your classes as..

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

如果在构造过程中定义属性和方法,最终将陷入各种各样的代码梦running.原因是像Customer.prototype = new Person();这样的一段代码要求在Customer构造函数中调用Person以获得真正的继承.否则,您将不得不始终知道原始代码所设置的内容.请看以下示例:

You will end up running into all sorts of nightmares of code if you are defining properties and methods during construction. The reason being is that a piece of code like Customer.prototype = new Person(); requires that the Person be called in the Customer constructor for true inheritance.. otherwise you'll end up having to know what the original one sets at all times. Take the following example:

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

现在,我们将更新Person来设置它们是否为新":

Now we're going to update Person to also set whether they are 'new':

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

现在在从Person继承的任何类"上,您必须将构造函数更新为遵循形式.您可以通过执行以下操作来解决此问题:

Now on any 'class' that is inheriting from the Person, you must update the constructor to follow form. You can get around that by doing something like:

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

在新的客户"范围内,这将称为"Person",从而使您不必了解Person的构造.

That will call 'Person' in the scope of the new 'Customer', allowing you to not have to know about the Person construction.

看看这些基准: http://jsperf.com/inherited-vs-assigned .
基本上,我想在此证明的是,如果要批量创建这些对象,最好的方法是在原型上创建它们.像这样创建它们:

Take a look at these benchmarks: http://jsperf.com/inherited-vs-assigned.
Basically, what I am attempting to prove here is that if you're creating these objects en masse, your best route is to create them on the prototype. Creating them like:

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

非常慢,因为对于每个对象创建,它都会创建一个 new函数-它不只是查找已经存在的原型链.相反,如果只有很少的几个对象经常调用这些方法,则在本地定义它们有助于通过查找原型链来降低速度.

is very slow, because for every object creation, it creates a new function - it doesn't simply look up the prototype chain for the already existing one. Conversely, if you've got only a few objects that the methods are called extremely frequently on, defining them locally helps with the speed lost by looking up the prototype chain.

这总是让我受益.假设您有类似以下内容的东西:

This always gets me. Let's say you've got something like the following:

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 实例化时的新对象,因此它只是查找原型链,直到找到'jobs'并按原样使用它.好玩吧?

Guess what? Jane's a janitor! No joke! Here's why. Since you didn't define this.jobs as being a new object on instantiation of the Employee, it's now just looking up the prototype chain until it finds 'jobs' and is using it as is. Fun, right?

因此,如果您想跟踪实例,这很有用,但是在大多数情况下,您会发现它令人沮丧.您可以通过执行以下操作解决此问题:

So, this is useful if you want to keep track of instances, but for the most part you're going to find it incredibly frustrating. You can get around that by doing the following:

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

这将迫使人员"创建一个新的"this.jobs".

This forces 'Person' to create a new 'this.jobs'.

由于JavaScript中没有真正私有"的东西,因此获取私有变量的唯一方法是在构造函数中创建它们,然后在构造函数中进行任何依赖于它们的初始化.

Since there's nothing that's really "private" in JavaScript, the only way you can get private variables is to create them in the constructor, and then make anything that relies on them initialize in the constructor.

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

但是,这也意味着您必须在继承的类的每个实例上都调用该构造函数.

However, this also means that you must call that constructor on every instantiation of an inherited class.

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

这是一个超级基本的类设置.这简单.有用.而且它将在90%的时间内完成您所需的工作,而不必处理JavaScript必须提供的所有疯狂功能:)

This is a super basic class setup. It's easy. It works. And it'll do what you need it to do 90% of the time without having to deal with all the insanity JavaScript has to offer :)

</rant>

这篇关于创建JavaScript类的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆