zoukankan      html  css  js  c++  java
  • es6对象扩展

    属性的简洁表示法

    ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

    let a = 'name'
    let obj = {a}
    console.log(obj)  // {a: "name"}
    

    上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量名, 属性值为变量的值。下面是另一个例子。

    方法也可以简写

    let obj = {
        fn(){
            console.log('aaa')
        }
    }
    
    

    属性名表达式

    JavaScript 定义对象的属性,有两种方法。

        let obj = {};
        obj.name = 1; // 第一种
        obj['a'+'b'] = 2; // 第二种
        console.log(obj) // {name:1,ab:2}
    

    上面代码的方法一是直接用标识符作为属性名(es5),方法二是用表达式作为属性名,这时要将表达式放在方括号之内(es6)。

    表达式也可以定义方法名

        let obj = {
            ['a'+'b'](){
                console.log('aaa')
            }
        }
      obj.ab() // aaa
    

    注意,属性名表达式与简洁表示法,不能同时使用,会报错。

    方法的name属性

    函数的name属性,返回函数名。对象方法也是函数,因此也有name属性。

    let obj = {
            fn(){}
        }
      console.log(obj.fn.name) // fn
    

    上面代码中,方法的name属性返回函数名(即方法名)。

    如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面,而是该方法的属性的描述对象的get和set属性上面,返回值是方法名前加上get和set。

    let obj = {
      get foo() {},
      set foo(x) {}
    };
    // console.log(obj.foo.name) // TypeError: Cannot read property 'name' of undefined
    let descriptor = Object.getOwnPropertyDescriptor(obj,'foo')
    console.log(descriptor.get.name) // get foo
    

    有两种特殊情况:bind方法创造的函数,name属性返回bound加上函数的名字;Function构造函数创造的函数,name属性返回

    function fn(){
    
    }
    console.log(fn.bind().name) // bound fn
    
    
    console.log(new Function().name) // anonymous
    

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

    let key = Symbol('name')
    let obj = {
      [key](){}
    }
    console.log(obj[key].name) // [name]
    

    属性的可枚举和遍历

    • 可枚举性

    对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象

    let obj = {
      name:'1'
    }
    let descriptor = Object.getOwnPropertyDescriptor(obj,'name')
    console.log(descriptor)  // {value: "1", writable: true, enumerable: true, configurable: true}
    

    描述对象的enumerable属性,称为可枚举性,如果该属性为false,就表示某些操作会忽略当前属性
    目前,有四个操作会忽略enumerable为false的属性

    • for...in 循环:只遍历对象自身的和继承的可枚举的属性
    • Object.keys():返回对象自身的所有可枚举属性的键名
    • JSON.stringify:只串行化自身的可枚举的属性
    • Object.assign():忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性

    这四个操作之中,前三个是 ES5 就有的,最后一个Object.assign()是 ES6 新增的。其中,只有for...in会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性。实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for...in操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for...in遍历到。

    属性的遍历

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

    • for...in :循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)
    • Object.keys(): 返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)的键名
    • Object.getOwnPropertyNames:返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
    let obj = {
      name:'1',
      age:11
    }
    console.log(Object.getOwnPropertyNames(obj)) // ["name", "age"]
    
    • Object.getOwnPropertySymbols:返回一个数组,包含对象自身的所有 Symbol 属性的键名。
    let name = Symbol('mm') 
    let obj = {
      [name](){},
      age:11
    }
    console.log(Object.getOwnPropertySymbols(obj)) // [Symbol(mm)]
    
    • Reflect.ownKeys(obj):返回一个数组,包含对象自身的所有键名,不管键名是Symbol或字符串,也不管是否可枚举
    let name = Symbol('mm') 
    let obj = {
      [name](){},
      age:11
    }
    console.log(Reflect.ownKeys(obj)) // ["age", Symbol(mm)]
    

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

    • 首先遍历所有数值减,按照竖直升序排列
    • 其次遍历所有字符串健,按照加入事件升序排列
    • 最后遍历所有Symbol键,按照加入时间排序

    super 关键字

    我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。

    const proto = {
      foo: 'hello'
    };
    
    const obj = {
      foo: 'world',
      find() {
        return super.foo;
      }
    };
    
    Object.setPrototypeOf(obj, proto);
    console.log(obj.find()) // "hello"
    

    上面代码中,对象obj.find()方法之中,通过super.foo引用了原型对象proto的foo属性。

    注意,super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。

    对象的扩展运算符

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

    let {a,...b} = {a:1,b:2,c:3,d:4}
    console.log(a,b)  // 1 {b: 2, c: 3, d: 4}
    

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

    注意,解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。

    let obj = {a:1,b:{c:2}}
    let {a,...x} = obj
    obj.b.c = 222;
    console.log(x)  // {b: {c: 222}}
    
  • 相关阅读:
    使用 ASP.NET Core 创建 Web API及链接sqlserver数据库
    SQLPrompt 最新版下载地址
    雷柏键鼠对码程序
    罗技无线鼠标接收器无法配对的详细解决办法
    Windows10安装NTP服务器
    查看udp端口及占用程序
    国人开发的api测试工具 ApiPost
    无法调用到appcode下的类
    Android 实时文件夹
    android 当ListView滚动时自动调用 onCheckedChanged 导致CheckBox 状态不停变化 的解决办法
  • 原文地址:https://www.cnblogs.com/mengxiangji/p/10708030.html
Copyright © 2011-2022 走看看