设置原型's对象's字段更改所有实例

Setting prototype's object's field changes all instances

本文关键字:实例 对象 原型 设置 字段      更新时间:2023-09-26

JSFiddle

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
Person.prototype = {
    nationality : {
        type : ""
    },
    changeNationality:function(n){
        this.nationality.type = n;
    }
};
var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Jane", "Doe", 50, "blue");
myMother.changeNationality("English");
myFather.changeNationality("German");
document.getElementById("demo").innerHTML =
"My father is " + myFather.nationality.type + "<br/> My mother is " + myMother.nationality.type;

当我改变父亲的国籍时,也会改变母亲的国籍。原因是什么?

因为您在prototype级别定义nationality,而不是Person实例,所以这就是prototype的原因!这个想法是在所有类实例之间共享,否则每个实例都会对每个方法有自己的定义,使用更多的内存和潜在的发散行为。

尝试将nationality移动到构造函数:

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
    this.nationality = { type: "" };
}

由于原型与对象定义的每个实例共享,因此应该执行以下操作:

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
    this.nationality = {
        type : ""
    };
}
Person.prototype = {
    
    changeNationality:function(n){
        this.nationality.type = n;
    }
};
var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Jane", "Doe", 50, "blue");
myMother.changeNationality("English");
myFather.changeNationality("German");
document.getElementById("demo").innerHTML =
"My father is " + myFather.nationality.type + "<br/> My mother is " + myMother.nationality.type;
<p id="demo"></p>

为了防止这种情况,请使用之一将属性分配给原型级别点和字符串分配

function Person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
    this.changeNationality = function(n){
        this.nationalityType = n
    }
}
Person.prototype.nationalityType = 'default';
var myFather = new Person("John", "Doe", 50, "blue");
var myMother = new Person("Jane", "Doe", 50, "blue");
myMother.changeNationality("English");
myFather.changeNationality("German");
document.getElementById("demo").innerHTML =
"My father is " + myFather.nationalityType + "<br/> My mother is " + myMother.nationalityType;
<p id="demo"></p>

更改

changeNationality:function(n){
        this.nationality.type = n;
    }

changeNationality:function(n){
        this.nationality = {type : n};
    }

也应该工作,因为设置属性将在对象上创建一个新的属性。但在this.nationality.type = n; 的情况下

this.nationality是一个正在执行的类型,因此它将从它获得的位置(即从原型(分配值。因此,你得到了这种行为。我已经更新了小提琴,你可以在这里查看