跳至主要內容

原型与原型链

wzCoding大约 3 分钟JavaScript原型与原型链

原型与原型链

原型和原型链是对象上的一个重要的特性,它们是 JavaScript 中实现继承和共享属性的基础,也是我们在学习对象的过程中一个非常重要的知识点。

下图是浏览器中对象的原型结构图:

原型
原型

原型

每个对象都有一个原型对象,可以通过__proto__属性访问,当我们在读取对象上的某一个属性时,如果对象本身没有定义这个属性,那么就会从对象的原型对象上查找该属性,这种现象叫做 原型继承

const fruit = {
    smell:'sweet',
    weight:function(){
        return `${200}g`;
    }
};
const apple= {
    color:'red'
}
apple.__proto__ = fruit;
console.log(apple.smell); // 输出 'sweet'
console.log(apple.weight()) // 输出 '200g'

在上面的例子中,我们将 apple 对象的原型对象设置为 fruit 对象,所以它便继承了 smell 属性和 weight 方法。

proto 与 [[prototype]]

在上面图片与示例代码中,我们发现对象的原型对象是通过 __proto__ 属性访问的,而在浏览器中却展示的是 [[prototype]],那么它们有什么区别呢?

  • __proto__ 是一个已经弃用了的属性(虽然还有浏览器仍然支持访问这个属性),用于访问对象的原型对象(一般不推荐直接使用)。
  • [[prototype]] 是一个标准属性,它存在于所有对象中,用于访问对象的原型对象。

在浏览器中,__proto__ 属性是 [[prototype]] 的非标准别名,它们的作用完全相同。如果想要操作对象的原型对象,推荐以下方法:

  • 使用 Object.getPrototypeOf(obj) 方法获取对象的原型对象。
  • 使用 Object.setPrototypeOf(obj, newProto) 方法设置对象的原型对象。

原型链

原型链是一种由原型对象组成的链式结构,用于实现继承和共享属性。当访问一个对象的属性时,JavaScript 会首先在当前对象中查找,如果没有找到,则会沿着原型链向上查找,直到找到为止。

原型链的终点是 null,表示原型链的结束。

原型链的用途

原型链是 JavaScript 中实现继承和共享属性的基础,它使得对象可以继承其他对象上的属性和方法。原型链的用途包括但不限于:

  • 实现继承:通过原型链,子对象可以继承父对象的属性和方法。

    const fruit = {
        smell:'sweet',
        weight:function(){
            return `${200}g`;
        }
    };
    const apple= {
        color:'red'
    }
    
    Object.setPrototypeOf(apple,fruit);
    
    console.log(apple.smell); // 输出 'sweet'
    console.log(apple.weight()) // 输出 '200g'
    
  • 实现共享属性:通过原型链,多个对象可以共享同一个原型对象上的属性和方法。

    const fruit = {
        smell:'sweet',
        weight:function(){
            return `${200}g`;
        }
    };
    const apple= {
        color:'red'
    }
    const banana= {
        color:'yellow'
    }
    
    Object.setPrototypeOf(apple,fruit);
    Object.setPrototypeOf(banana,fruit);
    
    console.log(apple.smell); // 输出 'sweet'
    console.log(banana.smell); // 输出 'sweet'
    console.log(apple.weight()) // 输出 '200g'
    console.log(banana.weight()) // 输出 '200g'
    
  • 实现动态属性:通过原型链,可以在运行时为对象添加新的属性和方法。

    const fruit = {
        smell:'sweet',
        weight:function(){
            return `${200}g`;
        }
    };
    const apple= {
        color:'red'
    }
    const banana= {
        color:'yellow'
    }
    
    Object.setPrototypeOf(apple,fruit);
    Object.setPrototypeOf(banana,fruit);
    
    fruit.price = 5;
    fruit.getColor = function(){
        return this.color;
    }
    console.log(apple.smell); // 输出 'sweet'
    console.log(banana.smell); // 输出 'sweet'
    console.log(apple.getColor()); // 输出 'red'
    console.log(banana.getColor()); // 输出 'yellow'
    console.log(apple.price); // 输出 5
    console.log(banana.price); // 输出 5