美文网首页
3张图记牢javaScript原型

3张图记牢javaScript原型

作者: 老陈要上天 | 来源:发表于2019-04-26 19:55 被阅读0次

    javaScript原型和原型链的详细介绍网上已经有很多大神文章介绍过,本篇不打算再讲原理。如果朋友您已经理解了原型、原型链兴许这边文章能起到一点点作用。
    说实在的我在实际工作中很少用到原型链,顶多在自建的对象原型上或者预定义对象原型上(比如Array.prototype)添加个方法,但我又一直记不住原型链。在学习总结之后,我我决定把种种特例拆开来记忆,就像小学学习乘除法时将0和1特殊记忆。

    必须了解的概念

    1、只有函数才有prototype属性
    2、所有对象都有_ _ proto _ _属性,它不是ECMA规范定义的,但绝大部分浏览器都实现了
    3、JavaScript中万物皆对象,函数也是对象,所以函数既有prototype又有_ _ proto _ _属性
    4、一个对象的_ _ proto _ _属性指向它的构造函数的prototype(原型),将这句话带入图中就更好理解和记忆

    不同类型的对象原型链图

    1、Object对象
    let a = { name:"小明",age:20 }//通过字面量创建的对象
    let b = new Object()//通过构造函数创建的对象
    

    这类Object对象的原型链最简单,如下图:


    Object对象的原型链
    2、Function对象
    let c = function() {}//函数表达式
    let d = new Function()//通过构造函数创建的函数
    

    这类的Function对象的原型链:


    Function类型的对象的原型链
    3、其他对象
    let e = new Array()//预定义类型的对象
    
    class Cat {
     constructor(){}
    }
    let f = new Cat()//通过其他function new出的对象
    
    其他自定义、预定义类型的对象的原型链

    最后两个图中,从typeof Function.prototype === function可以看出Function.prototype也是一个函数对象,所以它也有prototype属性,而它的prototype属性是undefined,也是特殊的一个地方
    下面是具体的实验:

        class Cat {
          constructor() {
          }
        }
        let mycat = new Cat();
        console.log("1-1:", mycat instanceof Cat);
        console.log("1-2:", Cat.prototype);
        console.log("1-3:", Cat.__proto__);
        console.log("1-4:", mycat.__proto__);
        console.log("1-5:", typeof Cat.prototype);
        console.log("1-6:", Cat.__proto__ === Function.prototype);
        console.log("1-7:", Object.prototype === Cat.prototype.__proto__);
        console.log("1-8:", Cat.prototype.constructor === Cat);    
        console.log("1-9:", mycat.__proto__ === Cat.prototype);
    
        let a = {};
        console.log("2-1:", a.__proto__);
        console.log("2-2:", a.prototype);
        console.log("2-3:", a.__proto__ === Cat.prototype.__proto__);
        console.log("2-4:", a.__proto__.__proto__);
    
        let b = new Object();
        console.log("3-1:", b.__proto__);
        console.log("3-2:", b.__proto__ === Object.prototype);
        console.log("3-3:", b.__proto__ === Cat.prototype.__proto__);
        console.log("3-4:", b.__proto__.__proto__);
    
        let c = function(arg1, arg2) {
          let cc = "hello";
        };
        console.log("4-1:", c.__proto__);
        console.log("4-2:", c.prototype);
        console.log("4-3:", c.__proto__ === Function.prototype);
        console.log("4-4:", c.__proto__.__proto__ == Object.prototype);
        console.log("4-5:", c.__proto__.__proto__.__proto__);
    
        let d = new Function();
        console.log("5-1:", d.__proto__);
        console.log("5-2:", d.prototype);
        console.log("5-3:", d.__proto__ === Function.prototype);
        console.log("5-4:", d.__proto__.__proto__ == Object.prototype);
        console.log("5-5:", d.__proto__.__proto__.__proto__);
        console.log("5-6:", Function.__proto__ === Function.prototype);
        console.log("5-7:", Function.prototype.__proto__ === Object.prototype);
    
        let e = new Array()
        console.log("6-1:", e.__proto__);
        console.log("6-2:", e.__proto__ === Array.prototype);
        console.log("6-3:", e.__proto__ === Cat.prototype.__proto__);
        console.log("6-4:", e.__proto__.__proto__);
        
        console.log("7-1:", typeof Function.prototype);
        console.log("7-2:", typeof Object.prototype);
        console.log("7-3:", Function.prototype.prototype);
    
    实验结果
    在chrome里Function.prototype通过console.log()打印是出来的是f(){[native code]}其实就是Function.prototype.toString()的结果,是 native 的代码实现的 built-in 函数,而不是 JavaScript 代码。但这并不是语言标准规定的,只是恰好 Chrome 都这么做了,不过这里不需要关心~。

    相关文章

      网友评论

          本文标题:3张图记牢javaScript原型

          本文链接:https://www.haomeiwen.com/subject/olzfnqtx.html