在Javascript原型继承中,数组和数字数据类型之间有区别吗

Is there a difference between array and number datatype in Javascript prototypal inheritance?

本文关键字:数据类型 数字 之间 有区别 数组 原型 Javascript 继承      更新时间:2023-09-26

我是javascript原型继承方面的书呆子。我可以理解下面代码中发生的事情

function Hamster() {  }
Hamster.prototype = {
  food: [],
  found: function(something) {
    this.food.push(something)
  }
}
// Create two speedy and lazy hamsters, then feed the first one
speedy = new Hamster()
lazy = new Hamster()
speedy.found("apple")
speedy.found("orange")
alert(speedy.food.length) // 2

下面的行也警告2 b'coz两个对象都共享来自Hamster的原型的food阵列

alert(lazy.food.length) // 2

但如果我将数组的数据类型更改为数字,则food密钥不会在两个实例之间共享

function Hamster() {  }
Hamster.prototype = {
  food: 0,
  found: function(something) {
    this.food = something
  }
}
// Create two speedy and lazy hamsters, then feed the first one
speedy = new Hamster()
lazy = new Hamster()
speedy.found(123)

alert(speedy.food) // 123

但是下面的行提醒0,你能告诉我为什么这没有提醒123

alert(lazy.food) // 0

Hamster的每个实例都有自己的food属性。但在第一个版本中,它们都指向同一个数组,您正在使用push对其进行修改。在第二个版本中,它们指向整数,这些整数不能就地修改;found函数重新分配该实例的属性,该属性对其他实例没有影响。

为了给每个实例提供自己的food数组属性,您需要使用一个分配它的构造函数

您可以在下面的中看到类似的行为,它只是使用普通变量,而不是对象和继承。

arr1 = [];
arr2 = arr1;
arr1.push(1);
console.log(arr2); // prints [1]
int1 = 0;
int2 = int1;
int1 = 1;
console.log(int2); // prints 0

赋值运算符"="会从变量中删除指针

arr1 = [];
arr2 = arr1;
arr2 = ['Appple'];
console.log(arr1); // prints []

在JavaScript中,属性查找遵循原型链,但不遵循属性分配。

所以,当你说

this.food = something;

在对象上创建food属性。因此,它从prototype覆盖food。但是,当您访问lazy时,由于它是属性查找,因此首先搜索当前对象,然后搜索原型,在原型中定义并分配值0。这就是它向0发出警报的原因。

需要理解的是,在第一种情况下,两个对象对于food仍然有自己的值;只是在每种情况下,它们的值都是对内存中同一对象的引用,所以将一个项推入该属性引用的数组会更改同一数组。

@Barmar的回答,我投了赞成票,已经说明了所有这些,但这里有另一个例子应该有助于证明这一点:

function Hamster() {}
Hamster.prototype = {
    food: [],
    found: function(something) {
        this.food = something;
    }
}
// Create two speedy and lazy hamsters, then feed the first one
speedy = new Hamster()
lazy = new Hamster()
speedy.found(["apple"])
speedy.found(["orange"])
alert(speedy.food) // orange
alert(lazy.food) // <empty>

在这种情况下,每个food属性都会引用一个不同的数组,因此很明显,每个属性都是独立的。

要拿走的关键东西:

持有对象的变量的值是对该对象的引用。保存基元(如数字)的变量的值是基元本身的值。