JS中常用的API-Object篇

通過(guò)閱讀MDN,總結(jié)了一些關(guān)于Object的方法
    1. Object.defineProperty(obj, prop, descriptor)
      • 該方法會(huì)直接在一個(gè)對(duì)象上(obj)定義一個(gè)新屬性(prop),或者修改一個(gè)對(duì)象的現(xiàn)有屬性,并返回此對(duì)象。
      • params : obj - 要傳入的對(duì)象 ,prop - 要定義或修改的屬性 ,descriptor - 要定義或修改屬性的描述符
      • 關(guān)于descriptor中的get 和 set 總結(jié) - 訪問(wèn)屬性時(shí)調(diào)用get,屬性修改時(shí)調(diào)用set

關(guān)于descriptor(描述符):
- configurable:
當(dāng)且僅當(dāng)該屬性的 configurable 鍵值為 true 時(shí),該屬性的描述符才能夠被改變,同時(shí)該屬性也能從對(duì)應(yīng)的對(duì)象上被刪除。
默認(rèn)為 false。
- enumerable:
enumerable定義了對(duì)象的屬性是否可以在for...in循環(huán)Object.keys()中被枚舉。
默認(rèn)為 false。
- value:
該屬性對(duì)應(yīng)的值。可以是任何有效的 JavaScript 值(數(shù)值,對(duì)象,函數(shù)等)。
默認(rèn)為 undefined。
- writable:
當(dāng) writable 屬性設(shè)置為 false 時(shí),該屬性被稱(chēng)為“不可寫(xiě)的”。它不能被重新賦值。
默認(rèn)為 false。
- get
屬性的 getter 函數(shù),如果沒(méi)有 getter,則為 undefined。當(dāng)訪問(wèn)該屬性時(shí),會(huì)調(diào)用此函數(shù)。執(zhí)行時(shí)不傳入任何參數(shù),但是會(huì)傳入 this 對(duì)象(由于繼承關(guān)系,這里的this并不一定是定義該屬性的對(duì)象)。該函數(shù)的返回值會(huì)被用作屬性的值。
默認(rèn)為 undefined。
- set
屬性的 setter 函數(shù),如果沒(méi)有 setter,則為 undefined。當(dāng)屬性值被修改時(shí),會(huì)調(diào)用此函數(shù)。該方法接受一個(gè)參數(shù)(也就是被賦予的新值),會(huì)傳入賦值時(shí)的 this 對(duì)象。
默認(rèn)為 undefined。

下面以一道常見(jiàn)的面試題來(lái)當(dāng)作應(yīng)用:

var _default = 0;

Object.defineProperty(window,'a',{
    get(){
        return ++ _default; //get函數(shù)的返回值作為該屬性的值!
    }
})

//使瀏覽器打印 'you win '
if (a === 1 && a ===2 && a === 3) { 
    console.log('you win')
    console.log(window.a)
}
    1. Object.assign(target,...sources)
      • 該方法將...sources(即可以是多個(gè)對(duì)象源)中的可枚舉屬性添加到target(目標(biāo)對(duì)象)中。
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

console.log(target);// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);// expected output: Object { a: 1, b: 4, c: 5 }

細(xì)節(jié)點(diǎn)1:繼承屬性和不可枚舉屬性是不能拷貝的

const obj = Object.create({foo: 1}, { // foo 是個(gè)繼承屬性。
    bar: {
        value: 2  // bar 是個(gè)不可枚舉屬性。
    },
    baz: {
        value: 3,
        enumerable: true  // baz 是個(gè)自身可枚舉屬性。
    }
});

const copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }

細(xì)節(jié)點(diǎn)2:原始類(lèi)型會(huì)被包裝成對(duì)象

 const v1 = "abc";
const v2 = true;
const v3 = 10;
const v4 = Symbol("foo")

const obj = Object.assign({}, v1, null, v2, undefined, v3, v4);
// 原始類(lèi)型會(huì)被包裝,null 和 undefined 會(huì)被忽略。
// 注意,只有字符串的包裝對(duì)象才可能有自身可枚舉屬性。
console.log(obj); // { "0": "a", "1": "b", "2": "c" }
    1. Object.create(proto,[propertiesObject])
      • 方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的__ proto__。
      • params : proto- 新創(chuàng)建對(duì)象的原型對(duì)象,[propertiesObject] - 可選,需要傳入一個(gè)對(duì)象,參考Object.defineProperty中的描述符
      • return : 一個(gè)新對(duì)象,帶著指定的原型對(duì)象和屬性。

我們可以使用該方法,實(shí)現(xiàn)一個(gè)兼容所有瀏覽器的繼承方法(即寄生組合式繼承)。

