Wang's blog Wang's blog
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Wang Mings

跟随大神,成为大神!
首页
  • 前端文章

    • HTML教程
    • CSS
    • JavaScript
  • 前端框架

    • Vue
    • React
    • VuePress
    • Electron
  • 后端技术

    • Npm
    • Node
    • TypeScript
  • 编程规范

    • 规范
  • 我的笔记
  • Git
  • GitHub
  • VSCode
  • Mac工具
  • 数据库
  • Google
  • 服务器
  • Python爬虫
  • 前端教程
更多
收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Python爬虫

  • 前端教程

    • 团队规范

    • Project

    • JS

      • Canvas基础
      • 数据结构
      • 树的深度优先遍历与广度优先遍历
      • for in和for of区别
      • ES6-新增特性一览
      • ES6-解构赋值及原理
      • ES6-Object
        • [#](#_1-key-value) 1. Key/Value
          • [#](#_1-1-object-keys-obj-es5) 1.1 Object.keys\(obj\)ES5
          • [#](#_1-2-object-values-obj-es8) 1.2 Object.values\(obj\)ES8
          • [#](#_1-3-object-entries-obj-es8) 1.3 Object.entries\(obj\)ES8
          • [#](#_1-4-object-getownpropertynames-obj) 1.4 Object.getOwnPropertyNames\(obj\)
          • [#](#_1-5-for-in) 1.5 for ... in
        • [#](#_2-descriptor) 2. Descriptor
          • [#](#_2-1-object-defineproperty-obj-prop-descriptor) 2.1 Object.defineProperty\(obj, prop, descriptor\)
          • [#](#案例) 案例:
          • [#](#实际应用) 实际应用
          • [#](#_2-2-object-defineproperties-obj-props) 2.2 Object.defineProperties\(obj, props\)
        • [#](#_3-other) 3. Other
          • [#](#_3-1-object-create-proto-props) 3.1 Object.create\(proto, \[props\]\)
          • [#](#举例) 举例:
          • [#](#思考题-为什么要有object-create-null) 思考题:为什么要有Object.create\(null\)?
          • [#](#_3-2-object-assign-target-sources-es6) 3.2 Object.assign\(target, ...sources\)ES6
          • [#](#_3-3-object-is-value1-value2-es6) 3.3 Object.is\(value1, value2\)ES6
          • [#](#_3-4-object-freeze-obj-stage-1) 3.4 Object.freeze\(obj\)Stage 1
          • [#](#_3-5-对象的扩展) 3.5 对象的扩展
        • [#](#参考文档) 参考文档:
      • ES6-模块详解
      • ES6-Class
      • ES6-ECMAScript特性汇总
      • 输入URL背后的技术步骤
      • JavaScript与浏览器 - 线程与引擎
      • HTTP跨域解决方案
      • Http 2与Http 1.x比较
      • JavaScript原型
      • JavaScript继承
      • JavaScript事件循环
      • 动手实现Promise
      • JS设计模式
      • JS 经典面试题
      • 排序算法
      • 正则表达式
      • MVC、MVP、MVVM区别
      • Array API与V8源码解析
      • 从V8 sort源码看插入排序
    • NodeJS

    • Vue

    • React

    • 效率工具

    • 读书笔记

  • 教程
  • 前端教程
  • JS
wangmings
2022-07-19
目录

ES6-Object

# # ES6-Object

Object是js最重要的数据结构,es6对其进行了重大升级。除了解构 (opens new window) (opens new window)外,Object还提供了大量的基础方法。另外Object对象属性及其方法太常用,有些相似的方法容易使用错误,故根据MDN (opens new window) (opens new window)归类整理。注意文中重点标注的文字以及角标标注的ES发布版本。

# # 1. Key/Value

# # 1.1 Object.keys(obj)ES5

该方法返回一个给定对象的自身可枚举属性组成的数组。

只列出自身的枚举属性(内部使用obj.hasOwnProperty(prop)指示对象自身属性中是否具有指定的属性)

    Object.keys = (function() {
      return function() {
        var result = [];
        for (var prop in obj) {
          if (hasOwnProperty.call(obj, prop)) result.push(prop);
        }
    
        return result;
      }
    })()
    
1
2
3
4
5
6
7
8
9
10
11

# # 1.2 Object.values(obj)ES8

该方法返回一个给定对象自身的所有可枚举属性值的数组。

只列出自身的枚举属性值

# # 1.3 Object.entries(obj)ES8

该方法返回一个给定对象自身可枚举属性的键值对数组。

只列出自身枚举的键值对数组。

Object.fromEntries()Stage 3是其逆方法,把键值对列表转换为一个对象.

# # 1.4 Object.getOwnPropertyNames(obj)

该方法返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。

自身的枚举和不枚举属性都会列出

# # 1.5 for ... in

for...in语句以任意顺序遍历一个对象的可枚举属性(包括原型链上的可枚举属性)。包括原型链上的可枚举属性。

自身和原型链上的属性。

# # 2. Descriptor

# # 2.1 Object.defineProperty(obj, prop, descriptor)

该方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

  • descriptor
    • configurable。 如果为false,则任何尝试删除目标属性或修改属性特性(writable, configurable, enumerable)的行为将被无效化。所以通常属性都有特性时,可以把configurable设置为true即可。
    • writable 是否可写。设置成 false,则任何对该属性改写的操作都无效(但不会报错,严格模式下会报错),默认false。
    • enumerable。是否能在for-in循环中遍历出来或在Object.keys中列举出来。

Reflect.defineProperty(target, propertyKey, attributes)和以上Object.defineProperty类似,不过它返回一个Boolean值

Object.getOwnPropertyDescriptor()返回对象对应的属性描述符。

# # 案例:

    const object1 = {};
    Object.defineProperty(object1, 'property1', {
      value: 42,
      writable: false
    });
    
    object1.property1 = 77;
    // throws an error in strict mode
    
    console.log(object1.property1);
    // expected output: 42
    
1
2
3
4
5
6
7
8
9
10
11
12

# # 实际应用

  1. 代理:
    // old
    //加入有一个目标节点, 我们想设置其位移时是这样的
    var targetDom = document.getElementById('target');
    var transformText = 'translateX(' + 10 + 'px)';
    targetDom.style.webkitTransform = transformText;
    targetDom.style.transform = transformText;
    
    // new
    Object.defineProperty(dom, 'translateX', {
    set: function(value) {
             var transformText = 'translateX(' + value + 'px)';
            dom.style.webkitTransform = transformText;
            dom.style.transform = transformText;
    }
    //这样再后面调用的时候, 十分简单
    dom.translateX = 10;
    dom.translateX = -10;
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  1. express获取属性时警告内容
    [
      'json',
      'urlencoded',
      'bodyParser',
      'compress',
      ...
    ].forEach(function (name) {
      Object.defineProperty(exports, name, {
        get: function () {
          throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately.');
        },
        configurable: true
      });
    });
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# # 2.2 Object.defineProperties(obj, props)

该方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。

Object.getOwnPropertyDescriptors()ES8返回对象所有属性描述符。该方法引入目的是为了解决Object.assign()无法正确拷贝get属性和set属性的问题,详见此 (opens new window) (opens new window)

# # 3. Other

# # 3.1 Object.create(proto, [props])

根据已有的对象作为原型,创建新的对象。

    // Object.create polyfill
    Object.create = function(proto) {
      function F() {
        F.prototype = proto
      }
      return new F()
    }
    
1
2
3
4
5
6
7
8

# # 举例:

    const person = {
      isHuman: false,
      printIntroduction: function () {
        console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
      }
    };
    const me = Object.create(person);
    
    me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
    me.isHuman = true; // inherited properties can be overwritten
    me.printIntroduction();
    
    const myObject = Object.create(null)
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# # 思考题:为什么要有Object.create(null)?

Object.create(null)创建一个对象,但这个对象的原型链为null,即Fn.prototype = null

    let a = null
    let b = Object.create(null) // 返回纯{}对象,无prototype
    let c = {}
    let d = Object.create({})
    
    a.attr // throw error
    a.__proto__ // throw error
    
    b // {}
    b.attr // undefined
    b.__proto__ // undefined
    b.toString() // throw error
    
    // d表现与c一致,毕竟只是多嵌套了一层原型链
    c // { __proto__: {constructor: ƒ, ...} }
    c.attr // undefined
    c.__proto__ // {constructor: ƒ, ...}
    c.toString() // "[object Object]"
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

需要Object.create(null)的时候:

  • 需要一个非常干净且高度可定制的对象当作数据字典的时候
  • 不考虑for in到原型链的属性(与Object.keys()等效)

所以绝大部分时候是直接使用{}

# # 3.2 Object.assign(target, ...sources)ES6

该方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。(翻看源码能知道,它是一层浅拷贝)

# # 3.3 Object.is(value1, value2)ES6

该方法判断两个值是否是相同的值。

解决ES5中只有===和==判断的不足Equality comparisons and sameness (opens new window) (opens new window)

# # 3.4 Object.freeze(obj)Stage 1

该方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。该方法返回被冻结的对象。目前该方法在tc39 Stage1阶段,兼容性需要看后续发展。

Object.isFrozen(obj)判断一个对象是否被冻结

# # 3.5 对象的扩展

    // 对象属性简写
    const foo = 'bar';
    const baz = {foo}; // 等价于{ foo: foo }
    
    // 对象方法简写
    const baz1 = {
      func1() {}, // 等价于 func1: function() {}
      foo
    };
    
1
2
3
4
5
6
7
8
9
10

# # 参考文档:

  • MDN Object (opens new window) (opens new window)

  • tc39 finished-proposals (opens new window) (opens new window)

  • Equality comparisons and sameness (opens new window) (opens new window)

编辑 (opens new window)
ES6-解构赋值及原理
ES6-模块详解

← ES6-解构赋值及原理 ES6-模块详解→

最近更新
01
theme-vdoing-blog博客静态编译问题
09-16
02
搜索引擎
07-19
03
友情链接
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式