zoukankan      html  css  js  c++  java
  • es6学习笔记3--解构和对象

    1、解构

    在接收数据的地方(比如赋值的左边),解构使你使用模式去获取部分数据。

    下面的代码是解构的一个例子:

    let obj = { first: 'Jane', last: 'Doe' };
    let { first: f, last: l } = obj; // (A)
        // f = 'Jane'; l = 'Doe'

    在行 A 解构了 obj :通过左边的模式,运用赋值操作符(=)从里面获取数据,并将数据赋值给变量 f 和 l 。这些变量事先自动声明好,因为该行以 let 开始。

    也可以解构数组:

    let [x, y] = ['a', 'b']; // x = 'a'; y = 'b'

    解构可以用于下列情形:

    // Variable declarations:解构赋值不仅适用于var命令,也适用于let和const命令。
    let [x] = ['a'];
    const [x] = ['a'];
    var [x] = ['a'];
    
    // Assignments:
    [x] = ['a'];
    
    // Parameter definitions:
    function f([x]) { ··· }
    f(['a']);

    也可以在一个 for-of 循环中解构:

    // Handled like a variable declaration:
    for (let [k,v] of arr.entries()) ···
    
    // Handled like an assignment
    for ({name: n, age: a} of arr) ···

    (1)Rest解构赋值

    对象的Rest解构赋值用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性,分配到指定的对象上面。所有的键和它们的值,都会拷贝到新对象上面。

    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    x // 1
    y // 2
    z // { a: 3, b: 4 }

    上面代码中,变量z是Rest解构赋值所在的对象。它获取等号右边的所有尚未读取的键(ab),将它们和它们的值拷贝过来。

    由于Rest解构赋值要求等号右边是一个对象,所以如果等号右边是undefinednull,就会报错,因为它们无法转为对象。

    let { x, y, ...z } = null; // 运行时错误
    let { x, y, ...z } = undefined; // 运行时错误

    Rest解构赋值必须是最后一个参数,否则会报错。

    let { ...x, y, z } = obj; // 句法错误
    let { x, ...y, ...z } = obj; // 句法错误

    上面代码中,Rest解构赋值不是最后一个参数,所以会报错。

    圆括号问题

    解构赋值虽然很方便,但是解析起来并不容易。对于编译器来说,一个式子到底是模式,还是表达式,没有办法从一开始就知道,必须解析到(或解析不到)等号才能知道。

    由此带来的问题是,如果模式中出现圆括号怎么处理。ES6的规则是,只要有可能导致解构的歧义,就不得使用圆括号。

    • 变量声明语句中,不能带有圆括号。

    • 函数参数中,模式不能带有圆括号。

    • 赋值语句中,不能将整个模式,或嵌套模式中的一层,放在圆括号之中。

    用途:

    • 交换变量的值

    • 从函数返回多个值

    • 函数参数的定义

    • 提取JSON数据

    • 函数参数的默认值

    • 遍历Map结构

    • 输入模块的指定方法

    总结:

    • 如果解构不成功,变量的值就等于undefined

    • 不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

    • 解构赋值允许指定默认值。

    • 对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    • 默认值生效的条件是,对象的属性值严格等于undefined

    • 解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。由于undefinednull无法转为对象,所以对它们进行解构赋值,都会报错。

    2、新的对象字面量特性

    1、新的对象字面量特性

    方法定义:

    let obj = {
        myMethod(x, y) {
            ···
        }
    };

    属性值缩写:

    let first = 'Jane';
    let last = 'Doe';
    
    let obj = { first, last };
    // Same as:
    let obj = { first: first, last: last };

    计算属性键:

    let propKey = 'foo';
    let obj = {
        [propKey]: true,
        ['b'+'ar']: 123
    };

    这种新语法也可用于方法定义:

    let obj = {
        ['h'+'ello']() {
            return 'hi';
        }
    };
    console.log(obj.hello()); // hi

    计算属性键主要的应用场景就是使 symbol 成为属性键变得更加方便。

    2、Object 中的新方法

    Object 中最重要的新方法是 assign() 。习惯上,在 JavaScript 的世界中,这个函数叫做 extend() 。 Object.assign() 仅考虑自有(非继承)属性。

    let obj = { foo: 123 };
    Object.assign(obj, { bar: true });
    console.log(JSON.stringify(obj));
        // {"foo":123,"bar":true}

     常见用途:

    (1)为对象添加属性

    (2)为对象添加方法

    (3)克隆对象

    (4)合并多个对象

    (5)为属性指定默认值

    属性的遍历

    ES6一共有6种方法可以遍历对象的属性。

    (1)for...in

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

    (2)Object.keys(obj)

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

    (3)Object.getOwnPropertyNames(obj)

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

    (4)Object.getOwnPropertySymbols(obj)

    Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有Symbol属性。

    (5)Reflect.ownKeys(obj)

    Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。

    (6)Reflect.enumerate(obj)

    Reflect.enumerate返回一个Iterator对象,遍历对象自身的和继承的所有可枚举属性(不含Symbol属性),与for...in循环相同。

    以上的6种方法遍历对象的属性,都遵守同样的属性遍历的次序规则。

    • 首先遍历所有属性名为数值的属性,按照数字排序。
    • 其次遍历所有属性名为字符串的属性,按照生成时间排序。
    • 最后遍历所有属性名为Symbol值的属性,按照生成时间排序。

    注意,语言规范把索引定义为字符串键,当转换成无符号整数然后再转换回来,仍然是同样的字符串(同样也必须比232-1小,因此数组是有长度限制的)。这意味着规范把数组索引看作字符串键,甚至普通的对象都可以有数组索引:

    Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
    //['2', '10', 'b', 'a', Symbol()]

    __proto__属性,Object.setPrototypeOf(),Object.getPrototypeOf()

    (1)__proto__属性

    __proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括IE11)都部署了这个属性。

    在实现上,__proto__调用的是Object.prototype.__proto__。

    (2)Object.setPrototypeOf()

    Object.setPrototypeOf方法的作用与__proto__相同,用来设置一个对象的prototype对象。它是ES6正式推荐的设置原型对象的方法。

    // 格式
    Object.setPrototypeOf(object, prototype)
    
    // 用法
    var o = Object.setPrototypeOf({}, null);

    该方法等同于下面的函数。

    function (obj, proto) {
      obj.__proto__ = proto;
      return obj;
    }

    (3)Object.getPrototypeOf()

    该方法与setPrototypeOf方法配套,用于读取一个对象的prototype对象。

    Object.values(),Object.entries()

    Object.keys()

    ES5引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

    Object.values()

    Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

    Object.entries

    Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

     

  • 相关阅读:
    商贸通帐套隐藏方法
    固定资产打开提示:上年度数据未结转!
    ZOJ 2432 Greatest Common Increasing Subsequence
    POJ 1080 Human Gene Functions
    POJ 1088 滑雪
    POJ 1141 Brackets Sequence
    POJ 1050 To the Max
    HDOJ 1029 Ignatius and the Princess IV
    POJ 2247 Humble Numbers
    HDOJ 1181 变形课
  • 原文地址:https://www.cnblogs.com/huansky/p/5670580.html
Copyright © 2011-2022 走看看