javascript核心浅析(一)之原型和原型链

113 阅读2分钟

基本说明

  • 所有引用类型(函数,数组,对象)都拥有__proto__属性(隐式原型)
  • 所有函数拥有prototype属性(显式原型)(仅限函数)
  • 原型对象:拥有prototype属性的对象,在定义函数时就被创建。
  • 每一个实例都有隐式原型(__proto__ ),并指向 创建它的构造函数的 显式原型(prototype)。

代码中原型和原型链展示

  • 主要有三个概念,__proto__(隐式原型) prototype (显示原型)constructor(构造函数)。

  • 所谓原型就是 person.__proto__ Person.prototype, 二者是等同的。

  • 所谓原型链就是通过隐式原型__proto__一层一层串联起来的链子。

  • 原型链一直查到null为止。

  • 三者之间的关系如下代码所示:

    // 声明一个构造函数 Person
    function Person (name = '张三') {
        this.name = name;
    };
    // 可以给函数的原型上添加方法,为Person添加一个方法 getName
    Person.prototype.getName = () => {
        return 'getting name';
    };
    // 创建一个Person实例
    let person = new Person();
    
    console.log( person );
    
    // 实例的__proto__指向构造函数的prototype,构造函数的显式原型的constructor指向的是构造函数。
    
    // 构造函数内部没有getName, 会向其父级寻找,找到后继承该方法。 实例的 __proto__ 等同于 函数的 prototype
    person.getName();  // 'getting name';
    
    person.__proto__ === Person.prototype;
    
    person.__proto__.constructor === Person;
    
    person.__proto__.__proto__ === Object.prototype;
    
    person.__proto__.__proto__.constructor === Object;
    
    person.__proto__.__proto__.__proto__ === null;
    
    // 如上所示,实例的__proto__指向的就是函数的原型,原型的constructor属性则将其指向构造函数。通过__proto__不断一级一级向上而形成的链子,就被成为原型链。
    // 逐层向上查找,直到null结束,如扔没有找到,则返回undefined。
    

原型和原型链的关系图如下所示:

原型链

拓展原型链的四种方法

// 方式一: Object.create() 创建一个对象,将其__proto__指向 proto
Object.create(proto, [ properties ]);  

// 方式二: Object.setPrototypeOf(obj, prototype);  prototype 设置为 obj 的 __proto__ 

// 方式三: __proto__;  
obj1.__proto__ = obj2;

// 方式四: 构造函数创建
function Person(){};
Person.prototype.getName = () => { console.log( 'getName' ) };

相关文章:

1. ES6学习笔记(一)

2. ES6学习笔记(二) --- 一探Object.create和对象属性操作符