ECMA Script 6_对象的扩展

对象

1. ES6 允许直接写入变量和函数,作为对象的属性和方法

  • const foo = ‘bar‘;
    
    /*****************属性的优化********************/
    const baz = {foo: foo};
    
    // 优化为
    const baz = {foo};
    
    /*****************属性的优化********************/
    
    function f(x, y) {
      return {x: x, y: y};
    };
    
    // 优化为
    function f(x, y) {
        return {x, y};
    };
    
    f(1, 2);    // Object {x: 1, y: 2}
    
    /*****************方法的简化*******************/
    const o = {
        method: function() {
            return "Hello!";
        },
    };
    
    // 优化为
    const o = {
        method() {
            return "Hello!";
        },
    };

2. 对象动态添加属性

obj.name = ‘RyenToretto‘;

obj[‘age‘] = 22;

bind方法创造的函数,name 属性返回 ‘bound 原函数的名字‘

Function 构造函数创造的函数,name 属性返回 ‘anonymous‘

对象的方法是一个 Symbol 值,那么name属性返回的是这个 Symbol 值的描述

  • (new Function()).name // "anonymous"
    
    var doSomething = function() {
        // ...
    };
    doSomething.bind().name;     // "bound doSomething"
    
    /*****************************************************/
    const key1 = Symbol(‘description‘);
    const key2 = Symbol();
    let obj = {
      [key1]() {},
      [key2]() {},
    };
    obj[key1].name // "[description]"
    obj[key2].name // ""

3. 属性的可枚举性

对象的每个属性,都有一个属性描述对象,该对象有个 enumerable 控制属性是否可遍历

  • 有四个操作会忽略 enumerable 为 false 的属性,即不会遍历
  • for...in        只遍历对象自身的和继承的可枚举的属性。
  • Object.keys()        返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify()        只串行化对象自身的可枚举的属性。
  • Object.assign()        忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
  • ES6 规定,所有 Class 的原型的方法都是不可枚举的

Object.getOwnPropertyDescriptor(class {foo() {}}.prototype, ‘foo‘).enumerable    // false

4. ES6 一共有 5 种方法可以遍历对象的属性名

遍历次序:

首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。

for...in

循环遍历对象自身的继承的可枚举属性(不含 Symbol 属性)

Object.keys(obj)

返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名

Object.getOwnPropertyNames(obj)

返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名

Object.getOwnPropertySymbols(obj)

返回一个数组,包含对象自身的所有 Symbol 属性的键名

Reflect.ownKeys(obj)

包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举

5. super 关键字

ES6 又新增了另一个类似 this 的关键字 super,指向当前对象的原型对象

表示原型对象时只能用在对象的方法之中,用在其他地方都会报错

JavaScript 引擎内部

super.foo 等同于

  • Object.getPrototypeOf(this).foo(属性)
  • Object.getPrototypeOf(this).foo.call(this)(方法)
  • 目前,只有对象方法的简写法可以让 JavaScript 引擎确认定义的是对象的方法
  • const proto = {
        foo: ‘hello‘,
    };
    
    const obj = {
        foo: ‘world‘,
        find() {
            return super.foo;
       },
    };
    
    Object.setPrototypeOf(obj, proto);
    obj.find();    // "hello"

6. 对象的 扩展运算符 ...

回忆数组的 扩展运算符

  • const [a, ...b] = [1, 2, 3];    // 定义属性的新方式
    console.log(a);    // 1
    console.log(b);    // [2, 3]

如今对象的解构赋值

就是利用了 ...指定对象

解构赋值必须是最后一个参数,否则会报错。用于从一个对象取值,相当于将目标对

象自身的所有可遍历的(enumerable)但尚未被读取的属性和属性值,分配到 ...指定对象 上面。

所有的键和它们的值,都会拷贝到新对象上面

  • let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    console.log(x);    // 1
    console.log(y);    // 2
    console.log(z);    // { a: 3, b: 4 }

是浅拷贝,即 如果对象的某属性,是复合对象,则拷贝的只是一个引用地址而已

扩展运算符的解构赋值,不能复制继承自原型对象的属性

7. 对象的新增方法

Object.is() 

背景需求:

