Skip to content

JavaScript 是基于原型的语言,Prototype 和 Prototype Chain 是实现继承的一种机制。每个 JavaScript 对象在创建时均关联原型对象,它们均有一个内置属性,通过 ES5 __proto__ 或 ES6 Object.getPrototypeOf 获得。原型链是对象通过其原型与其他对象相关联的链,当你访问一个对象的属性或方法时,若在对象本身没有找到,则继续在该对象的原型上查找,若原型上也没有,则继续在原型的原型上查找,直到找到该属性或方法或到达原型链的末端,原型链的末端是 Object.prototype,若在原型链的任何地方找不到指定的属性或方法,则返回 undefined

什么是原型和原型链

在 JavaScript 中,每个对象都有一个原型对象,原型对象也是一个普通的对象,它有一个 constructor 属性指向创建它的构造函数,它也有一个原型对象,这样就构成了一个原型链。在 JS 中,面向对象的实现是基于原型的,而不是基于类的。就算 ES6 中引入了 class 关键字,但是它只是语法糖,本质上还是基于原型的。

题目: https://juejin.cn/post/6959043611161952269#heading-59

js
//这是一个构造函数
function Animals(name){
    this.name=name;
    
}
//在构造函数的原型上添加属性和方法
Animals.prototype.sleep=function(){
 console.log(`${this.name} is sleeping`);
}
//创建对象
const dog=new Animals(Bob);

//定义子类构造函数
function Cat(name,age){
 Animals.call(this.name);
 this.age=age;
}
//设置子类的原型为父类的实例,实现继承
Cat.prototype=Object.create(Animals.prototype);
Cat.prototype.constructor=Cat;

//在子类上面添加方法
Cat.prototype.miao=function(){
console.log(`${this.name}miaomiao`)

//创建子类实例
const huahua=new Cat(`huahua`,1);
const kitty=new Cat(`kitty`,2);

//调用继承的方法和子类自己的方法
huahua.miao();
kitty.sleep();
}
  1. 优势:
  • 实现简单,只需要修改原型对象就行
  • 能实现基于原型的方法共享,提高内存利用率
  • 符合js面向对象风格易于理解
  1. 不足:
  • 继承层次过多时,性能受到影响
  • 原型链继承导致对象之间引用关系复杂,不利于调试

应用场景

  • 组件库开发,开发按钮组件库
js
function Button(label) {
    this.label = label;
}

Button.prototype.click = function() {
    console.log(`${this.label} button clicked`);
};

function IconButton(label, icon) {
    Button.call(this, label);
    this.icon = icon;
}

IconButton.prototype = Object.create(Button.prototype);
IconButton.prototype.constructor = IconButton;

IconButton.prototype.click = function() {
    console.log(`${this.icon} icon button clicked`);
};

const myButton = new Button('Submit');
myButton.click(); // Submit button clicked

const myIconButton = new IconButton('Upload', '📁');
myIconButton.click(); // 📁 icon button clicked