一句話概括:JS對象是一組無序屬性的集合!
這裡的
key
可以是任何有效的 JavaScript 字元串,或者可以被轉換為字元串的任何類型,包括空字元串;而
value
可以是資料或者函數
在
JavaScript
中,所有的對象都是
Object
函數的執行個體
注意:這裡的是一個函數,而
Function.prototype
是一個數組!是不是很殘忍?(這打破了我們慣性思維的認為原型對象的
Array.prototype
就一定是
typeof
)
object
console.log(typeof Function.prototype); // function
console.log(typeof Array.prototype); // object
console.log(Array.isArray(Array.prototype)); // true
更多原型知識會在後面的系列文章中,敬請期待
其次是JS對象所處的記憶體空間,大多數小夥伴應該都知道對象是引用類型,是以是存儲在堆記憶體中,我們平時最常做的将一個對象指派給一個變量,其實是将對象在堆記憶體中的位址值指派給了這個變量。這也說明了JS中是按值傳遞而非引用
let per1 = {
name: 'mrkleo'
};
let per2 = per1;
console.log(per1 === per2); // true
這裡的
0xb2c8
就是堆記憶體配置設定給對象的位址值
文章的開頭就提到JS對象就是屬性的集合,那麼就少不了對屬性的掌握
屬性分兩種,一種是資料屬性,一種是通路器屬性
對于資料屬性,有四個特性
[[Configurable]],[[Enumerable]],[[Writable]],[[Value]]
,而對于通路器屬性則是将
[[Writable]],[[Value]]
取代為
[[Get]],[[Set]]
從字面上了解資料屬性的四個特性分别是:
- 可配置?
- 可枚舉?(for…in)
- 可寫?
- 值
就拿是否可寫
[[Writable]]
舉例:
let obj = {
name: 'leo'
};
Object.defineProperty(obj, 'name', {
configurable: true,
enumerable: true,
// 設定為隻讀
writable: false,
value: '我是預設值,不可修改'
});
obj.name = 'new leo'; // 修改屬性name
console.log(obj.name); // 我是預設值,不可修改
從字面上了解通路器屬性的四個特性分别是:
- 可配置?
- 可枚舉?(for…in)
-
:讀取屬性時調用的函數,預設值為undefined[[Get]]
-
:設定屬性時調用的函數,預設值為undefined[[Set]]
有兩種設定
Set
與
Get
的形式:
/*
第一種:直接在對象中書寫
*/
let skill = 'code';
let person = {
get skill() {
return skill;
},
set skill(value) {
skill = value;
}
}
console.log(person.skill); // code
person.skill = 'play the ball';
console.log(person.skill); // play the ball
/*
第二種:通過Object.defineProperty()定義
*/
let person = {
name: 'Mr.KLeo',
age: 20,
skill: 'code',
// 僞私有屬性 _hobby_
_hobby_: 'dance'
}
Object.defineProperty(person, 'hobby', {
get() {
return this._hobby_;
},
set(value) {
this._hobby_ = value;
}
})
console.log(person);
console.log(person.hobby); // 觸發get函數:dance
person.hobby = 'play the basketball'; // 觸發set函數修改
console.log(person.hobby); // 觸發get函數:play the basketball
這裡的
[[Get]]
與
[[Set]]
在後面學習Vue架構的資料綁定原理時起到了很大的作用,大家可以多熟悉這塊内容,這樣就可以更好的接納Vue
在ES6中新增
Map
與
Set
資料結構,他們的原型最終也是結束于
Object.Prototype
,并且對于
Map
而言,他和
Object
的差別在于可以存儲任意類型的屬性名,That’s awesome ~
更多關于JS的知識,持續更新…