這個部分要來學習的是關於物件(Object)的一些方法,那就開始吧!
MDN:
Object.create(): 指定其原型物件與屬性,創建一個新物件。
意思是我們可以透過這個語法指定(assign)一個新物件的原型物件,然後建立新物件。
而透過 Object.create 將原型物件指定(assign)給一個新的物件,也稱為 原型繼承
以下面這個例子來說:
var obj = {
name: 'Bill',
sayHi: function (){
console.log('Hello!');
}
}
var newObj = Object.create(obj);
console.log(newObj);
透過這個圖可以知道 obj 已作為 newObj 這個物件的原型物件。

但對於比較舊的瀏覽器而言, Object.create 也許是無法使用的,所以就必須透過其他方式解決。
而這個透過某段程式因應瀏覽器不支援的情況稱為polyfill
在 Understanding the weird parts 中對於因應這樣子的情況有著下列這段程式碼:
if (!Object.create) {
Object.create = function (o) {
if (arguments.length > 1) {
throw new Error('Object.create implementation only accepts the first parameter');
}
function F() {};
F.prototype = o;
return new F();
};
}
當瀏覽器不支援 Object.create 時,會符合條件判斷句並執行內容,而上述程式碼中的這段:
function F() {};
F.prototype = o;
就是透過建構式建立物件,達到跟 Object.create 一樣的用途
用在定義某個物件的特性和值,而且可以決定是否 可寫入(writable)、可配置(configurable)及可列舉(enumerable)。
關於 可寫入(writable)、可配置(configurable)及可列舉(enumerable) 則需要說明一下:
writable 從 false 改成 true ,但可以從 true改為 false
for...in )被取出來看看測試的例子:
一、 將 writable 改為 false:
var obj = {};
Object.defineProperty(obj,'name',{
value: 'Bill',
enumerable:true,
configurable:true,
writable:false,
})
obj.name = "Jack";
console.log(obj);
將物件改為不可寫入,可以看到 Jack 這個值無法被寫入 obj 物件

二、 將 configurable 改為 false:
var obj = {};
Object.defineProperty(obj,'name',{
value: 'Bill',
enumerable:true,
configurable:false,
writable:true,
})
// delete: 刪除特性
delete obj.name;
console.log(obj);
將物件設定為不可配置,可以看到 name 這個特性並沒有被刪除

三、 將 enumerable 改為 false:
var obj = {habbit: "Read books"};
Object.defineProperty(obj,'name',{
value: 'Bill',
enumerable:false,
configurable:true,
writable:true,
})
var prop = Object.keys(obj);
console.log(prop);
可以看到 name 這個特性並沒有被取出來(因為不可列舉)

直接來看測試的例子:
var obj = {};
Object.defineProperties(obj,{
'name':{
value: 'Bill',
writable:true
},
'habbit':{
value: 'Read books',
writable:true
}
});
console.log(obj);
可以看到同時新增了 name、habbit 特性到 obj 物件中。

false。hasOwnProperty() 不會檢查原型物件中是否有該特性,所以會回傳 false。true
來做些測試驗證看看:
var obj = {
sayHi: () => console.log('Hello!')
}
var obj2 = Object.create(obj);
obj2.habbit = 'Read books';
console.log(obj2);
console.log(`驗證 obj2 有沒有該特性: ${obj2.hasOwnProperty('habbit')}`);
console.log(`驗證 obj2 有沒有該特性: ${obj2.hasOwnProperty('sayHi')}`);
console.log(`驗證 obj2 有沒有該特性: ${obj2.hasOwnProperty('playball')}`);
console.log(obj2.hasOwnProperty('habbit')); 因為 obj2 中本來就有 habbit 這個特性,所以回傳 true
console.log(obj2.hasOwnProperty('sayHi')); 因為 sayHi 這個特性是存在於原型物件中,並非 obj2 本身自有的,所以回傳 false
console.log(obj2.hasOwnProperty('playball')); 因為 obj2 中沒有 playball 這個特性,所以回傳 false

再來測試關於不可列舉的特性,看看能否正常取出特性:
var obj = {};
//透過 `Object.defineProperty()` 設定一個不可列舉的特性
Object.defineProperty(obj,'name',{
value: 'Bill',
enumerable:false
})
console.log(`驗證 obj 能否取得不可列舉的特性: ${obj.hasOwnProperty('name')}`);

只會將物件中可列舉的特性回傳(這和 hasOwnProperty() 有些差別)。
來看一下測試的例子:
var obj = {
name: 'Bill',
habbit: 'Read books'
}
Object.defineProperty(obj,'weight',{
value: '65kg',
enumerable:false
})
console.log(`obj物件的 name 是否為可列舉特性: ${obj.propertyIsEnumerable('name')}`);
console.log(`obj物件的 habbit 是否為可列舉特性: ${obj.propertyIsEnumerable('habbit')}`);
console.log(`obj物件的 weight 是否為可列舉特性: ${obj.propertyIsEnumerable('weight')}`);
透過 Object.defineProperty() 設定一個不可列舉的特性 :weight,可以發現propertyIsEnumerable() 回傳 false ,代表為不可列舉的特性

關於物件的方法今天先告一段落,明天再來學習剩餘的部分
明天見~