资讯专栏INFORMATION COLUMN

JavaScript学习之Object(中)属性描述对象

AaronYuan / 2431人阅读

摘要:属性描述对象何为属性描述对象就是用来描述对象属性的对象,其作用就是规定了属性的行为,即拥有属性和方法一共有个控制属性的属性在介绍前必须先熟悉操作和访问属性描述对象的方法此方法用于获取自身继承的不行,也就是不能越级属性的属性描述对象,两个参数

属性描述对象 何为属性描述对象
就是用来描述对象属性的对象,其作用就是规定了属性的行为,即拥有属性和方法
一共有6个控制属性的属性;在介绍前必须先熟悉操作和访问属性描述对象的方法
Object.getOwnPropertyDescriptor()
此方法用于获取自身(继承的不行,也就是不能越级)属性的属性描述对象,两个参数,第一个参数是目标对象,
第二个参数是字符串,目标对象的属性名

```
var obj = {name : 123};
obj.getOwnPropertyDescriptor(obj, "name"); 
//{value: 123, writable: true, 
//enumerable: true, configurable: true}
```
Object.defineProperty(),Object.defineProperties()

Object.defineProperty()
Object.defineProperty(object, propertyName, attributesObject)用于设置一个属性的属性描述对象,
object:目标对象
propertyName:目标对象属性
attributesObject:要设置的属性描述对象

var obj = Object.defineProperty({}, "p", {
    value : "aaa",
    writable : false,
    enumerable : true,
    configurable : false,
})

Object.defineProperties()
Object.defineProperties()可以一次性设置多个属性的属性描述对象

var obj ={};
Object.defineProperties(obj1, {
    a : {value : 123},
    b : {value : 456, enumerable : true},
    })
console.log(obj);      //{b : 456, a : 123}

Object.prototype.propertyIsEnumerable()

Object.prototype.propertyIsEumerable(elem),作用为该属性是否可以枚举,填入一个字符串,(值为属性名),返回一个布尔值;这是一个实例方法

var obj = [1, 2];
obj.name = "arr";
obj.propertyIsEnumerable("name");     //true
obj.propertyIsEnumerable("length");   //false
obj.propertyIsEnumerable("0");        //true
6大元属性

能控制属性的属性称为元属性

value
设置该属性的属性值,默认值为undefined

var obj = Object.defineProperty({}, "p", {value : 123});
obj["p"];   //123

writable
表示属性值(value)外部能否直接赋值,writable是一个布尔值,默认值是true
在用defineProperty()设置属性时,writable默认值为fasle;同理enumerable,configurable也是如此

var obj = Object.defineProperty({}, "p", {value : 123});
Object.getOwnPropertyDescriptor(obj, "p");
//{ value: 123, writable: false, enumerable: false, configurable: false}

var obj1 = {p :123};
Object.getOwnPropertyDescriptor(obj1, "p");
//{ value: 123, writable: true, enumerable: true, configurable: true} 

如值为false,外部无法直接赋值改变

var obj = {a : 1};
Object.defineProperty(obj, "a", {writable : false});
obj.a = 2;
console.log(obj.a);  //1,严格模式下这么做会报错

enumerable
表示该属性是否可以枚举,即是否可以遍历默认是值为true,如值为false,则无法被for-in,JSON.stringify以及Object.keys()

var obj = {
    a : 1,
    b : 2,
    c : 3,
};
Object.defineProperty(obj, "a", {enumerable: false});
for(var i in obj) {
    console.log(i);
}
//b
//c

configurable
其值为布尔值,决定来是否可以修改属性描述对象,也就是当值为false时,enumerable,configurable,这两者不能再被修改,不然会报错:TypeError

注意点

writable只有当false改为true时会把错,由true改为false时不会报错

var obj = Object.defineProperty({}, "a", {
        value : 123,
        //writable : false,
        writable : true
        enumerable : true,
        configurable : false,
    });
    //Object.defineProperty(obj, "a", {writable : true}) 报错
    Object.defineProperty(obj, "a", {writable :false});  //可以修改

value值只有在writable和configurable至少一个为true时才能修改不然报错

configurable为false时则属性不能被删除

var obj = {
    a : 1,
    b : 2,
}; 
Object.defineProperty(obj, "b", {configurable : false});
delete obj.a;
delete obj.b;
console.log(obj);  //{b : 2}

get,set
get:取值,在对象取值时会跳用getter函数,默认值undefined,例如obj.a
set:存值,在对象赋值时会调用setter函数,默认值undefined,例如obj.a = 123;
注意点:当设置了set或者get元属性时,若设置了writable,或者设置value 属性,会报错:Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute,

var obj = Object.defineProperty({}, "a", {
        get : function () {
            return "getter"
        }
        set : function (value) {
            console.log(value);
        },

    })

写法2:

var obj = {
        get a() {
            return "getter";
        },
        set a(value) {
            console.log(value);
        }
    }
    obj.a = 123;

