• JavaScript扩展原型链浅析


    前言

    上文对原型和原型链做了一些简单的概念介绍和解析,本文将浅析一些原型链的扩展。

    javaScript原型和原型链
    http://lewyon.xyz/prototype.html

    扩展原型链

    使用new操作符

    利用原型是对象的特性,实例化对象的时候,继承多个构造函数的属性和方法

    兼容性:支持目前以及所有可想象到的浏览器 (IE5.5 都可以使用)

    function parent1() {}
    
    parent1.prototype = {
      parentName: "parent1",
    };
    
    function parent2() {}
    
    let child = new parent1();
    
    child.childName = "child";
    
    parent2.prototype = child;
    
    let newChild = new parent2();
    
    console.log(newChild.parentName); // parent1
    
    console.log(newChild.childName); // child
    
    

    使用Object.create

    Object.create

    Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的 proto

    兼容性:支持当前所有非微软版本或者 IE9 以上版本的浏览器

    /**
     *
     * Object.create(proto,[propertiesObject])
     *
     * @params proto 新创建对象的原型对象。
     * 如果proto参数不是 null 或非原始包装对象,则抛出一个 TypeError 异常,可以使用try和catch捕获抛出的异常
     *
     * @params propertiesObject   可选参数 ,数据类型:对象
     *
     * */
    const parent1 = {
      name: "parent1",
      do: function () {
        console.log(this.name);
      },
    };
    const child = Object.create(parent1);
    child.name = "child"; // child添加自身的属性name
    child.do(); // child
    
    
    /**
     *
     *
     *
     *---------------------------------------------------------------------------------------
     *
     *
     * */
    function parent2() {}
    parent2.prototype = {
      name: "parent2",
    };
    function parent3() {}
    let child = Object.create(parent2.prototype);
    child.childName = "child";
    parent3.prototype = child;
    let newChild = new parent3();
    console.log(newChild.name); // parent2
    console.log(newChild.childName); // child
    
    

    使用setPrototypeOf

    兼容性:不支持 IE8 以下的版本。

    
    /**
     * Object.setPrototypeOf(obj, prototype)
     *
     * @params obj   要设置其原型的对象。
     *
     * @params  prototype
     *
     * 该对象的新原型 (一个对象 或 null)
     * 如果要设置原型的对象的 [[Prototype]] 被修改成不可扩展 (通过 Object.isExtensible()查看),就会抛出 TypeError 异常。
     * 如果 prototype 参数的数据类型不是 对象或者 null  (例如,数字,字符串,boolean,或者 undefined),那么方法就不会执行。
     * 否则,该方法将 obj 的 [[Prototype]] 修改为新的值。
     *
     * Object.setPrototypeOf() 是 ECMAScript 6中新增的方法,相对于操作对象的原型链Object.prototype.__proto__来说,更适合拿来修改对象的原型
     *
     *
     * */
    
    function parent1() {}
    parent1.prototype = {
      name: "parent1",
    };
    function parent2() {}
    let Obj = {
      ObjName: "Obj",
    };
    Object.setPrototypeOf(Obj, parent1.prototype);
    parent2.prototype = Obj;
    let newChild = new parent2();
    console.log(newChild.name); // parent1
    console.log(newChild.ObjName); // Obj
     
    
    折叠

    使用__proto__直接在原型链上操作,

    使用__proto__操作,如果设置的属性和方法较多,会产生性能问题,因此不太推荐使用__proto__

    兼容性:IE10 及以下的浏览器版本。

    /**
     * 
     * 直接在原型链上操作,如果设置的属性和方法较多,会产生性能问题
     * 
     * */ 
    var obj = {
      __proto__: {
        protoName1: "protoName1",
        __proto__: {
          protoName2: "protoName2",
          __proto__: Object.prototype,
        },
      },
    };
    console.log(obj.protoName1); // protoName1
    console.log(obj.protoName2); // protoName1
    
    

    小结

    • 在使用原型链编写组件的过程中,我们需要考虑到原型链的性能问题。
    • 实例化对象过程中,会向上查找原型链的方法和属性,在书写的过程中,需要注意构造函数和对象的自带的方法,确认是否会被覆盖和重写。

    以上就是js中扩展原型链的简单解析,有任何问题欢迎留言,后续的文章整理然后作为补充。

    文章博客地址:JavaScript扩展原型链浅析

    源码地址

    欢迎关注公众号:程序员布欧,不定期更新一些文章

    创作不易,转载请注明出处和作者。

  • 相关阅读:
    Navicat工具连接Oracle数据库
    机器学习—非零中心化、非零中心化会带来的问题
    MySQL索引的类型有哪些?
    新型BI解决方案:SaaS BI,在浏览器上分析数据
    阿里巴巴《MySQL成长手册》精简版
    Flutter最新配置本地资源文件详解,报错看这篇文章就对了!
    吉时利2602A数字源表-安泰测试
    GIT 常见操作记录
    Pandas DataFrame 的可视化工具大全
    Stream 流式编程:并行流
  • 原文地址:https://www.cnblogs.com/akari16/p/16425744.html