我看到人们按照以下编码方式进行了很多次,但是由于我通常不这样做而且没有它我可以正常工作,我只是好奇它是否重要。
注意:我将我所说的话标记为// this line
function Test(name, something){
this.name = name;
this.something = something
}
Test.prototype.name = ''; // this line
Test.prototype.something = ''; // this line
Test.prototype.getName = function(){
return this.name;
}
答案 0 :(得分:8)
这里有一个重要的区别。要查看差异而不是字符串原语,请使用对象:
Test.prototype.arr = [];
这将在arr
原型上创建Test
属性。 因此,Test
的所有实例都将共享完全相同的arr
值。为了演示,请考虑以下事项:
function Test(){}
Test.prototype.arr = [];
var t1 = new Test();
t1.arr.push("hello")
console.log(t1.arr); // ["hello"]
var t2 = new Test();
t2.arr.push("world")
console.log(t1.arr); // ["hello", "world"]
console.log(t2.arr); // ["hello", "world"]
看看那里发生了什么?以下几行
t1.arr.push("hello");
t2.arr.push("world");
更改prototype
本身的值。因此,Test
,过去和将来的所有实例现在都有arr
属性包含两个字符串。
也许以上就是你原本想要的;但是,在大多数情况下,您要做的实际上是在实例上设置属性,而不是prototype
:
function Test() {
this.arr = [];
}
var t1 = new Test();
t1.arr.push("hello");
console.log(t1.arr); // ["hello"]
var t2 = new Test();
t2.arr.push("world");
console.log(t1.arr); // ["hello"],
console.log(t2.arr); // ["world"];
至于你提供的例子,它可能被证明是有点多余的,也许没有必要首先在原型上拥有属性,然后在创建实例后,实例属性。
请注意,当JavaScript运行时执行属性查找时,首先检查对象本身,如果它没有属性(由hasOwnProperty
检查),则检查其原型;失败了,原型的原型,直到找到匹配或到达原型链的末尾(并返回null
值)。
考虑一下:
function Test() {}
Test.prototype.name = "";
var t = new Test()
t.hasOwnProperty("name"); // false
name
只是原型的属性,因此hasOwnProperty("name")
将为false
,而在以下情况中:
function Test(name) {
this.name = name
}
Test.prototype.name = "";
var t = new Test();
t.hasOwnProperty("name"); // true
创建t
会导致在实例本身上创建不同的name
属性,因此hasOwnProperty("name")
现在为true
。
答案 1 :(得分:3)
他们可能只想表明该类的实例将具有这些属性。由于我们知道原型上的属性是由所有实例共享的,因此只需查看原型,我们就知道实例将具有哪些属性。一切都在“一个地方” 这可能不是从构造函数中显而易见的,这可能是更复杂的条件和什么不是。
此外,某些类型的检查程序或文档生成工具(如Google Closure Compiler)可能需要在原型上定义任何实例属性。
我只是好奇它是否重要
关于运行时行为,没有。在构造函数中分配给实例的属性无论如何都会影响原型属性。