欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JavaScript中的Object.defineProperty()函数

程序员文章站 2022-07-12 21:55:12
...

       花了一个半小时写的,请怀着一颗感恩的心阅读,谢谢!

       我在说明一个事物和概念时,喜欢先上代码看到效果,然后再解释概念。

       Object.defineProperty()函数可以给JavaScript对象增加属性。啊……,那以前的json对象不是本来就可以吗。为何还得搞出个这么复杂的函数来做这个事情。

一、代码部分(先上代码):

1、回顾一下json对象增加属性

如果没有问题,可以不看本段。

//定义一个对象

Var person = {};

//给对象增加一个属性

Person.age = 12;

Person.name = “张三疯”;

Person.isAdult =”未成年”;

 

Ok,没有问题。但是:

1)、思考一个问题,age属性的值应该是有个用有效范围的(如:0-150),但是,这样增加的属性没法限制age属性的取值范围

2)、如果age属性的变化,会引起其它属性的变化,即其它属性的值会随着age的变化而变化,这样没法很好控制,而且很容易控制不好。如以上属性isAdult的值,不能直接随便赋值,而是age的值变化后,isAdult 的值会跟着变化。

     

2、如何用 Object.defineProperty()函数给对象增加属性。

 

Var person = {};

Object.defineProperty(person ,"name",{

    value:"张三疯",

writable:true //属性name不能修改

});

Console.log(person.name);//张三疯

person.name = "隔壁老王"; //修改不成功

console.log(person.name);//张三

 

没想到吧,我们还可以让某些属性的值是只读的。

 

    3、如果用 Object.defineProperty()进行给对象增加属性,该属性的取值是可控的,而且会影响其它属性的变化。

  注意:以下代码中,在对象的定义中,写的是带下划线的:_age,而在defineProperty()函数里写的属性名是不带下划线的:age,外部使用该对象的属性时,用不带下划线的:


let person = {
    _age:12,
    isAdult:"未成年"
};
Object.defineProperty(person,"age",{
    get:function(){
        return this._age;
    },
    set:function(newValue){
        //此判断是限制属性的取值范围是0-150之间
        if(newValue<0 || newValue>150){
            return;
        }
        this._age = newValue;
        //此判断是 _age属性的值影响isAdult的值。
        if(this._age>=18){
            this.isAdult = "已成年";
        }else{
            this.isAdult = "未成年";
        }
    }
});

person.age = 16; //此句话会调用 set函数。
console.log(person.age);//此句话对调动get函数
console.log(person.isAdult);//未成年

person.age = 25; //此句话会调用 set函数。
console.log(person.age);//此句话对调动get函数
console.log(person.isAdult);//已成年

 

二、概念:

     1、普及一个概念,JavaScript的属性有三种类型(重点看前两点):

          1)、命名数据属性:拥有一个确定的值的属性。这也是最常见的属性。

          2)、命名访问器属性:通过getter和setter进行读取和赋值的属性(这是今天重点要说的)

          3)、内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性[[Prototype]],你不能直接访问这个属性,但可以通过Object.getPrototypeOf()方法间接的读取到它的值。虽然内部属性通常用一个双吕括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性

 

    2、Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。

    3、Object.defineProperty()函数的格式:

Object.defineProperty(obj, prop, desc)

参数:

Obj:表示增加属性的对象

Prop:属性名

Desc:属性描述符

   4、属性描述符

1)、概念:

 属性描述符,是对当前属性的描述(包括设置)。

如 以上代码:

Object.defineProperty(person ,"name",{

    value:"张三疯"

});

      中的value就表示name属性的值为 “张三疯”。

2)、属性描述分为:数据描述符和存取描述符,

            (1)、数据描述符有两个:value和writable

       (2)、存取描述符:是由一对 getter、setter 函数功能来描述的属性

3)、共有的描述符:

数据描述符和存取描述均具有以下描述符

Configrable,enumerable

4)、属性描述符的解释

Value: 属性的取值

Writable:属性是否可以修改

configurable描述属性是否配置,以及可否删除

enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中

get:针对命名访问器属性值的获取

Set:针对命名访问器属性值的修改

默认值:

属性名

默认值

Value

Undefined

Writable

False

configurable

False

enumerable

False

get

Undefined

Set

Undefined