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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM