我正在阅读 javascript 中的原型,在一篇文章http://phrogz.net/js/classes/OOPinJS.html我读到我们不能在 javascript 的对象构造函数中分配公共方法?原型方法与静态方法有何不同,使用它们有什么优势?
3 回答
我读到我们不能在 javascript 的对象构造函数中分配公共方法?
是的,文章指的是这个:
function MyObj(name)
{
this.name = name;
}
MyObj.prototype.sayHello = function() {
alert('hello ' + this.name);
}
new MyObj('world').sayHello();
如您所见,公共方法sayHello()
是在原型中声明的,这是在构造函数之外完成的。这就是 JavaScript 的工作原理。
原型方法与静态方法有何不同,使用它们有什么优势?
原型方法仅“附加”到对象。对于静态方法,您需要使用此构造:
var MyStaticThing = {
name: 'world',
sayHello: function() {
alert('hello ' + this.name);
}
}
MyStaticThing.sayHello();
JavaScript 不太适合大多数 OOP 概念和范例,尤其是当您尝试模拟继承时。与其在 OOP 术语中考虑原型与“特权”方法,不如从 JavaScript 如何实例化对象的角度来考虑。学习这个简单的“类”:
var id = 0;
function myClass()
{
var that = this;
id++; //closure, each new instance gets a unique id
this.id = id;
this.toString = function()
{
return that.id.toString();
}
}
这个类是这样实例化的:
var classInstance = new myClass();
这不是我必须推荐的模式,重点是说明对于每个实例化,每个实例都有自己独特的toString
function。这意味着如果您实例化 100 classInstances
,并且您更改toString
其中一个以执行其他操作,那么只有一个实例将具有该新功能。
这也意味着对于每个实例,每个特权方法也随之实例化。如果您要实例化大量实例,则可能会产生很大的性能差异。我有一个案例,通过将我的特权方法转换为原型方法,我看到了可衡量的速度提升。
说到原型方法,可能看起来像这样:
var id = 0;
function myClass()
{
id++; //closure, each new instance gets a unique id
this.id = id;
}
myClass.prototype.toString = function()
{
return this.id.toString();
}
在这种情况下,无论myClasses
您有多少,您只实例化该toString
方法一次。如果它改变,它会改变所有的myClasses
。
就个人而言,我在我的大多数 JavaScript 类中使用特权方法,因为它看起来更干净,并且只有在我知道它将被实例化很多次时才会打扰原型链。还能够访问私有变量使您可以隐藏一些信息,而不是被迫公开任何访问的变量。
“使用它们的优势”...您指的是哪一个?通常,优势将是使用原型方法(以及一般的对象构造),而不是 javascript 中的静态或经典方法。您正在寻找的答案真的太长了,无法在这里解决,但简短的答案是 javascript 基于原型对象继承系统(这意味着对象可以动态创建并且可以相互继承),而不是经典系统(对象只能从类继承,即 Java、C++ 等)
虽然您可以以经典方式在 javascript 中创建对象——因为该语言非常灵活——但这是一种糟糕且令人困惑的方式。原型对象构造允许您做重要且有益的事情,例如数据隐藏、访问超级方法等。就像我说的那样,这是一个冗长的主题,在一个小文本框中进行处理真的太大了。