我正在学习javascript。
为什么在对象之外定义函数?
function Man(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Man.prototype.getName = function () {
return this.firstName + this.lastName;
};
对我来说有点奇怪。它可以工作,如果我在类中添加函数(删除.protoype等)但我被告知定义该函数outisde对象。
为什么?
答案 0 :(得分:8)
对我来说有点奇怪。
这就是如何设置由构造函数分配的原型。你并不是唯一一个发现它很尴尬的人,见下文。 :-) (更新:,请参阅下文,了解ES6如何让这一切变得如此简单。)
如果我在类中添加函数(删除.protoype等),它会起作用,但我被告知要定义函数outisde对象。
如果你这样做:
function Man(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.getName = function () {
return this.firstName + this.lastName;
};
}
...然后每个Man
对象获得该函数的自己的副本。它们不共享,最终为每个Man
对象提供了一个新的函数对象。 (智能引擎可以重用底层函数代码,但将成为两个函数对象。)原型的目的是创建可由构造的对象共享的特性由构造函数。
关于原型的另一个好处是对象与原型的连接正在进行中,这意味着您可以通过添加到原型来向已存在的对象添加功能。例如:
function Man(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Man.prototype.getName = function () {
return this.firstName + " " + this.lastName;
};
var joe = new Man("Joe", "Bloggs");
console.log(joe.getName()); // "Joe Bloggs"
Man.prototype.introduction = function() {
return "Hi there, I'm " + this.getName();
};
console.log(joe.introduction()); // "Hi there, I'm Joe Bloggs"
请注意我们在创建 introduction
后如何将joe
添加到原型中。没关系,查找是动态的。执行joe.introduction
后,引擎会在introduction
上查找joe
属性,如果找不到,则查看原型。因此,稍后(间接)添加到原型会增强现有对象。
你不是唯一一个发现语法笨拙的人。您经常看到人们创建“extend
”方法,如jQuery,Underscore,Prototype等中的方法。 extend方法只是将源对象的属性分配给目标对象。它的简单形式是:
function extend(target, source) {
var name;
for (name in source) {
target[name] = source[name];
}
}
...虽然通常会看到具有更多功能的内容(多个源对象,返回目的地等)。
然后你可以像这样使用它:
function Man(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
extend(Man.prototype, {
getName: function () {
return this.firstName + this.lastName;
},
introduction: function() {
return "Hi there, I'm " + this.getName();
}
});
使用对象初始化器语法(有时称为“对象文字”),将其传递到extend
,extend
将属性放在Man.prototype
上。
你还会看到像my Lineage
script这样的东西,它们可以进一步简化语法,并且可以更简单地处理其他一些事情(比如调用父原型的函数版本)。
从ES6开始,它几乎已经完成并且正在进入浏览器(你也可以转换),这会变得更加简单:
class Man {
constructor(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
getName() {
return this.firstName + " " + this.lastName;
}
introduction() {
return "Hi there, I'm " + this.getName();
}
}
var joe = new Man("Joe", "Bloggs");
console.log(joe.getName()); // "Joe Bloggs"
console.log(joe.introduction()); // "Hi there, I'm Joe Bloggs"
答案 1 :(得分:1)
你可以定义对象内部的函数,但并不总是可以(内置对象,第三方库等)。
据推测,本书/教师/老师希望您使用原型,因为他们希望您学习如何使用该方法扩展对象。