使用 JavaScript 中的实例更新原型
Updating a prototype using an instance in JavaScript
我有这个构造函数Person
:
function Person(name) {
this.name = name;
}
我在其原型上添加了一个数组 favorites
以便 Person
的所有实例都可以指向同一个数组:
Person.prototype.favorites = [];
var person1 = new Person("KimK");
var person2 = new Person("KhloeK");
person1.favorites = ["coke"];
person2.favorites = ["pepsi"];
console.log(person1.favorites); //["coke"]
console.log(person2.favorites); //["pepsi"]
我希望两个日志语句都打印 ["pepsi"]
,因为 person1
和 person2
都指向原型上的同一个基本数组 favorites
,并且 person2
最后修改为 ["pepsi"]
,我预计两个输出都是 ["pepsi"]
。我错过了什么吗?
当您将 ["coke"]
分配给 person1.favorites
时,您修改的是 person1
的 属性,而不是 Person
原型。您可以通过 console.log(Person.prototype.favorites)
轻松检查它——它仍然包含空数组。如果要更改所有实例的值,唯一的方法是直接修改原型,即:
Person.prototype.favorites = ["coke"];
但是,如果您没有设置favorites
属性到Person
个实例,您可以通过修改person1.favorites
来修改原型。例如:
function Person(name) {
this.name = name;
}
Person.prototype.favorites = [];
var person1 = new Person("KimK");
person1.favorites.push("coke", "pepsi")
console.log(person1.favorites); // ["coke", "pepsi"]
var person2 = new Person("KhloeK");
console.log(person2.favorites); // ["coke", "pepsi"]
console.log(Person.prototype.favorites); // ["coke", "pepsi"]
这会为 person1 的收藏夹分配一个新数组 属性。它不会修改其原型上现有的:
person1.favorites = ["coke"];
您可以使用 push 附加到数组,也可以通过将其长度设置为 0 来清空数组。例如:
person1.favorites.push( 'coke' );
person2.favorites.length = 0;
person2.favorites.push( 'coke' );
读取对象属性可能涉及搜索继承链。
读取 javascript 对象 属性 首先搜索对象的本地 属性 名称。如果没有找到本地或 "own" property,则通过依次查看继承链中的每个原型对象继续搜索,直到找到 属性 名称或检查了继承链中的所有对象。如果找到该名称,则从找到它的对象中获取其值。如果找不到读取 returns undefined
作为命名的 属性 值。
写入对象属性总是*在本地写入 属性 值
写入命名值 属性 的值会创建或更新被写入对象持有的本地 属性 值。如果它之前是通过继承链继承的,它将停止被继承:优先读取 returns 本地值。请注意,继承它的对象的继承 属性 值保持不变。
所以
person1.favorites = ["coke"];
person2.favorites = ["pepsi"];
在写入 ["coke"]
之前创建一个 person1
的新本地 favorites
属性,以及一个新的本地 favorites
属性 person2
写入 ["pepsi"]
之前。
从 Person.prototype
、[] 继承的先前 favorites
属性 值在进程中被隐藏。
*排除在 ES5 中定义的 Getters 和 Setters
Setter and getter 函数将 属性 名称与对象相关联。 属性 以这种方式设置的名称缺少内部 [[value]] 槽,但可以作为 getter 和 setter 函数继承。特别是写入对象确实会在继承链中搜索 setter,如果同名的本地 属性 尚不存在。
虽然 getters 和 setters 被调用的对象作为它们的 this
值被读取或写入,但它们存储和检索值的位置和方式无法概括,因为它取决于它们是如何写的。
我有这个构造函数Person
:
function Person(name) {
this.name = name;
}
我在其原型上添加了一个数组 favorites
以便 Person
的所有实例都可以指向同一个数组:
Person.prototype.favorites = [];
var person1 = new Person("KimK");
var person2 = new Person("KhloeK");
person1.favorites = ["coke"];
person2.favorites = ["pepsi"];
console.log(person1.favorites); //["coke"]
console.log(person2.favorites); //["pepsi"]
我希望两个日志语句都打印 ["pepsi"]
,因为 person1
和 person2
都指向原型上的同一个基本数组 favorites
,并且 person2
最后修改为 ["pepsi"]
,我预计两个输出都是 ["pepsi"]
。我错过了什么吗?
当您将 ["coke"]
分配给 person1.favorites
时,您修改的是 person1
的 属性,而不是 Person
原型。您可以通过 console.log(Person.prototype.favorites)
轻松检查它——它仍然包含空数组。如果要更改所有实例的值,唯一的方法是直接修改原型,即:
Person.prototype.favorites = ["coke"];
但是,如果您没有设置favorites
属性到Person
个实例,您可以通过修改person1.favorites
来修改原型。例如:
function Person(name) {
this.name = name;
}
Person.prototype.favorites = [];
var person1 = new Person("KimK");
person1.favorites.push("coke", "pepsi")
console.log(person1.favorites); // ["coke", "pepsi"]
var person2 = new Person("KhloeK");
console.log(person2.favorites); // ["coke", "pepsi"]
console.log(Person.prototype.favorites); // ["coke", "pepsi"]
这会为 person1 的收藏夹分配一个新数组 属性。它不会修改其原型上现有的:
person1.favorites = ["coke"];
您可以使用 push 附加到数组,也可以通过将其长度设置为 0 来清空数组。例如:
person1.favorites.push( 'coke' );
person2.favorites.length = 0;
person2.favorites.push( 'coke' );
读取对象属性可能涉及搜索继承链。
读取 javascript 对象 属性 首先搜索对象的本地 属性 名称。如果没有找到本地或 "own" property,则通过依次查看继承链中的每个原型对象继续搜索,直到找到 属性 名称或检查了继承链中的所有对象。如果找到该名称,则从找到它的对象中获取其值。如果找不到读取 returns undefined
作为命名的 属性 值。
写入对象属性总是*在本地写入 属性 值
写入命名值 属性 的值会创建或更新被写入对象持有的本地 属性 值。如果它之前是通过继承链继承的,它将停止被继承:优先读取 returns 本地值。请注意,继承它的对象的继承 属性 值保持不变。
所以
person1.favorites = ["coke"];
person2.favorites = ["pepsi"];
在写入 ["coke"]
之前创建一个 person1
的新本地 favorites
属性,以及一个新的本地 favorites
属性 person2
写入 ["pepsi"]
之前。
从 Person.prototype
、[] 继承的先前 favorites
属性 值在进程中被隐藏。
*排除在 ES5 中定义的 Getters 和 Setters
Setter and getter 函数将 属性 名称与对象相关联。 属性 以这种方式设置的名称缺少内部 [[value]] 槽,但可以作为 getter 和 setter 函数继承。特别是写入对象确实会在继承链中搜索 setter,如果同名的本地 属性 尚不存在。
虽然 getters 和 setters 被调用的对象作为它们的 this
值被读取或写入,但它们存储和检索值的位置和方式无法概括,因为它取决于它们是如何写的。