Object.defineProperty()方法与Uncaught TypeError: Property description must be an object错误

一、背景原因

原文报错:

Uncaught TypeError: Property description must be an object: a
    at Function.defineProperties (<anonymous>)

未捕获的类型错误:属性描述必须是一个对象:。。。

背景:

        使用Object.defineProperty()方法时,不小心通过快捷键按倒了Object.defineProperties()方法。

原因:

         其实也就是Object.defineProperty()方法与Object.defineProperties()方法的用法差异。下面针对这2个方法说明下。

二、Object.defineProperty()

1、概述:

该静态方法用于给对象定义一个新的属性,或修改一个现有属性,其格式为:

Object.defineProperty(obj, prop, descriptor)

参数解析:

·obj:需要定义属性的对象、被操作对象;

·prop:需要定义或修改的属性名称,通常使用’’单引号括住;

·descriptor:要定义或修改的属性的描述符

方法返回值:所传入的对象obj,并且指定新增或修改的属性已经被操作完成。

2、简单代码示例:

 /** Object.defineProperty()的用法 **/
            //新建一个对象
            let person = {
                name:'刘亦菲',
                sex:'女'
            };

            //通过defineProperty方法对上述对象进行新属性age的插入
            Object.defineProperty(person, 'age',{
                value : '18'
            });

            //打印对象
            console.log(person);

3、结果呈现:

4、描述符:

1)描述符概念与作用:

·Object.defineProperty()允许精确的添加或修改对象上的属性。

·通过赋值添加的普通属性会在枚举属性时出现(例如for..in、Object.keys()等),它们的值可以被更改,也可以被删除;

·但是,当使用Object.defineProperty()操作属性时,属性的额外细节将会被修改,令其与默认值不同。通过该新增的属性在默认情况下,是不可写、不可枚举(即遍历等)、不可配置的。

·Object.defineProperty()使用[[defineOwnProperty]]内部方法,而不是[[Set]],即使属性已经存在,它也不会调用setter。

2)描述符类型:

对象中存在的属性描述符主要有两种类型:描述符只能是两种类型之一,不能同时为两者。

a、数据描述符;

        数据描述符是一个具有可写或不可写值的属性。

b、访问器描述符。

        访问器描述符是由getter/setter函数对描述的属性。

3)描述符可选键:

共享描述符:(即数据描述符、访问器描述符皆具备的键)

a、configurable:默认false

        ·用于指定属性的类型能否在数据属性、访问器属性之间更改;默认否。

        ·指定属性是否可被删除;默认否。

        ·指定其描述符的其他属性能否更改。默认否(当它是可写的数据描述符时,value键可以被改,writable可以改为false)

b、enumerable:默认false

        控制当前操作的属性,能否被枚举。当且仅当该属性在对象的属性枚举中出现时,值为true。

数据描述符特有键

a、value:默认undefined(未定义、未明确的)

        配置属性的值。可以是任何有效的js值(数字、对象、函数等)。

b、writable:默认false

        是否可写。需要配置与属性关联的值,可以使用赋值运算符更改,则为true。

访问器描述符特有键

a、get:默认undefined

        ·用于属性getter的函数,没有getter则为undefined

        ·访问该属性时,将不带参地调用此函数,并将this设置为通过该属性访问的对象。

        ·返回值将被用作该属性的值。

b、set:默认undefined

        ·用作属性setter的函数,没有setter则为undefined

        ·当属性被赋值时,将调用该函数,并带一个参数(需要赋予属性的值),并将this设置为通过该属性分配的对象。

5、描述符的要点:

        1)如果描述符没有value、writable、get和set键的任何一个,默认视为数据描述符。即如果你使用了Object.defineProperty()方法,操作一个对象,而不对描述符进行键配置。默认就是数据描述符。

        2)如果描述符同时具备两种类型的描述符键,则会抛出异常。(即同时具备了value\writable和get\set)。

        3)这些属性不一定是描述符本身的属性。继承的属性也会被考虑在内。为了确保这些默认值得到保留,你可以预先冻结描述符对象原型链中的现有对象,明确指定所有选项,或使用 Object.create(null) 指向 null

三、Object.defineProperties()

1、概述:

        这个函数的作用与描述符的概念,跟上面的Object.defineProperty()是一致的。唯一不同的是使用格式。可以理解为,Object.defineProperty()可以操作对象的一个属性,而Object.defineProperties()可以操作对象的多个属性。

2、格式:

Object.defineProperties(obj, props)

·obj:需要操作的对象;

·props:需要操作的属性组,可以是一个或多个

-- props的格式一般为map类型,如:

Object.defineProperties(obj, {
  property1: {
    value: true,
    writable: true,
  },
  property2: {
    value: "Hello",
    writable: false,
  },
  // ……
});

3、代码示例:同时演示键enumerable的作用(枚举)

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8 /">
        <title>数据代理</title>
        <script type="text/javascript" src=""></script>
    </head>
    <body>

        <script type="text/javascript">
            /** Object.defineProperty()的用法 **/
            //新建一个对象
            let person = {
                name:'刘亦菲',
                sex:'女'
            };

            //通过defineProperty方法对上述对象进行新属性age的插入
            Object.defineProperty(person, 'age',{
                value : 18
            });

            //打印对象
            console.log(person);

            /** Object.defineProperties()的用法 **/
            //新建一个对象
            let student = {
                name:'张柏芝',
                sex:'女'
            };

            //通过defineProperty方法对上述对象进行新属性age的插入
            Object.defineProperties(student,{
                'age':{
                    value:20,
                    enumerable:true
                },
                'adress':{
                    value:'五环'
                }
            });

            //打印对象
            console.log(student);
            //枚举测试:
            console.log('枚举测试:',Object.keys(student));

        </script>
    </body>
</html>

分析:

1)在页面展示中,不可被枚举的属性,会被似乎用浅粉色展示;

2)通过方法defineProperty()或defineProperties()所操作的属性(无论是新增或修改),皆被进行了从新定义(是否赋值、是否可配置、是否可枚举等)。

这就是这2个静态方法的作用。

  • 26
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值