控制对象的状态
Object.preventExtensions:能删除修改旧属性,不能添加新属性
Object.seal:不能删除旧属性,但能赋值修改旧属性,不能添加新属性,相当于把configurable:false
Object.freeze:不能删除修改旧属性,不能添加新属性,相当于对象变为常量
        var obj1 = {a : 1};
        var obj2 = {a : 1};
        var obj3 = {a : 1};
        Object.preventExtensions(obj1);   //旧属性能删除,能修改属性对象value,能外部直接赋值
        //obj1.a = 2;
        //delete obj1.a;
        //Object.defineProperty(obj1, "a", {value : 3});
        //obj1.b = 2;                                      //新属性不能进行赋值
        //Object.defineProperty(obj1, "b", {value : 3});   //不能添加新的属性描述对象,会保错
        Object.seal(obj2);                //旧属性不能删除,能修改属性对象value,能外部直接赋值
        // obj2.a = 2;

        //delete obj2.a;
        // Object.defineProperty(obj2, "a", {value : 3});
        //obj2.b = 2;                                      //新属性不能进行赋值
        //Object.defineProperty(obj2, "b", {value : 3});   //不能添加的新属性描述对象,会保错
        Object.freeze(obj3);              //旧属性不能删除,不能修改属性对象value,不能外部直接赋值
        obj3.a = 2;

        //delete obj3.a;
        //Object.defineProperty(obj3, "a", {value : 3});
        //obj3.b = 2;                                      //新属性不能进行赋值
        //Object.defineProperty(obj3, "b", {value : 3});     //不能添加的新属性描述对象,会保错

注意点:

冻结的是对象自身的属性,但是可以通过给原型添加属性来实现

var obj = {a :1};
Object.freeze(obj);
console.log(obj.b);    //undefined
var obj0 = Object.getPrototypeOf(obj);
obj0.b = 2;
console.log(obj.b);    //2

当然我们可以冻结原型

var obj = {a :1};
Object.freeze(obj);
console.log(obj.b);              //undefined
var obj0 = Object.getPrototypeOf(obj);
Object.freeze(obj0);
obj0.b = 2;
console.log(obj.b);              //undefined

但是对于属性值为object类型的,我们冻结的是它的地址不变,但其内容还是可以变得

var obj = {a :{b : 1}};
Object.freeze(obj);
console.log(obj.a);              //{b : 1}
obj.a.b = 2;
console.log(obj.a);              //{b : 2}
obj.a.c = 3;
console.log(obj.a);              //{b : 2, c : 3}

三个检测是否冻结的方法

Object.isExtensible:能否为对象添加新属性
Object.isSealed:是否使用了Object.seal()
Object.isFrozen:是否使用了Object.freeze()

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98149.html

相关文章

  • JavaScript习之Object(下)相关方法

    摘要:它不区分该属性是对象自身的属性,还是继承的属性。那么我们要遍历对象所有属性,包括继承以及不可遍历的属性,用加原型遍历实现类似的用递归 Object静态方法 Object自身方法,必须由Object调用,实例对象并不能调用 Object.getPrototypeOf() 作用是获取目标对象的原型 function F() {}; var obj = new F(); console.lo...

    amuqiao 评论0 收藏0
  • Javascript习之继承

    摘要:继承是面向对象编程语言中的一个重要的概念,继承可以使得子类具有父类的属性和方法或者重新定义追加属性和方法等。但是在中没有类的概念,是基于原型的语言,所以这就意味着对象可以直接从其他对象继承。 继承是面向对象编程语言中的一个重要的概念,继承可以使得子类具有父类的属性和方法或者重新定义、追加属性和方法等。但是在Javascript中没有类的概念,是基于原型的语言,所以这就意味着对象可以直接...

    CHENGKANG 评论0 收藏0
  • JavaScript习之对象拷贝

    摘要:对象拷贝可遍历属性浅拷贝简单的浅拷贝可以用,对存取器定义的对象也试用深拷贝属性描述对象的拷贝这是个浅拷贝深拷贝不可遍历属性对象的拷贝例如拷贝获得共同的原型,与是兄弟关系说明也继承了原型,同级别简洁化版 对象拷贝 可遍历属性 浅拷贝 if(typeof Object.prototype.copy != function) { Object.prototype.copy = fun...

    Aklman 评论0 收藏0
  • JS习之Object

    摘要:文中的多为构造函数原型对象属性为函数的专属属性,表示函数的原型对象。关于各种数据类型的属性的展示对象的构造器函数该属性指向创建该对象原型的构造函数。对对象的冻结状态的设置和判断,前者让冻结对象,后者判断对象是否被冻结。 前言 上篇文章介绍了JS的对象,本文将介绍Object这个基类,主要介绍其属性和方法(其实这些在MDN里都有^_^,点击这里可以直通MDN)。好了废话不多说了,直接开始...

    qujian 评论0 收藏0
  • JavaScript习之Object(下)new命令

    摘要:命令作用作用是执行构造函数,返回实例对象上面例子是自定义一个构造函数,其最大的特点就是首字母大写,用执行构造函数其中,在的执行下,代表了实例化后的对象,这个也就有属性注意点如果不用执行构造函数,那么指向的是全局有两种方式可以避免内部定义严格 new命令 new作用 作用是执行构造函数,返回实例对象 function F() { this.name = object } var ...

    Salamander 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<