以下两个 Javascript 原型之间的功能差异是什么,选择其中一个有什么好处?
选项1:
Person.prototype.sayName = function(name) {
alert(name);
}
选项 2:
Person.prototype = {
sayName: function(name) {
alert(name);
}
}
我是否正确地假设选项 2 会导致某些隐式绑定到原型的函数被破坏?
以下两个 Javascript 原型之间的功能差异是什么,选择其中一个有什么好处?
选项1:
Person.prototype.sayName = function(name) {
alert(name);
}
选项 2:
Person.prototype = {
sayName: function(name) {
alert(name);
}
}
我是否正确地假设选项 2 会导致某些隐式绑定到原型的函数被破坏?
我是否正确地假设选项 2 会导致某些隐式绑定到原型的函数被破坏?
对,就是这样。尽管唯一隐式绑定的属性是constructor
您很少需要的属性。
有哪些功能差异?
选项 1 只是扩展现有的原型。如果已经有Person
从原型对象继承的实例,它们也将能够使用该sayName
方法。使用选项 2,新原型将仅用于覆盖后实例化的对象。
选择一个而不是另一个有什么好处吗?
这些现在应该是不言自明的。选项 1(扩展)被认为更简洁,如果您要修改外部/未知/本地原型,则必须使用选项 1(扩展)。尽量避免选项 2。
如果您仍然更喜欢对象字面量语法,则应该考虑使用Object.assign
扩展现有原型:
Object.assign(Person.prototype, {
sayName: function(name) {
alert(name);
}
});
您可能需要填充工具Object.assign
预ES6环境。或者,$.extend
也可以_.extend
正常工作。当然,您最喜欢的库也为此提供了一个辅助函数。
第二个将用对象覆盖 person.prototype。
方法一:
Object.toString=function(){
return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
return "Person to string";
}
Person.prototype.sayName=function(){}
console.log(Person.prototype.constructor.toString());// "Person to string"
方法二:
Object.toString=function(){
return "Object to string";
}
var Person = function(){
};
Person.toString=function(){
return "Person to string";
}
Person.prototype = {
sayName:function(){}
}
console.log(Person.prototype.constructor.toString());// "Object to string"
第一个适用于一两个额外的功能,但定义一个具有许多功能的全新原型将非常重复。另一方面,执行后者会破坏您提到的原型的所有现有定义。
在实践中,我使用了第一个在 Array 和 Math 等中定义了附加函数,有点像 Objective-C 中的类别。后者我用作“类定义”。
构造函数的任何现有实例将继续指向旧的原型对象。创建的任何新实例都将指向新的原型对象。
选项 1 相对于选项 2 的优点只是您不必重新建立构造函数属性,并且可以节省一个缩进级别,这对我来说非常重要。
为了节省重复,我只是将属性分配给一个局部变量:
var method = Person.prototype;
method.getAge = function() {
return this.age;
};
method.getName = function() {
return this.name;
};
同样常见的选择是fn
(jQuery),p
它们甚至比method
.
简而言之,区别在于Person.prototype.sayName
您所做的只是向prototype
. 只是添加新功能。
在第二个中Person.prototype = {}
,您正在创建一个新的整个对象并将其分配给prototype
. 所以你创建新对象或用新对象覆盖prototype
。
第一种方法是好,你要添加许多功能上的需求。您可以按时添加它们,因此我认为当您的程序简单并且您的应用程序对象之间没有共享太多功能或对象时,这很好。
如果您的应用程序对象在它们之间共享一些对象(或@isaach 中所说的一组函数Math functions
),则第二种方法很好。