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)属性的键值对数组。

     

  • 相关阅读:
    [面试题]去除字符串中相邻两个字符的重复
    [面试题]单向链表的倒序索引值?
    Android数据存储——文件读写操作(File)
    python操作Excel读写(使用xlrd和xlrt)
    在Ubuntu上安装qq2012客户端
    sharepoint 2010开发webpart(转)

    【Sharepoint 2007】WebPart开发、部署过程全记录(转)
    sharepoint2010最初的了解
    基于windows验证的moss2010站点登录域后还弹出对话框解决方法(转)
  • 原文地址:https://www.cnblogs.com/huansky/p/5670580.html
Copyright © 2011-2022 走看看