ES6--对象的扩展

本文详细介绍了ES6中对象的属性和方法简写、getter和setter访问器的使用、属性名表达式、方法的name属性、原生JS设置getter和setter、属性的可枚举性和遍历、super关键字以及扩展运算符在内存引用中的问题。内容涵盖了对象的创建、访问和操作的各种技巧,深入理解这些特性对于提升JavaScript编程能力至关重要。
摘要由CSDN通过智能技术生成

一、对象的属性、方法简写

1.属性的简写

           //es5
           var name = '赵';
           var obj = {
               name:name
           }
           console.log(obj);//{name: "赵"}
           //es6
           var name = '赵';
           var stu = {
               name
           }
           console.log(stu);//{name: "赵"}

2.方法的简写

           let a = 10;
           let b = 20;
           let stu = {
               //es5函数写法
               sleep:function(){

               },
               //es6函数写法
               eat(){
                   return{
                       a,b
                   }
               }
           }

二、setter、getter访问器

  • 对象里面的getter、setter访问器,这两个访问器是操作属性的,至于属性的可读可写,只读和getter、setter访问器有关。
  • getter访问器获取值,setter访问器是设置值
  • 对象中简写的方法不能当作构造函数来使用,会报错

1.针对属性获取或设置

    //对象里面的getter、setter访问器,这两个访问器是操作属性的
    //至于属性的可读可写,只读和getter、setter访问器有关
    //getter访问器获取值,setter访问器是设置值
    let person={
        init(){

        },
        get name(){
            console.log("获取name属性");
            return this._name;
        },
        set name(n){
            console.log("设置name属性");
            this._name=n;
        }
    }
    console.log(person);
    person.name="张三";
    console.log(person.name);
    //对象中简写的方法不能当作构造函数来使用,会报错
    new person.init(); 

在这里插入图片描述

2.对象获取值的方法二

  • 对象点属性
  • 对象[key](不只可以取值,还可以检测属性是否存在)
  • es6允许对象的属性可以是变量,变量添加[]----字面量解析
    //es6允许对象的属性可以是变量,变量添加[]----字面量解析
    let key="name";
    let obj1={
        [key]:'张三'
    }
    console.log(obj1);//{name: "张三"}
    console.log(obj1[key]);//张三

三、属性名表达式

对象的常规属性定义

           let o = {};
           o.age = 18;
           o['sex'] = '男';
           console.log(o);//{age: 18, sex: "男"}
  • 对象的属性可以以接入字面变量的方式定义。也就是对象的属性可以是变量,通过解析变量产生对象的属性。
           let person = "name";
           let per = "eat";
           //解析属性变量使用[]包变量
           let list = {
               [person]:'',
               [per](){
                   console.log('执行函数');//执行函数
               }
           }
           console.log(list);//{name: "", eat: ƒ}
           console.log(list[per]());//undefined
           //对象属性上的name属性,获取的是函数名称
           console.log(list[per].name);//eat
  • 对象属性上的name属性,获取的是函数名称。

四、方法的 name 属性

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

获取get、set访问器的name属性。

          let a = {
               set age(n){
                   this._age = n;
               },
               get age(){
                   return _age;
               }
           }
           console.log(a.age.name);//ReferenceError: _age is not defined
  • 会报错,get、set访问器的name属性不能直接获取。
  • 那么,怎样获取呢?
  • 如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面,而是该方法的属性的描述对象的get和set属性上面,返回值是方法名前加上get和set。
           //首先得获取整个访问器
           let descript = Object.getOwnPropertyDescriptor(a,'age');
           console.log(descript);//{get: ƒ, set: ƒ, enumerable: true, configurable: true}
           console.log(descript.set.name);//set age
           console.log(descript.get.name);//get age

在这里插入图片描述

五、使用原生js设置getter、setter访问器

设置多个属性

  • 设置get、set访问器不能配置value、writeable属性
    //设置get、set访问器不能配置value、writeable属性
    let obj={
        get sex(){return this._sex;},
        set sex(n){this._sex=n;}
    }
    Object.defineProperties(obj,{
        name:{
            enumerable:true,
            configurable:true,
            get:function(){
                return this._name;
            },
            set:function(n){
                this._name=n;
            },
        }
    });
    obj.name="张三";
    obj.sex="女";
    console.log(obj.name);
    console.log(obj.sex);
    console.log(obj);