ES5 比较两个值是否相等,只有两个运算符:相等运算符(==严格相等运算符(===

它们都有缺点,== 会自动转换数据类型,=== NaN不等于自身,以及 +0 === -0

JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。

ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。

Object.is() 就是部署这个算法的新方法。

它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致

不同之处只有两个:    +0 不等于 -0    NaN 等于 NaN

  • +0 === -0    //true
    NaN === NaN    // false
    
    
    Object.is(+0, -0);    // false
    Object.is(NaN, NaN);    // true
    
    Object.is(‘foo‘, ‘foo‘);    // true
    Object.is({}, {});    // false

Object.assign()

用于对象属性的合并,将 多个源对象(source)的所有可枚举属性,复制到目标对象(target)

  • const target = { a: 1 };
    
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    console.log(target);     // {a:1, b:2, c:3}

只能进行值的复制,如果要复制的值是一个取值函数,那么会执行函数,再将返回值复制过去

如果是赋值的是非取值函数,则正常复制

  • const a = {
        foo(x, y){
            console.log(‘哈哈‘);
            return "呵呵";
        },
    };
    const b = {};
    Object.assign(b, a);
    
    console.dir(b);
    console.log(b.foo());
  • 如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性(处理方法是替换,而不是添加。)
  • const target = { a: 1, b: 1 };
    
    const source1 = { b: 2, c: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    console.log(target);    // {a:1, b:2, c:3}
  • 如果非对象参数出现在源对象的位置(即非首参数),那么这些参数都会转成对象,如果无法转成对象,就会跳过
  • let obj = {a: 1};
    Object.assign(obj, undefined) === obj     // true
    Object.assign(obj, null) === obj     // true
  • 字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果(undefined,null,number,boolean)
  • const v1 = ‘abc‘;
    const v2 = true;    // 被忽略
    const v3 = 10;    // 被忽略
    
    const obj = Object.assign({}, v1, v2, v3);
    console.log(obj);    // { "0": "a", "1": "b", "2": "c" }
  • 布尔值、数值、字符串分别转成对应的包装对象时

可以看到它们的原始值都在包装对象的内部属性[[PrimitiveValue]]上面,

这个 内部属性[[PrimitiveValue]] 属性是不会被 Object.assign() 拷贝的

  • Object(true);    // {[[PrimitiveValue]]: true}
    Object(10);     //  {[[PrimitiveValue]]: 10}
    Object(‘abc‘);    // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
  • 不拷贝 不可枚举的属性(enumerable: false)
  • 属性名为 Symbol 值的属性,也会被 Object.assign() 拷贝

注意:

Object.assign() 实行的是浅拷贝,而不是深拷贝。

也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用

  • Object.assign() 可以用来处理数组,但是会把数组视为对象
  • Object.assign([1, 2, 3], [4, 5]);    // [4, 5, 3]

常见用途

  • ① 为对象添加属性
  • class Point {
        constructor(x, y) {
            Object.assign(this, {x, y});    // 将 x 属性 和 y 属性 添加到 Point类 的对象实例
        };
    };
  • ② 为对象 添加方法
  • Object.assign(Point.prototype, {
        someMethod(arg1, arg2) {
            ···
        },
        anotherMethod() {
            ···
        },
    });
  • ③ 克隆对象
  • 只克隆 原始对象 本身的值
  • function clone(origin) {
        return Object.assign({}, origin);
    };
  • 克隆,并克隆其原型链
  • function clone(origin) {
        let originProto = Object.getPrototypeOf(origin);
        return Object.assign(Object.create(originProto), origin);
    };
  • ④ 合并多个对象
  • const merge = (target, ...sources) => Object.assign(target, ...sources);
    
    const newObj = merge({}, obj1, obj2, obj3);
  • ⑤ 为属性指定默认值
  • const DEFAULTS = {
        logLevel: 0,
        outputFormat: ‘html‘
    };
    
    function processContent(options) {
        options = Object.assign({}, DEFAULTS, options);
        console.log(options);
        // ...
    };
  • 注意,由于存在浅拷贝的问题
  • const DEFAULTS = {
        url: {
            host: ‘example.com‘,
            port: 7070
        },
    };
    
    processContent({ url: {port: 8000} })
    // {
    //   url: {port: 8000}    // 由于拷贝了整个对象,所以覆盖了原来的 url 对象,导致对象里的内容不一样
    // }

Object.getOwnPropertyDescriptors()

3

3

3

3

3

3

3

3

3

 NaN

原文地址:https://www.cnblogs.com/tianxiaxuange/p/10129032.html

时间: 2024-10-06 17:08:02

ECMA Script 6_对象的扩展的相关文章

ECMA Script 6_数值的扩展

1. 二进制 和 八进制 新的表示法 前缀 0b(或0B) 表示 二进制 前缀 0o(或 0O )表示 八进制 console.log(0b111110111 === 503); // true console.log(0o767 === 503); // true 如果要将 0b 和 0o 前缀的字符串数值 转为十进制,要使用 Number() 方法 2. Number.isFinite() 检查一个数值是否为有限的(finite),即 不是 Infinity 返回 true 只对数值有效 如

ECMA Script 6_函数的扩展

参数的默认值 ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面 函数不能有同名参数 参数初始化会形成一个单独作用域.实际执行的是 let a = 1; 参数默认值是惰性求值的 每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100 let x = 99; function foo(p = x + 1) { console.log(p); } foo(); // 100 x = 100; foo(); // 101 function log(x, y = 'World')

ECMA Script 6_异步编程之 Promise

Promise 对象 异步编程 方案,已同步的方式表达异步的代码,解决回调地狱的问题 比传统的解决方案——回调函数和事件——更合理和更强大 是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息. Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理 基本使用 const promise = new Promise(function(resolve, reject) { // ... s

JavaScript原生对象及扩展

转自:http://segmentfault.com/a/1190000002634958 内置对象与原生对象 内置(Build-in)对象与原生(Naitve)对象的区别在于:前者总是在引擎初始化阶段就被创建好的对象,是后者的一个子集:而后者包括了一些在运行过程中动态创建的对象. 原生对象(New后的对象) ECMA-262 把原生对象(native object)定义为“独立于宿主环境的 ECMAScript 实现提供的对象”.包括如下: Object.Function.Array.Stri

Java程序员的JavaScript学习笔记(11——jQuery-在“对象”层面扩展)

计划按如下顺序完成这篇笔记: 1.    理念. 2.    属性复制和继承. 3.    this/call/apply. 4.    闭包/getter/setter. 5.    prototype. 6.    面向对象模拟. 7.    jQuery基本机制. 8.    jQuery选择器. 9.    jQuery工具方法. 10.    jQuery-在"类"层面扩展. 11.    jQuery-在"对象"层面扩展. 12.    jQuery-扩

atitit.编程语言 类与对象的 扩展机制.doc

atitit.编程语言 类与对象的 扩展机制.doc 1.1. Java 下一代: 没有继承性的扩展1 1.2. 继承1 1.3. 使用cglib动态为Java类添加方法1 1.4. 工具类 1 1.5. Wrap 包装类  装饰器模式2 1.6. 扩展方法 (其实就是工具类的语法糖)2 1.7. Scala 的隐式转换2 1.8. 类别类.ExpandoMetaClass2 1.1. Java 下一代: 没有继承性的扩展 Groovy.Scala 和 Clojure 提供了许多扩展机制,但继承

js中String常用方法详解及String对象方法扩展

一.JavaScript 中 slice .substr 和 substring的区别: 1: String.slice(start,end): 一个新的字符串.包括字符串 stringObject 从 start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符. 2: String.substring(start,end) 这个就有点特别了,它是先从start,end里找出一个较小的值. 然后从字符串的开始位置算起,截取较小值位置和较大值位置之间的 字符串,截取出来的

ES6 常用总结——第三章(数组、函数、对象的扩展)

1.1. Array.from() Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map). 下面是一个类似数组的对象,Array.from将它转为真正的数组. let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3}; // ES5的写法var arr1 = [].slice.call(arrayLike);

关于数据库对象的扩展属性

今天有人问有没有办法查看表的注释,或查询所有表的注释.这里所说的表或表字段等的注释,其实是数据库对象的扩展属性.在MSSQL中,支持把一些注释性的内容放到数据库或数据库对象中,增强可读性,有助于日后的管理和维护工作.扩展属性的内容可以通过SSMS添加.修改或删除,也可以通过系统视图查询,通过执行相关的存储过程来维护. 创建一张测试表: IF OBJECT_ID(N'T8') IS NOT NULL BEGIN DROP TABLE T8 END GO CREATE TABLE T8 ( id I