目录

prototype和proto的区别

prototype和proto的区别

在 JavaScript 中,prototype__proto__ 都与原型链和继承机制有关,但它们的含义和作用是不同的。下面来详细讲解它们的区别。


一、prototype 和proto** 的区别**

特性prototype__proto__
作用构造函数的原型对象实例对象的隐式原型
类型对象对象
访问方式构造函数.prototype实例对象.proto
作用场景为构造函数定义方法和属性用于实例对象访问原型链
修改影响修改后影响所有实例修改后仅影响该实例及其后代

二、prototype 和proto** 的详细解析**

1 prototype 的作用

  • 每个构造函数 都有一个名为 prototype 的属性,它指向一个对象
  • 这个对象是用来共享方法和属性 的。
  • 当通过构造函数创建对象时,实例会继承 prototype 上的方法和属性示例: // 构造函数 function Person(name) { this.name = name; } // 给构造函数的 prototype 添加方法 Person.prototype.sayHello = function() { console.log(“Hello, my name is " + this.name); }; // 创建实例 const person1 = new Person(“Alice”); const person2 = new Person(“Bob”); person1.sayHello(); // 输出:Hello, my name is Alice person2.sayHello(); // 输出:Hello, my name is Bob
注意:
  • 通过修改 Person.prototype所有实例 都能访问到新的方法或属性。
  • prototype 只有在构造函数上存在,实例本身没有prototype 属性

2.proto 的作用

  • 每个对象实例 都有一个 __proto__ 属性,指向创建该实例的构造函数的原型对象
  • 这个属性是隐式原型 ,用于查找属性和方法示例: console.log(person1.proto === Person.prototype); // true console.log(person2.proto === Person.prototype); // true
作用:
  • 当我们访问对象的属性或方法时,JavaScript 会先查找对象本身 ,如果没有,则沿着**__proto__** 继续查找,直到 null
  • 这种链式查找机制 称为原型链

三、构造函数、实例、原型三者关系

  1. 构造函数:
  • Person.prototype:原型对象。
  • Person.prototype.constructor:指向构造函数本身。
  1. 实例对象:
  • person1.__proto__:指向构造函数的原型对象,即 Person.prototype关系图: Person –> prototype –> { sayHello, constructor } ↑ proto ↑ person1 / person2

四、示例验证原型链

console.log(person1.proto === Person.prototype); // true console.log(Person.prototype.constructor === Person); // true console.log(Object.getPrototypeOf(person1) === Person.prototype); // true


五、修改 prototype 和proto** 的区别**

修改 prototype:影响所有实例

Person.prototype.greet = function() { console.log(“Greetings from " + this.name); }; person1.greet(); // Greetings from Alice person2.greet(); // Greetings from Bob

修改proto** :仅影响当前对象**

const obj = {}; obj.proto = { customMethod: function() { console.log(“I am custom!”); } }; obj.customMethod(); // I am custom!


六、在类中的表现(ES6+)

在 ES6 中,使用 class 语法定义类,原型机制依然有效: class Animal { speak() { console.log(“Animal speaks”); } } const dog = new Animal(); console.log(dog.proto === Animal.prototype); // true console.log(Animal.prototype.constructor === Animal); // true


七、为什么proto** 不推荐使用?**

  1. 性能问题: __proto__ 是非标准特性,访问速度较慢。
  2. 兼容性问题: 早期版本的 IE 不支持。
  3. 规范性: 建议使用 Object.getPrototypeOf() 代替: console.log(Object.getPrototypeOf(person1) === Person.prototype); // true

八、总结

比较项prototypeproto
作用构造函数的原型对象实例对象的隐式原型
类型对象对象
修改效果修改后影响所有实例修改后仅影响该实例及其后代
使用场景批量定义共享方法和属性查找实例对象原型链中的属性和方法
推荐使用否,建议使用 Object.getPrototypeOf() 代替

面试高频问题

  1. prototype 和proto** 有什么区别?**
  • prototype 是构造函数的属性,__proto__ 是实例对象的属性。
  • prototype 用于定义共享方法和属性__proto__ 用于访问原型链
  1. 如何修改实例的原型?
  • 可以直接使用 Object.setPrototypeOf(obj, newProto);obj.__proto__ = newProto;,但前者性能更优。
  1. 为什么不推荐使用proto** ?**
  • 性能差且非标准化,推荐使用 Object.getPrototypeOf()

希望这些讲解能帮你彻底搞清楚 prototype__proto__ 的区别!