插件窝 干货文章 JS中__proto__与prototype的区别

JS中__proto__与prototype的区别

对象 prototype 函数 proto 97    来源:    2024-10-12

JS中__proto__和prototype是两个与原型相关的属性,它们在功能上稍有不同。本文将具体介绍并比较这两者的区别,并提供相应的代码示例。

首先,我们先来了解一下它们的含义和用途。

proto

__proto__是对象的一个内置属性,它用于指向该对象的原型。每个对象都有一个__proto__属性,包括自定义对象、内置对象和函数对象。通过__proto__属性,我们可以访问和操作对象的原型链。

让我们来看一个例子:

let obj = {};
console.log(obj.__proto__); // 输出:Object {}

let arr = [];
console.log(arr.__proto__); // 输出:Array []

function func() {}
console.log(func.__proto__); // 输出:[Function]

上面的代码中,我们创建了一个空对象obj,并访问了它的__proto__属性。可以看到,obj.__proto__指向了一个Object{}对象。同样,我们还创建了一个空数组arr,并访问了它的__proto__属性,结果是arr.__proto__指向了一个Array []对象。而对于函数对象func来说,它的__proto__指向的是一个[Function]对象。

总结起来,__proto__属性用于指向对象的原型,我们可以通过它来访问和操作原型链。

prototype

prototype是函数对象独有的属性,它指向了一个原型对象。每个函数对象都有一个prototype属性,但它只有在这个函数作为构造函数使用时才有意义。

我们来看一个示例:

function Person() {}

console.log(Person.prototype); // 输出:Person {}

上面的代码中,我们定义了一个Person函数对象,并访问了它的prototype属性。可以看到,Person.prototype指向了一个Person{}对象。

prototype属性的主要作用是在构造函数模式下,用于构建实例对象的原型链。当我们使用构造函数来创建一个对象时,它的__proto__属性会指向构造函数的prototype属性。

let person = new Person();

console.log(person.__proto__ === Person.prototype); // 输出:true

上面的代码中,我们使用了Person构造函数来创建了一个对象person。结果表明,person.__proto__指向了Person.prototype。

区别和联系

__proto__和prototype都与对象的原型相关,它们之间的联系和区别如下:

  1. __proto__是实例对象的属性,用于指向该对象的原型;而prototype是构造函数的属性,用于指向构造函数的原型对象。
  2. __proto__是读取并访问对象的原型链的属性,可以在实例对象上直接访问;而prototype是构造函数的属性,只能在构造函数内部访问。
  3. __proto__可以通过Object.setPrototypeOf()或直接赋值的方式来修改;而prototype只能在构造函数内部通过函数名.prototype来修改。
  4. __proto__是非标准的属性,只有部分浏览器支持;而prototype是标准属性,所有的对象和函数都有。

下面的代码示例用于进一步说明这两者的区别与联系:

function Animal() {}
Animal.prototype.eat = function() {
  console.log("Animal is eating");
};

function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.bark = function() {
  console.log("Dog is barking");
};

const dog1 = new Dog();
dog1.eat(); // 输出:Animal is eating
dog1.bark(); // 输出:Dog is barking

console.log(dog1.__proto__ === Dog.prototype); // 输出:true
console.log(Dog.prototype.__proto__ === Animal.prototype); // 输出:true

上面的代码中,我们通过定义Animal构造函数和Dog构造函数,创建了一个继承关系。通过__proto__和prototype属性,我们可以访问到对象的原型链,并且证明了它们之间的联系。

综上所述,__proto__和prototype在JS中都与原型相关,但在功能和使用方式上有所不同。了解它们的区别可以帮助我们更好地理解JS中的原型机制,并在编写代码时更灵活地利用它们。