function Parent(){
    this.x = 100;
}

parent.prototype.getX = function(){
    return this.x;
}

function Child(){
    //將parent中this.xxx的私有屬性拿到
    parent.call(this);
    this.y = 200;
}

//創(chuàng)建一個(gè)空對(duì)象x,并且把[OBJECT](這個(gè)值需要是一個(gè)對(duì)象)作為新對(duì)象的原型指向
Child.prototype = Object.create(parent.prototype)
Child.prototype.constructor = child;
Child.prototype.getY = function(){
    
}
    1. Object.entries(obj)
      • 該方法將對(duì)象轉(zhuǎn)換為數(shù)組,數(shù)組中存儲(chǔ)的是該對(duì)象可枚舉的屬性及其值
function Test() {
   this.a = 1;
   this.b = 2
}


Test.prototype.c = 3;

const test = new Test();

for (let k in test) {
   console.log(k, test[k]);
}

// for in 會(huì)把遍歷對(duì)象的原型上的自定義屬性也遍歷出來(lái)
// 將對(duì)象轉(zhuǎn)換成數(shù)組的形式 - >可迭代  [['a',1],['b',2]]

const testArr = Object.entries(test);  

for (let [k, val] of testArr) {
   console.log(k, val)
}

與之相對(duì)的方法為Object.fromEntries(),該方法把鍵值對(duì)列表轉(zhuǎn)換為對(duì)象,值得注意的是在將對(duì)象用Object.entries()轉(zhuǎn)換后,再用Object.fromEntires()轉(zhuǎn)換回來(lái),和原對(duì)象用的不是同一個(gè)引用地址

    1. Object.freeze(obj)
    • 凍結(jié)的對(duì)象不可修改、不可刪除、不可添加屬性,凍結(jié)后的原型不可修改。
    • 特別注意不論是Object.freeze()、Object.preventExtensions()、Objext.seal(),對(duì)對(duì)象的操作都是對(duì)屬性的第一層的操作,即淺凍結(jié),上面所說(shuō)凍結(jié)后的原型不可修改指的是不可重新賦值一個(gè)新的引用地址,我們是可以對(duì)原型上的屬性進(jìn)行操作的。
    • Object.defineProperty()同樣也不能對(duì)凍結(jié)后的對(duì)象進(jìn)行操作
    • 方法返回值與參數(shù)obj是同一引用地址

MDN中也有寫(xiě)了對(duì)象的深度凍結(jié)

Object.deepFreeze = function (o) {
// Object.keys() //不能拿到不能枚舉的屬性
    var _key = Object.getOwnPropertyNames(o)
    if (_key.length) {
        _key.forEach(function (k) {
            var _value = o[k];

            if (typeof _value === 'object' && _value !== null) {
                Object.deepFreeze(_value)
            }
        })
    }
    return Object.freeze(o);
}
    1. Objext.seal(obj)
      • 該方法對(duì)obj進(jìn)行密封(淺密封),obj被密封后,可修改,不可刪除,不可擴(kuò)展。
      • 該方法返回的是原對(duì)象的引用地址
  • 7 . Object.preventExtensions()

    • 返回的obj 可修改 可刪除 不可擴(kuò)展
    • Object.defineProperty() 也不能給其擴(kuò)展
  • 對(duì)比 freeze seal preventExtensions
    • freeze 不可修改 不可刪除 不可擴(kuò)展
    • seal 可修改 不可刪除 不可擴(kuò)展
    • preventExtensions 可修改 可刪除 不可擴(kuò)展
    • 當(dāng)obj = {} 并且 Object.preventExtensions(obj),Object.isFrozen(obj) Object.isSealed(obj)均返回true,原因是 當(dāng)是空對(duì)象且又不可擴(kuò)展時(shí) 也滿(mǎn)足它們的判斷條件
  • 8 . Object.keys(obj)

    • 方法會(huì)返回一個(gè)由obj自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性的排列順序和正常循環(huán)遍歷對(duì)象時(shí)的順序一致。
  • 9 . Object.getOwnPropertyNames(obj)

    • 返回一個(gè)數(shù)組,該數(shù)組對(duì)元素是 obj自身?yè)碛械拿杜e或不可枚舉屬性名稱(chēng)字符串。 數(shù)組中枚舉屬性的順序與通過(guò) for...in 循環(huán)迭代該對(duì)象屬性時(shí)一致。數(shù)組中不可枚舉屬性的順序未定義。
  • 10 . Object.prototype.hasOwnProperty(obj)

    • 方法會(huì)返回一個(gè)布爾值,指示對(duì)象自身屬性中是否具有指定的屬性(也就是,是否有指定的鍵)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容