ES5的常用对象方法详解

ECMAScript 5 为 JavaScript 添加了大量新的对象方法,如下

阅读目录

讲述下列对象方法之前,有必要先了解下对象属性相关的方法,有利于更能深刻的熟悉对象方法

对象属性描述符

概念:两种主要形式分贝为数据描述符和存取描述符;

         数据描述符--是一个具有值的属性,该值可能是可写的,也可能不是可写的,包括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

posted @ 2019-07-29 21:20  yaolan  阅读(1453)  评论(0编辑  收藏  举报