如何建立一個“純淨”的物件
⭐️ 更多前端技術和知識點,搜尋訂閱號
JS 菌
訂閱
首先來看一段程式碼 ?
Object.prototype.log = ''
let obj = {
name: 'oli',
age: 12
}
for (const key in obj) {
console.log(key) // name age log
}
複製程式碼
假設 Object 的原型中有一個自定義的 log 屬性,我們用字面量語法定義 obj 物件,那麼使用 for-in 遍歷方法就會遍歷到這個 log 物件,為了只遍歷其自身的屬性,需要增加一層篩選
Object.prototype.log = ''
let obj = {
name: 'oli',
age: 12
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) { // 檢查是否是自身的屬性
console.log(key) // name age
}
}
複製程式碼
雖然這樣能夠避免列印原型上的屬性,但仍然比較麻煩 ?
接下來我們嘗試用 Object.create
方法來建立物件
Object.prototype.log = ''
let obj = Object.create(null) // 傳入 null 作為引數
obj.name = 'oli'
obj.age = 12
for (const key in obj) {
console.log(key)
}
複製程式碼
這樣就不會列印出原型上的屬性了
我們再來看下 Object.create
和字面量語法建立一個空物件有什麼區別
可以看到使用 create 方法並傳入 null 作為引數可以避免原型被繼承
字面量語法與
Object.create(Object.prototype)
是一樣的
那麼 create 方法到底做了什麼呢 ?
我們直接去看 MDN 有關這個方法的 polyfill
if (typeof Object.create !== "function") {
Object.create = function (proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object: ' + proto);
} else if (proto === null) {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
if (typeof propertiesObject != 'undefined') {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
}
+ function F() {}
+ F.prototype = proto;
+ return new F();
};
}
複製程式碼
重點看這裡,create 方法的內部建立了一個函式,這個函式的原型指向 proto 並返回通過 new 操作符建立的函式的例項
因此用 create 方法建立的新的物件擁有原型上的屬性也是正常了 ?
很多時候就像第一段程式碼一樣我們並不需要遍歷原型上的屬性和方法
使用 create 方法並傳入 null 就能避免列印出原型上的方法
或者手動將 __proto__
設定為 null
obj1 = {name: 'oli'}
obj1.__proto__ = null
複製程式碼
?
請關注我的訂閱號,不定期推送有關 JS 的技術文章,只談技術不談八卦 ?