lakeiedward's lakeiedward's
首页
标签
  • UI组件库

    • vue-luckyui (opens new window)
    • vue-luckyui文档 (opens new window)
  • 若依页面分层工具

    • ry-layer-page (opens new window)
    • ry-layer-page文档 (opens new window)
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 书单
    • 关于
掘金 (opens new window)
GitHub (opens new window)

lakeiedward

首页
标签
  • UI组件库

    • vue-luckyui (opens new window)
    • vue-luckyui文档 (opens new window)
  • 若依页面分层工具

    • ry-layer-page (opens new window)
    • ry-layer-page文档 (opens new window)
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 书单
    • 关于
掘金 (opens new window)
GitHub (opens new window)
  • 「Object.create」详解 之 源码彻底吃透

    • Object.create是什么?
      • 语法
        • 使用 null 原型的对象
          • Object.create的使用示例
            • 源码-示例
              • Object.create的兼容性
              lakeiedward
              2022-12-02
              前端技术
              目录

              「Object.create」详解 之 源码彻底吃透

              # Object.create是什么?

              MDN的定义:Object.create()方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。

              # 语法

              Object.create(proto, propertiesObject)
              
              1

              proto

              • 新创建对象的原型对象。

              propertiesObject (可选)

              • 如果该参数被指定且不为 undefined,则该传入对象的自有可枚举属性将为新创建的对象添加指定的属性值和对应的属性描述符。这些属性对应于 Object.defineProperties() 的第二个参数,也就是enumerable。

              # 使用 null 原型的对象

              1.以 null 为原型的对象存在不可预期的行为,因为它未从 Object.prototype 继承任何对象方法,即创建对象的原型为空。

              const normalObj = {};   
              const nullProtoObj = Object.create(null); 
              
              1
              2

              图片.png

              2.使用null创建原型对象的时候,再使用Object的原型对象的方法就会报错,因为原型上不存在该方法了;

              const normalObj = {};   
              const nullProtoObj = Object.create(null); 
              
              normalObj.valueOf(); // {}
              nullProtoObj.valueOf(); //error:nullProtoObj.valueOf is not a function
              
              1
              2
              3
              4
              5

              图片.png

              3.我们可以为以 null 为原型的对象添加 toString 方法,类似于这样:

              nullProtoObj.toString = Object.prototype.toString;
              console.log(nullProtoObj); // toString: ƒ toString()
              
              1
              2

              与常规的对象不同,nullProtoObj 的 toString 方法是这个对象自身的属性,而非继承自对象的原型。这是因为 nullProtoObj “没有”原型(null)。

              4.在实践中,Object.prototype原型的自有属性可能会导致我们判断错误

              const ages = { alice: 18, bob: 27 };
              
              function hasPerson(name) {
                return name in ages;
              }
              
              function getAge(name) {
                return ages[name];
              }
              
              hasPerson("hasOwnProperty") // true
              getAge("toString") // [Function: toString]
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12

              使用null创建对象则消除了这种潜在的问题

              const ages = Object.create(null, {
                alice: { value: 18, enumerable: true },
                bob: { value: 27, enumerable: true },
              });
              
              hasPerson("hasOwnProperty") // false
              getAge("toString") // undefined
              
              1
              2
              3
              4
              5
              6
              7

              # Object.create的使用示例

              let o = Object.create(
                {},
                {
                  p: {
                    value: 42,
                    writable: false,//可写的 -- 为true时o对象的属性值可改变
                    enumerable: false,//可枚举的 -- 为true时o对象的属性可被遍历
                    configurable: false,//可配置的 -- 为true时o对象的属性可被删除
                  },
                }
              );
              
              o.p = 24; //{p: 42}
              delete o.p; //{p: 42}
              for (let i in o) {
                console.log(i);// i 没有输出
              }
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17

              # 源码-示例

              /* 源码
               ------------------------------*/
              Object.myCreate = function (proto, propertiesObject = undefined) {
                if (propertiesObject === null) {
                  // 这里没有判断propertiesObject 是否是原始包装对象
                  throw "Cannot convert undefined or null to object at Function.create (<anonymous>)";
                } else {
                  function Fn() {}
                  Fn.prototype = proto;
                  let obj = new Fn();
                  if (proto === null) {
                    obj.__proto__ = null; 
                  }
                  if (propertiesObject !== undefined) {
                    Object.defineProperties(obj, propertiesObject);
                  }
                  return obj;
                }
              };
              
              /* 示例
               ------------------------------*/
              const throwError = Object.myCreate({}, null); //throwError
              
              const obj1 = Object.myCreate(null);
              console.log(obj1);
              
              const obj2 = Object.myCreate({ age: 18 });
              console.log(obj2); //  obj2的构造函数的原型对象是age: 18
              
              const obj3 = Object.myCreate(
                { age: 18 },
                {
                  isTrue: {
                    value: true,
                    enumerable: true,
                  },
                }
              );
              console.log(obj3); // isTrue: true, obj3的构造函数的原型对象是age: 18
              
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40

              # Object.create的兼容性

              图片.png

              如有小伙伴发现错误之处欢迎指正🤚

              #JS
              上次更新: 2022/12/02, 09:00:55
              Theme by Vdoing | Copyright © 2017-2023 lakeiedward | blog 皖ICP备2023006581号-1
              • 跟随系统
              • 浅色模式
              • 深色模式
              • 阅读模式