ES6—对象

作者: 林之小记 | 来源:发表于2019-10-30 13:37 被阅读0次

    作者:米书林
    参考文章:《菜鸟教程》、《 ECMAScript 6 入门》(阮一峰)

    1.属性的简洁表示法

    简介:ES6允许对象的属性直接写变量,这时候属性名是变量名,属性值是变量值。

    let name = "小明",
        age = 12;
    let student = {name,age};
    console.log(student);  // {name: "小明", age: 12}
    // 相当于
    let student = {name:name,age:age};
    

    变量的值发生改变不会影响到对象,即上面修改age = 13,student.age仍然等于12

    2.方法的简洁表示法

    ES5中给对象定义方法,需要先定义一个函数,再把函数赋值给对象的属性;ES6可以把函数声明function去除,直接定义一个方法

    let sex = "男"
    let person = {
      name:"小明",
       age:12
    }
    let student = {
        ...person,
        sex,
        study(a){
            return `你好,我是${this.name},今年${this.age}岁,我正在学习${a}`
        }
    }
    console.log(student);  // {name: "小明", age: 12, sex: "男", study: ƒ}
    
    student.study("语文")    // "你好,我是小明,今年12岁,我正在学习语文"
    
    // 等同于
    let student = {
        name:"小明",
        age:12,
        sex:"男",
        study:function(a){
            return "你好,我是"+this.name+",今年"+this.age+"岁,我正在学习"+a;
        }
    }
    

    如果是Generator 函数,则要在前面加一个星号

    const obj = {
      * myGenerator() {
        yield 'hello world';
      }
    };
    //等同于
    const obj = {
      myGenerator: function* () {
        yield 'hello world';
      }
    };
    
    

    用途

    1.返回函数的结果
    function f(x, y) {
      return {x, y};
    }
    
    // 等同于
    
    function f(x, y) {
      return {x: x, y: y};
    }
    
    f(1, 2) // Object {x: 1, y: 2}
    
    2.CommonJS 模块输出一组变量
    let ms = {};
    
    function getItem (key) {
      return key in ms ? ms[key] : null;
    }
    
    function setItem (key, value) {
      ms[key] = value;
    }
    
    function clear () {
      ms = {};
    }
    
    module.exports = { getItem, setItem, clear };
    

    3.属性名表达器

    js属性表达的方式

    第一种:.
    第二种:[""]

    let obj = {name:"小明"};
    obj.name;    //  "小明"
    obj["name"]  // 小明
    

    属性名表达式

    简介:ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内

    const obj = {
     ["he"+"llo"](){
       return "Hi";
      }
    }
    obj.hello();  //"Hi"
    
    let lastWord = 'last word';
    
    const a = {
      'first word': 'hello',
      [lastWord]: 'world'
    };
    
    a['first word'] // "hello"
    a[lastWord] // "world"
    a['last word'] // "world"
    

    4.对象的拓展运算符

    1.解构赋值

    基本用法
    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 ,c:5};
    console.log(z); //   a: 3, b: 4 ,c:5
    
    注意事项:

    1.等号右边是一个对象

    let { ...a } = null;  // 报错
    let { ...a } = true;  // {}
    let { ...a } = undefined;  // 报错
    let { ...a } = NaN;   // {}
    let { ...a } = 1;   // {}
    let { ...a } = "12";   // {0: "1", 1: "2"}
    

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

    let { ...x, y, z } = { a:0,x: 1, y: 2, z: 3}; // 句法错误 Rest element must be last element
    let { x, ...y, ...z } = { a:0,x: 1, y: 2, z: 3}; // 句法错误  Rest element must be last element
    

    3.解构赋值的拷贝是浅拷贝

    let obj = {name:"张三",hobby:{h1:"篮球",h2:"排球"}}
    let {...obj1} = obj;
    obj.hobby.h1 = "乒乓球";
    obj1;
    // {name: "张三", hobby: {h1: "乒乓球", h2: "排球"}}
    

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

    let o1 = { a: 1 };
    let o2 = { b: 2 };
    o2.__proto__ = o1;
    let { ...o3 } = o2;
    o3 // { b: 2 }
    o3.a // undefined
    

    4.对象方法的name属性

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

    let obj = {
      name:"张三",
      smoking(){
        return `大家好,我是${this.name},我不会抽烟`
        }
    }
    obj.smoking.name  // "smoking"
    

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

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

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

    (new Function()).name // "anonymous"
    
    var doSomething = function() {
      // ...
    };
    doSomething.bind().name // "bound doSomething"
    

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

    const key1 = Symbol('description');
    const key2 = Symbol();
    let obj = {
      [key1]() {},
      [key2]() {},
    };
    obj[key1].name // "[description]"
    obj[key2].name // 
    

    属性的遍历

    (1)for...in

    遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)的key值

    (2)Object.keys(obj)

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

    (3)Object.getOwnPropertyNames(obj)

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

    (4)Object.getOwnPropertySymbols(obj)

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

    (5)Reflect.ownKeys(obj)

    遍历对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举,返回一个数组。

    let sy = Symbol("h");
    let obj = {name:"abc",[sy]:"dd",arr:[1,2,3],};
    
    // for...in遍历
    for(key in obj){
      console.log(key);
    }
    // name
    // arr
    
    Object.keys(obj)
    // ["name", "arr"]
    
    Object.getOwnPropertyNames(obj)
    // ["name", "arr"]
    
    Object.getOwnPropertySymbols(obj)
    // [Symbol(h)]
    
    Reflect.ownKeys(obj)
    // ["name", "arr", Symbol(h)]
    
    

    对象的super关键字

    this关键字指向函数所在的当前对象,super关键字指向当前对象的原型对象

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

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

    // 报错
    const obj = {
      foo: super.foo
    }
    
    // 报错
    const obj = {
      foo: () => super.foo
    }
    
    // 报错
    const obj = {
      foo: function () {
        return super.foo
      }
    }
    
    

    相关文章

      网友评论

        本文标题:ES6—对象

        本文链接:https://www.haomeiwen.com/subject/jkawvctx.html