ES5的常用对象方法详解
ECMAScript 5 为 JavaScript 添加了大量新的对象方法,如下
阅读目录
- Object.defineProperty(object, property, descriptor) // 添加或更改对象属性
- Object.defineProperties(object, descriptors) // 添加或更改多个对象属性
- Object.keys(object) // 以数组返回所有可枚举的属性
- Object.freeze(object) // 防止对对象进行任何更改
- Object.isFrozen(object) // 如果对象被冻结,则返回 true
- Object.getOwnPropertyDescriptor(object, property) // 访问属性
- Object.getOwnPropertyNames(object) // 以数组返回所有属性
讲述下列对象方法之前,有必要先了解下对象属性相关的方法,有利于更能深刻的熟悉对象方法
对象属性描述符
概念:两种主要形式分贝为数据描述符和存取描述符;
数据描述符--是一个具有值的属性,该值可能是可写的,也可能不是可写的,包括configurable,enumerable,writable,value;
存取描述符--是由getter-setter函数对描述的属性,包括get和set方法,可以代替value和writable
注:属性描述符”对象只能在Object.defineProperty或Object.defineProperties中使用。
Object.defineProperty(object, property, descriptor)
概念:用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象
特点:使用Object.defineProperty()定义的属性,默认是不可以被修改,不可以被枚举,不可以被删除的,参考案例1;若要修改对象的属性,需要通过设置属性描述符可修改成功,参考案例2;
注:设置set或者get,就不能在设置value和wriable,否则会报错,参考案例3
案例1:
var obj = {}; Object.defineProperty(obj, 'name', { value: 'definePropertyTest' }); console.log('obj默认值:', obj); delete obj.name; console.log('obj删除后:', obj); console.log('obj枚举:', Object.keys(obj)); obj.name = 'definePropertyTest1'; console.log('obj修改后:', obj);
输出结果
案例2:
var obj = {}; Object.defineProperty(obj, 'name', { value: 'definePropertyTest', writable: true, // 可以被修改 enumerable: true, // 可以被枚举 configurable: true, // 可以被删除 }); console.log('obj默认值:', obj); console.log('obj枚举:', Object.keys(obj)); obj.name = 'definePropertyTest1'; console.log('obj修改后:', obj); delete obj.name; console.log('obj删除后:', obj);
输出结果
案例3:
var obj = {}; Object.defineProperty(obj, 'name', { // value: 'definePropertyTest', // writable: true, 放开注释则会报Invalid property descriptor. Cannot both specify accessors and a value or writable attribute enumerable: true, configurable: true, get: function () { console.log('get', this); return 'name ' + this.__name; }, set: function (newVal) { localStorage.setItem('name', newVal); console.log('set', newVal); this.__name = newVal; } }); console.log('obj默认值:', obj); obj.name = 'definePropertyTest'; console.log('obj枚举:', Object.keys(obj)); delete obj.name; console.log('obj删除后:', obj);
输出结果
Object.defineProperties(object, descriptors)
概念:在对象上定义多个新的属性或者修改多个原有属性,返回修改后的目标对象
特点:与Object.defineProperties()方法相同,区别为可以对多个属性进行定义和修改
案例:
var obj = {}; Object.defineProperties(obj, { name:{ enumerable: true, configurable: true, get: function () { return this.__name; }, set: function (newVal) { this.__name = 'definePropertyTest'; } }, age:{ enumerable: true, configurable: true, get: function () { return this.__age; }, set: function (newVal) { this.__age = '18'; } }, }); console.log('obj默认值:', obj); console.log('obj枚举:', Object.keys(obj)); obj.name = 'definePropertyTest1'; obj.age = 19; console.log('修改后:', obj); //set方法进行了拦截,无法修改 delete obj.name; delete obj.age; console.log('obj删除后:', obj); //无法删除
输出结果
Object.keys(object)
概念:返回对象的可枚举属性和方法,返回类型为数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致
注:在ES5里,如果此方法的参数不是对象(而是一个原始值),那么它会抛出 TypeError。在ES2015中,非对象的参数将被强制转换为一个对象
案例:
var obj = { key1:1,key2:2 } console.log(Object.keys(obj)) //['key1','key2'] //传入数组或字符串,返回索引 var arr = ['key1','key2']; var string = "key"; console.log(Object.keys(arr)) //["0","1"] console.log(Object.keys(string)) //["0","1","2"] //传入构造函数 返回空数组或者属性名 function TestObjectKey(name,age){ this.name = name; this.age = age; this.toString = function(){ return 'toString'; } } console.log(Object.keys(TestObjectKey)); //[] var key = new TestObjectKey("key1",18); console.log(Object.keys(key)); // ["name", "age", "toString"]
Object.freeze(object)
概念:冻结一个对象,返回和传入的参数相同的对象
特点:冻结的对象不能被修改,不能向对象添加新的属性,不能删除已有属性,不能修改属性的性质包括可枚举性、可配置性、可写性、以及不能修改已有属性的值,该对象的原型也不能修改
注:冻结对象不是常量对象(浅冻结)
案例:
const obj1 = { name:"freeze1" } Object.freeze(obj1); const obj2 = Object.freeze(obj1); console.log(obj1===obj2); //true 返回原来的对象 obj1.name = "freeze1"; console.log(obj1); //{name:"freeze1"} 冻结的对象不可更改 delete obj1.name console.log(obj1); //{name:"freeze1"} 冻结的对象不可删除 obj1.age = 18; console.log(obj1) //{name:"freeze1"} 冻结的对象不可添加属性 const obj3 = { internal:{} } Object.freeze(obj3); obj3.internal.name = "freeze3"; console.log(obj3) //{internal:{name:freeze3}} 冻结的对象不是常量对象-浅冻结 var arr = ["freeze"]; Object.freeze(arr); arr[1] = "freeze1"; console.log(arr) //冻结的数组不能修改,其它同对象
Object.isFrozen(object)
概念:返回给定对象是否冻结的Boolean
特点:一个对象默认是非冻结的,冻结的对象不可扩展,不可配置
案例:
var obj = {}; console.log(Object.isFrozen(obj)); //空对象默认是非冻结的 var obj1 = { name:'isFrozen' } console.log(Object.isFrozen(obj1)); //非空对象默认是非冻结的 var obj2 = Object.freeze(obj); console.log(Object.isFrozen(obj)); //true 冻结对象是冻结的 console.log(Object.isFrozen(obj2)); //true 冻结对象的拷贝也是冻结的
Object.getOwnPropertyDescriptor(object, property)
概念:返回指定对象上一个自有属性对应的属性描述符
案例:
var obj = {name:"getOwnPropertyDescriptor"} Object.getOwnPropertyDescriptor(obj,"name"); // { // value: "getOwnPropertyDescriptor", // writable: true, // enumerable: true // configurable:true // } var obj1 = {}; Object.defineProperty(obj1, "name", { value: "getOwnPropertyDescriptor", writable: false, enumerable: false }); Object.getOwnPropertyDescriptor(obj1, "name"); // { // value: "getOwnPropertyDescriptor", // writable: false, // enumerable: false, // configurable:false // }
Object.getOwnPropertyNames(object)
概念:返回一个由指定对象的所有自身属性的属性名组成的数组
案例:
var obj = {}; Object.getOwnPropertyNames(obj); //[] var arr = ["a","b","c"]; Object.getOwnPropertyNames(arr); //["0", "1", "2", "length"]
参考网站
https://segmentfault.com/a/1190000019446677