在这里插入图片描述

设置单个属性

    let obj={
        get sex(){return this._sex;},
        set sex(n){this._sex=n;}
    }
    Object.defineProperty(obj,'age',{
        enumerable:false,
        configurable:true,
        get:function(){
            return this._age;
        },
        set:function(n){
            this._age=n;
        },
    });
    obj.sex="男";
    obj.age=10;
    console.log(obj);
    console.log(Object.getOwnPropertyDescriptor(obj,'age'));
    console.log(obj.age);
    console.log(obj.sex);

在这里插入图片描述

六、属性的可枚举性和遍历

  • 对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
  • Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
           let people = {
               name:"赵佳敏",
               age:20
           }
  • 获取people对象name属性的相关配置
           var desc = Object.getOwnPropertyDescriptor(people,'name');
           console.log(desc);//{value: "赵佳敏", writable: true, enumerable: true, configurable: true}
  • 设置对象属性的相关配置
           Object.defineProperty(people,'name',{
               enumerable:false
           });
           var desc1 = Object.getOwnPropertyDescriptor(people,'name');
           console.log(desc1);//{value: "赵佳敏", writable: true, enumerable: false, configurable: true}
  • defineProperty直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
  • 描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。
  • 有四个操作会忽略enumerable为false的属性
  • for…in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
  • Object.assign()是 ES6 新增的。其中,只有for…in会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性。实际上,引入“可枚举”(enumerable)这个概念的最初目的,就是让某些属性可以规避掉for…in操作,不然所有内部属性和方法都会被遍历到。比如,对象原型的toString方法,以及数组的length属性,就通过“可枚举性”,从而避免被for…in遍历到。
    for(let key in people){
        console.log(key);//age
    }
    //configurable 默认true,允许删除对象属性,false不允许
    console.log(delete people.age);//true
    console.log(people);//{name: "赵佳敏"} 
  • configurable----delete删除,是否可以删除对象属性,true可以删除,false不可删除
  • enumerable—是否可以枚举
  • writable----是否可写
  • ES6 规定,所有 Class 的原型的方法都是不可枚举的

七、属性的遍历

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

(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 或字符串,也不管是否可枚举。
  • 以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
  • 首先遍历所有数值键,按照数值升序排列。
  • 其次遍历所有字符串键,按照加入时间升序排列。
  • 最后遍历所有 Symbol 键,按照加入时间升序排列。
          //对对象的属性设置不可枚举,不能获取到
           let sw = {
               name:'zhao',
               age:10,
               sex:"女",
               [Symbol('age')](){
                   console.log('独一无二的方法');
               }
           }
           for(let key in sw){
               console.log(key);
           }

           //Object.keys();返回所有key集合
           console.log(Object.keys(sw));//["name", "age", "sex"]
           console.log(Object.getOwnPropertyNames(sw));//["name", "age", "sex"]
           //返回symbol数据类型的key值
           console.log(Object.getOwnPropertySymbols(sw));//[Symbol(age)]
    console.log(Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 }));//(5) ["2", "10", "b", "a", Symbol()]

八、super 关键字

  • 我们知道,this关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。
    let person={
        name(){
            console.log("全名称");
        },
    }
    let student={
        sleep(){
            console.log(this);
            super.name();
        }
    }
    //设置原型对象
    Object.setPrototypeOf(student,person);
    student.sleep();
    console.log(student);

在这里插入图片描述

九、扩展运算符—内存引用问题

    let a1={a:1};
    let {...x}=a1;
    a1.a=2;
    console.log(x.a);//1
    let a2={a:{b:1}};
    let {...x1}=a2;
    a2.a.b=2;
    console.log(x1.a.b);//2 
  • 首先是a1复制了一份给了x,是外部空间的引用空间链断了,所以a1改变以后对x没有影响,x1.a.b为2是因为外部空间引用链断了,但是内部引用链没有变,所以输出为2
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南初️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值