• 一篇文章图文并茂地带你轻松学完 JavaScript 原型和原型链


    JavaScript 原型和原型链

    在阅读本文章之前,已经默认你了解了基础的 JavaScript 语法知识,基础的 ES6 语法知识 。
    本篇文章旨在为 JavaScript继承 打下基础

    原型

    1. JavaScript 里任何一个函数都有一个 prototype 属性,这个属性称之为原型
    function Person() {
        this.name = "name";
    }
    console.log(Person.prototype)
    

    Person.prototype 实际上是一个包含 constructor 属性的对象

    constructor 实际上就是构造函数本身

    // Person.prototype
    {
        constructor: Person
    }
    
    1. Person.prototype 指向的对象很特殊(原型链学完就明白为什么特殊了),可以被实例所共享,可以作为实例的属性直接调用
    const obj1 = new Person();
    const obj2 = new Person();
    console.log(obj1.constructor === obj2.constructor) 	// true
    console.log(obj1.constructor === Person)			// true
    

    这意味着,我们可以在 Person.prototype 上加一些共享属性或者方法,然后直接在实例中共享

    Person.prototype.eat = function() {
        console.log("eat");
    }
    
    // 现在
    obj1.eat(); // "eat";
    obj2.eat(); // "eat";
    

    上面,我们简要的说明了原型,以及原型的作用,下面我们探索原型链

    原型链

    我们先看一个小例子

    function Person() {
        this.name = "name";
    }
    
    const p = new Person();
    p.toString(); 			// [object Object]
    

    我们并没有在 Person.prototype 上定义 toString 这个方法,按理来说当我们调用的时候应该报错 ,然而浏览器却 "不厚道" 的输出了 [object Object]

    要解释这个原因,还有 "很长的路" 要走。

    1. 首先任何实例化出来的对象都拥有 __proto__ 属性,这个属性指向构造函数的 prototype
    console.log(p.__proto__ === Person.prototype) // true
    

    之前我们写过这样的代码

    Person.prototype.eat = function() {
        console.log("eat");
    }
    
    obj1.eat(); // "eat";
    obj2.eat(); // "eat";
    

    我们惊讶的发现, obj1 上也可以拥有 eat 方法了。

    1. 如果一个对象上没有这个属性,他就会去他的 __proto__ 属性对应的对象上去找,如果还没有就继续这个对象的 __proto__上去找

    那么 Person.prototype 是否有 __proto__

    console.log(Person.prototype.__proto__);
    

    在这里输出的结果中有 constuctor: Object

    之前提到 constuctor 其实就是构造函数本身,因此

    console.log(Person.prototype.__proto__ === Object.prototype); // true
    

    我们在 Object.prototype 中发现了这个方法,并进行调用

    console.log(Object.prototype.hasOwnProperty("toString")) // true
    Object.prototype.toString.call(p); // [object Object]
    

    至此原型链基本是说完了,有兴趣的可以探究一下

    1. Object.prototype 是否有 __proto__ ?
    2. 构造函数是否也是被实例化出来的?
    3. 数组的原型链是什么样的

    对于第三题,有兴趣的可以自己画一下图

    console.log(Array.prototype.__proto__ === Object.prototype) // true
    
  • 相关阅读:
    [树形DP]Luogu P1131 [ZJOI2007]时态同步
    [状压DP]JZOJ 1303 骑士
    [DFS]JZOJ 1301 treecut
    [最小费用最大流]JZOJ 4802 探险计划
    [KMP][倍增求LCA]JZOJ 4669 弄提纲
    [DP]JZOJ 1758 过河
    列表生成式和生成器表达式
    协程函数
    生成器
    迭代器
  • 原文地址:https://www.cnblogs.com/huro/p/14370354.html
Copyright © 2020-2023  润新知