可能重复:
在JavaScript中使用“原型”与“本”的?
在Javascript面向对象的问题
能否请您推荐以下哪个是最好的或者他们的优点和缺点?
方法1
function User() {
this.name = "my name";
this.save = function() {
};
}
方法2
function User() {
this.name = "my name";
}
User.prototype.save = function() {
}
从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>
最好是一个非常主观的术语。
方法1给出了真正的私有变量的可能性。 例如:
function User() {
var name = "fred";
this.getName = function () { return name;};
}
方法2将使用较少的内存,作为一个单一的保存功能由所有用户对象共享。
“最佳”将您的具体要求来确定。
JavaScript是一种“基于对象”的语言,而不是“基于类的”语言。 共享行为,这是类的概念,通过连接原型实现。
方法1不创建一个类。 每次你调用它的时候,你创建的定义和它们不与其他“实例”共享的属性和功能。 如果更换this.save
那么只有一个实例将有行为改变。
方法2个实现共享行为。 因此,这是什么人用类和实例相关联。 如果更换this.save
枝条不同的功能,那么所有衍生的实例会立即有新的行为。
如果“最佳”是指不消耗内存的功能,重新定义和分享共同的行为(这是基于编程往往等同于什么类)的方法2是要走的路。
正如其他人所说,有两个主要的不同:
- 方法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()