通过实例对象能修改原型对象上的属性吗?

2023/9/14 prototype

一个经常会搞混的点,还是记录一下吧(虽然可能过几天又忘了...)

这里容易混淆的地方主要是两点

  1. 数据类型不同时,修改得到的结果也会有所不同
  2. 修改方式的不同,是整体修改这个属性,还是修改引用类型属性其中的内容

下面就根据这两点分别进行分析吧 👇

# 当原型对象上的属性为基本数据类型时

原型对象上设置了一个属性 name,它是基本数据类型,我们通过实例对象修改它试一下👇

// 构造函数

function SuperType(age) {
  this.age = age;
}

// 构造函数的原型对象
SuperType.prototype = {
  name: "super",
  color: ["red", "blue", "yellow"],
  printName: function () {
    console.log(this.name);
  },
};

// 创建实例对象
let obj__1 = new SuperType(16);
let obj__2 = new SuperType(18);

console.log("obj__1.name: ", obj__1.name); //super
console.log("obj__2.name: ", obj__2.name); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);
obj__1.name = "obj__1"; //修改属性

console.log("-------------------分割线---------------------");

console.log("obj__1.name: ", obj__1.name); //obj__1
console.log("obj__2.name: ", obj__2.name); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);

结果如下:

2

发现当原型对象上的属性为基本数据类型时,我们通过实例对象去修改这个属性,其实就是往这个实例对象上添加了该同名属性,然后给其赋值成我们修改的值,对原型对象是没有任何影响的

谁修改了就往谁身上添加,对其他的实例对象也是不会有影响的

# 当原型对象上的属性为引用数据类型时

# 直接修改该属性

原型对象上设置了一个属性 color,它是引用数据类型,我们通过实例对象修改它试一下👇

// 构造函数

function SuperType(age) {
  this.age = age;
}

// 构造函数的原型对象
SuperType.prototype = {
  name: "super",
  color: ["red", "blue", "yellow"],
  printName: function () {
    console.log(this.name);
  },
};

// 创建实例对象
let obj__1 = new SuperType(16);
let obj__2 = new SuperType(18);

console.log("obj__1.color: ", obj__1.color); //super
console.log("obj__2.color: ", obj__2.color); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);
obj__1.color = ["black", "white"]; //修改属性

console.log("-------------------分割线---------------------");

console.log("obj__1.name: ", obj__1.color); //obj__1
console.log("obj__2.name: ", obj__2.color); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);

结果如下:

2

发现直接修改引用数据类型,和基本数据类型的效果是一样的,这里就不再重复赘述了😄

# 修改引用数据类型的属性

这里就是重点了,我们通过修改引用数据类型的属性,比如我修改数组的第一项,或者删除对象的某个属性,会有什么结果呢?👇

// 构造函数

function SuperType(age) {
  this.age = age;
}

// 构造函数的原型对象
SuperType.prototype = {
  name: "super",
  color: ["red", "blue", "yellow"],
  printName: function () {
    console.log(this.name);
  },
};

// 创建实例对象
let obj__1 = new SuperType(16);
let obj__2 = new SuperType(18);

console.log("obj__1.color: ", obj__1.color); //super
console.log("obj__2.color: ", obj__2.color); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);
obj__1.color[1] = "black"; //修改属性

console.log("-------------------分割线---------------------");

console.log("obj__1.name: ", obj__1.color); //obj__1
console.log("obj__2.name: ", obj__2.color); //super
console.log("obj__1: ", obj__1);
console.log("obj__2: ", obj__2);

结果如下:

3

这里就是易混淆的地方了,当我们通过实例对象修改引用数据类型的属性时,原型对象上的属性是被修改成功了的因为我们在破坏原数据,其他的会修改原数组的方法(push, sort, splice)也是会修改原型对象上的引用类型数据的属性的

😄希望下次面试问到的时候可以顺利回答出来吧~

How to love
Lil Wayne