您能否推荐以下哪些是最好的或它们的优缺点?
方法一
function User() {
this.name = "my name";
this.save = function() {
};
}
方法二
function User() {
this.name = "my name";
}
User.prototype.save = function() {
}
您能否推荐以下哪些是最好的或它们的优缺点?
function User() {
this.name = "my name";
this.save = function() {
};
}
function User() {
this.name = "my name";
}
User.prototype.save = function() {
}
来自 Java 和 PHP 的背景,我最初对 JavaScript 中的整个“类”概念感到困惑。这里有几点需要考虑。
首先,因为您可能会将您的类定义为..
Customer = function () {}
Customer.prototype = new Person();
如果您在构造过程中定义属性和方法,您最终会遇到各种各样的代码噩梦。原因是像这样的一段代码Customer.prototype = new Person();
需要在 Customer 构造函数中调用 Person 以实现真正的继承。否则您最终将不得不始终知道原始设置的内容。举个例子:
Person = function (name) {
this.name = name;
this.getName = function () {return this.name}
}
Customer = function (name) {
this.name = name;
}
Customer.prototype = new Person();
现在我们将更新 Person 以设置它们是否是“新的”:
Person = function (name, isNew) {
this.name = name;
this.isNew = isNew;
this.getName = function () {return (this.isNew ? "New " : "") + this.name; }
}
现在在从 Person 继承的任何“类”上,您必须更新构造函数以遵循表单。您可以通过执行以下操作来解决此问题:
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实例化的新对象,因此它现在只是查找原型链,直到找到“工作”并按原样使用它。有趣,对吧?
因此,如果您想跟踪实例,这很有用,但在大多数情况下,您会发现它非常令人沮丧。您可以通过执行以下操作来解决此问题:
Employee = function () { Person.apply(this); }
这迫使“Person”创建一个新的“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 将使用更少的内存,因为所有 User 对象共享一个保存函数。
“最佳”将由您的具体要求决定。
JavaScript 是一种“基于对象”的语言,而不是“基于类”的语言。共享行为,即类概念,是通过链接原型来实现的。
方法 1 不创建类。每次调用它时,您都会按照定义创建属性和函数,并且它们不会与其他“实例”共享。如果您更换this.save
,那么只有一个实例会改变行为。
方法 2 实现共享行为。因此,它是人们与类和实例相关联的东西。如果您用this.save
不同的函数替换,那么所有派生实例将立即具有新行为。
如果“最佳”意味着不消耗内存重新定义函数和共享常见行为(这是基于类的编程倾向于等同的),那么方法 2 就是要走的路。
正如其他人所提到的,有两个主要区别:
这是一个演示这些的示例:
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()