为什么有些人定义了javascript对象的原型属性值

cg.*_*ike 5 javascript

我已经看到人们做了很多次编码的方式,但是我通常不这样做,没有它我就可以正常工作,我只是好奇它是否重要. 注意:我标记了我所说的线条// 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;
}
Run Code Online (Sandbox Code Playgroud)

kri*_*isk 8

这里有一个重要的区别.要查看差异,请使用对象:而不是字符串原语:

Test.prototype.arr = [];
Run Code Online (Sandbox Code Playgroud)

这将arrTest原型上创建一个属性. 因此,所有实例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"]
Run Code Online (Sandbox Code Playgroud)

看看那里发生了什么?以下几行

t1.arr.push("hello");
t2.arr.push("world");
Run Code Online (Sandbox Code Playgroud)

改变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"];
Run Code Online (Sandbox Code Playgroud)

至于你提供的例子,它可能被证明有点多余,并且可能没有必要首先在原型上拥有属性,然后在创建实例时,实例属性.

请注意,当JavaScript运行时执行属性查找时,首先检查对象本身,如果它没有属性(选中hasOwnProperty),则检查其原型; 失败,原型的原型,直到找到匹配或达到原型链的末尾(并null返回一个值).

考虑一下:

function Test() {}
Test.prototype.name = "";

var t = new Test()
t.hasOwnProperty("name"); // false
Run Code Online (Sandbox Code Playgroud)

name仅是原型的属性,因此hasOwnProperty("name")将是false,虽然在下面的情况:

function Test(name) {
    this.name = name
}
Test.prototype.name = "";

var t = new Test();
t.hasOwnProperty("name"); // true
Run Code Online (Sandbox Code Playgroud)

创建t导致name在实例本身上创建不同的属性,hasOwnProperty("name")现在就是这样true.

  • 看起来您回答了"相反"的问题,为什么/何时要在构造函数中指定值. (3认同)

Fel*_*ing 3

他们可能只是想表明该类的实例将具有这些属性。由于我们知道原型上的属性是由所有实例共享的,因此只需查看原型,我们就知道实例将具有哪些属性。一切都在“一处”。
从构造函数来看,这一点可能不那么明显,哪些条件和哪些条件不条件可能要复杂得多。

此外,某些类型检查器或文档生成工具(例如 Google Closure Compiler)可能需要在原型上定义任何实例属性。

我只是好奇这是否重要

关于运行时行为,没有。无论如何,在构造函数中分配给实例的属性都会隐藏原型属性。