1. 介紹:闡述 Object 對象。javascript
2. 構造函數:介紹 Object 對象的構造函數。html
3. 實例屬性:介紹 Object 對象的實例屬性:prototype、constructor等等。java
4. 實例方法:介紹 Object 對象的實例方法: hasOwnProperty、isPrototypeOf、propertyIsEnumerable等等。數組
5. 靜態方法:介紹 Object 對象的靜態方法:Object.create()、Object.defineProperties()等等。app
6. 屬性描述符:介紹屬性描述符的類別:數據屬性與訪問器屬性。函數
Object對象,是全部JavaScript對象的超類(基類)。Object.prototype(Obecjt的原型)定義了Js對象的基本方法和屬性。this
參數:spa
①value {number | bool | string} :一個數字、布爾值或者字符串prototype
返回值:code
{Number、Boolean、String} 返回一個轉換後的對象
示例 :
1
2
3
4
5
6
|
var
o =
new
Object(123);
console.log(o);
// => Number對象
o =
new
Object(
true
);
console.log(o);
// => Boolean對象
o =
new
Object(
'abc'
);
console.log(o);
// => String對象
|
說明:
1) 賦值時,對象繼承新原型的全部方法和屬性,以及新原型的原型鏈中的全部方法和屬性。
2) 屬性名稱以兩個下劃線開始和結束。
3) 對象的__proto__ == 對象類的prototype
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// 1.自定義對象多層繼承
function
People(name) {
this
.name = name;
}
function
Student(age) {
this
.age = age;
}
Student.prototype =
new
People();
// 設置Student的原型爲People對象
var
s =
new
Student(22);
console.log(s.__proto__);
// => People 對象
console.log(Student.prototype);
// => People 對象
console.log(s.__proto__ == Student.prototype);
// => true
// 2.對象直接量
var
p = {};
// 等於new Object()
console.log(p.__proto__ == Object.prototype);
// => true
|
說明:
1) prototype爲對象類的屬性。__proto__是對象的屬性。
2) Js內置對象(Array、Date等對象)都有一個只讀的prototype屬性。 可將屬性和方法添加到原型中,但不能爲內置對象分配其餘原型。
3) 自定義對象的prototype屬性可進行讀寫操做。
示例:
1
2
3
4
5
6
7
8
9
10
|
var
Student =
function
(name) {
this
.name = name;
};
// 給Student的原型添加一個sayHello方法
Student.prototype.sayHello =
function
() {
alert(
'Hello,'
+
this
.name);
}
var
st =
new
Student(
'張三'
);
// 初始化對象st
console.log(st.name);
// => 張三
st.sayHello();
// 彈出:Hello,張三
|
說明:
1) 設置或返回建立此對象的構造函數。
2) 若一個對象有多層繼承,將返回最早調用的構造函數。
3) obj.constructor.prototype 可表示對象的原型。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 1.內置對象
var
str =
'abc'
;
console.log(str.constructor);
// => function String 構造函數
var
o = {};
console.log(o.constructor);
// => function Object 構造函數
// 2.自定義對象多層繼承 :constructor返回最早調用的構造函數
function
People(name) {
this
.name = name;
// s對象初始化時,先調用People構造函數,再調用Student構造函數
console.log(
'People調用'
);
}
function
Student(age) {
this
.age = age;
console.log(
'Student調用'
);
}
Student.prototype =
new
People();
// 設置Student的原型爲People對象
var
s =
new
Student(22);
console.log(s.constructor);
// => function People 構造函數
|
說明:
1) 對象的__proto__ 等於 類的prototype
2) 對象的constructor 等於 類,因此obj.constructor.prototype 可表示對象的原型。
示例:
1
2
3
4
|
var
o = {};
console.log(o.__proto__ === Object.prototype);
// true :對象的__proto__等於類的prototype
console.log(o.constructor === Object);
// true :對象的constructor 等於 類
console.log(o.constructor.prototype === Object.prototype);
// true :o.constructor.prototype 可表示對象的原型。
|
參數:
①propertyName {string} :屬性名稱。
返回值:
{bool} 判斷對象是否擁有一個指定名稱的本地定義(非繼承)的屬性;此方法不會檢查對象原型鏈中的屬性。
true :屬性爲對象的實例屬性,非繼承。
false :屬性不爲對象的實例屬性。
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 1.Object對象
var
o =
new
Object();
o.name =
'自定義屬性'
;
// 定義一個實例屬性
console.log(o.hasOwnProperty(
'name'
));
// => true:name屬性爲實例o本身定義的,而非繼承
console.log(o.hasOwnProperty(
'toString'
));
// => false:toString爲繼承屬性
// 2.自定義對象
var
Student =
function
(name) {
this
.name = name;
};
// 給Student的原型添加一個sayHello方法
Student.prototype.sayHello =
function
() {
alert(
'Hello,'
+
this
.name);
}
// 給Student的原型添加一個age屬性
Student.prototype.age =
''
;
var
st =
new
Student(
'張三'
);
// 初始化對象st
console.log(st.hasOwnProperty(
'name'
));
// => true :調用構造函數時,經過this.name附加到實例對象上
console.log(st.hasOwnProperty(
'sayHello'
));
// => false :sayHello方法爲原型上的成員
console.log(st.hasOwnProperty(
'age'
));
// => false :age屬性爲原型上的成員
|
語法:
prototype.isPrototypeOf(object)
參數:
①obejct {object} :被檢測的對象。
返回值:
{bool} 返回某個原型是否出如今對象的原型鏈中
true :是
false :不是
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 1.Obejct對象
var
o =
new
Object();
console.log(Object.prototype.isPrototypeOf(o));
// => true :o爲Obejct一個對象
// 2.Array
var
array = [1, 2, 3];
console.log(Array.prototype.isPrototypeOf(array));
// => true :數組原型
console.log(Object.prototype.isPrototypeOf(array));
// => true :Object是全部對象的基原型
// 3.自定義對象
var
People =
function
() {
}
var
Student =
function
() {
}
// 設置Student類的原型爲People
Student.prototype =
new
People();
var
st =
new
Student();
console.log(Student.prototype.isPrototypeOf(st));
// => true :st爲Student一個對象
console.log(People.prototype.isPrototypeOf(st));
// => true :Student的原型爲People
console.log(Object.prototype.isPrototypeOf(st));
// =>true :Object是全部對象的基原型
|
參數:
①propertyName {string} :屬性名稱
返回值:
{bool} 判斷屬性是否爲實例屬性而且是可枚舉的(可用for/in循環枚舉),不考慮原型鏈中的成員。
true :是
false :不是
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 1.Array對象
var
array = [1, 2, 3];
array.name =
'Array'
;
console.log(array.propertyIsEnumerable(
'name'
));
// => true :name屬性爲實例屬性
console.log(array.propertyIsEnumerable(
'join'
));
// => false :join方法繼承自Array
console.log(array.propertyIsEnumerable(
'length'
));
// => false :length屬性繼承自Array
console.log(array.propertyIsEnumerable(
'toString'
));
// => false :toString方法繼承自Object
// 2.自定義對象
var
Student =
function
(name) {
this
.name = name;
}
// 定義一個原型方法
Student.prototype.sayHello =
function
() {
alert(
'Hello'
+
this
.name);
};
var
a =
new
Student(
'tom'
);
console.log(a.propertyIsEnumerable(
'name'
));
// => true :name爲自身定義的實例屬性
console.log(a.propertyIsEnumerable(
'age'
));
// => false :age屬性不存在,也返回false
console.log(a.propertyIsEnumerable(
'sayHello'
));
// => false :sayHello屬於原型方法
|
參數:無
返回值:
{object} 返回當前對象關聯的原始值,若沒有相關聯的值,則返回對象自己
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
var
a = [1, 2, 3];
console.log(a.valueOf());
// => [1, 2, 3]
var
b =
true
;
console.log(b.valueOf());
// => true
var
c = {};
console.log(c.valueOf());
// => Object {}
var
s =
'abc'
;
console.log(s.valueOf());
// => abc
// 自定義個對象,重寫valueOf
var
customObject = {};
customObject.valueOf =
function
() {
return
'自定義對象'
;
}
console.log(customObject.valueOf());
// => 自定義對象
|
參數:
①prototype {prototype} :返回對象的原型,能夠爲null。若爲null,對象的原型爲undefined。
②propertyDescriptor {propertyDescriptor} 可選:屬性描述符。
屬性描述符:設置屬性的一系列特性;
語法格式:
1
2
3
4
5
6
|
propertyName: {
value:
''
,
// 設置此屬性的值
writable:
true
,
// 設置此屬性是否可寫入;默認爲false:只讀
enumerable:
true
,
// 設置此屬性是否可枚舉(經過for/in預付);默認爲false:不可枚舉
configurable:
true
// 設置此屬性是否可配置;如:是否能夠修改屬性的特性及刪除屬性。默認爲false
}
|
返回值:
{object} 返回一個指定原型和指定屬性的對象
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 創建個自定義對象,設置name和age屬性
var
obj = Object.create(
null
, {
name: {
value:
'tom'
,
writable:
true
,
enumerable:
true
,
configurable:
true
},
age: {
value: 22
}
});
console.log(obj.name);
// => tom
console.log(obj.age);
// => 22
obj.age = 28;
console.log(obj.age);
// => 22 :age屬性的writable默認爲false,此屬性爲只讀
for
(p
in
obj) {
console.log(p);
// => name :只輸出name屬性;age屬性的enumerable默認爲false,不能經過for/in 枚舉
}
|
參數:
①object {object} :對象
②propertyDescriptor {propertyDescriptor} 屬性描述符。
說明:
若對象包含此屬性,則是修改此屬性的特性;不然爲爲對象添加此屬性。
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
var
obj = {};
// 爲對象添加name和age屬性
Object.defineProperties(obj, {
name: {
value:
'tom'
,
enumerable:
true
},
age: {
value: 22,
enumerable:
true
}
});
for
(p
in
obj) {
console.log(p);
// => name、age :輸出name和age屬性
}
|
參數:
①object {object} :對象
②propertyName {string} :屬性的名稱
③propertyDescriptor {propertyDescriptor} 屬性描述符。
說明 :
若對象包含此屬性,則是修改此屬性的特性;不然爲添加此屬性。
示例:
1
2
3
4
5
6
7
8
9
10
|
var
obj = {};
// 添加一個name屬性
Object.defineProperty(obj,
'name'
, {
value:
'tom'
,
writable:
true
,
enumerable:
true
,
configurable:
true
}
);
console.log(obj.name);
// => tom :輸出name屬性的value的值
|
參數:
①object {object} :對象
說明 :
1) 此操做不可逆,凍結後沒法進行解封。
2) 隻影響實例屬性,不影響原型屬性。
示例:
1
2
3
4
5
6
7
8
9
10
|
var
obj = {
name:
'tom'
,
age: 22
};
Object.freeze(obj);
// 凍結對象
obj.email =
'123@qq.com'
;
console.log(obj.email);
// undefined :沒法添加屬性
obj.age = 25;
console.log(obj.age);
// 22 :沒法設置屬性的值
|
參數:
①object {object} :對象
②propertyName {propertyName} 屬性名稱
返回值:
{propertyDescriptor} 屬性描述符對象
示例 :
1
2
3
4
5
6
7
|
var
obj = {
name:
'tom'
,
age: 22
};
var
propertyDes = Object.getOwnPropertyDescriptor(obj,
'name'
);
console.log(propertyDes);
// => Object {value: "tom", writable: true, enumerable: true, configurable: true} :輸出描述符對象
|
參數:
①object {object} :對象
返回值:
{Array} 一個數組,包含對象的全部實例屬性和方法,不包含原型繼承的屬性和方法
示例 :
1
2
3
4
5
6
7
8
|
var
obj = {
name:
'tom'
,
age: 22,
sayHello:
function
() {
alert(
'Hello'
+
this
.name);
}
};
console.log(Object.getOwnPropertyNames(obj));
// => ["name", "age", "sayHello"] :返回對象的實例成員
|
參數:
①object {object} :對象
返回值:
{object} 返回原型對象
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 1.對象直接量
var
obj = {
name:
'tom'
,
age: 22,
sayHello:
function
() {
alert(
'Hello'
+
this
.name);
}
};
console.log(Object.getPrototypeOf(obj));
// => Object 對象:對象直接量的原型爲Object
// 2.自定義對象
var
People =
function
(name) {
this
.name = name;
};
var
p =
new
People(
'tom'
);
var
people = Object.getPrototypeOf(p);
console.log(people);
// => People 對象:new 建立的對象使用構造函數的prototype屬性做爲他們的原型
console.log(Object.getPrototypeOf(people));
// => Object 對象:原型People的原型爲Object
|
參數:
①object {object} :對象
返回值:
{Array} 返回一個數組,包含對象可枚舉的實例屬性名稱
說明:
此方法與getOwnPropertyNames()相似,但getOwnPropertyNames()包含了可枚舉和不可枚舉的成員
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var
obj = {
name:
'tom'
,
age: 22,
sayHello:
function
() {
alert(
'Hello'
+
this
.name);
}
};
// 1)getOwnPropertyNames與keys方法返回的內容都相同
console.log(Object.getOwnPropertyNames(obj));
// => ["name", "age", "sayHello"] :返回對象的全部實例成員
console.log(Object.keys(obj));
// => ["name", "age", "sayHello"] :返回對象的全部可枚舉成員
// 設置對象的name屬性不可枚舉
Object.defineProperty(obj,
'name'
, {
enumerable:
false
}
);
// 2)keys方法,只包含可枚舉成員
console.log(Object.getOwnPropertyNames(obj));
// => ["name", "age", "sayHello"] :返回對象的全部實例成員
console.log(Object.keys(obj));
// => ["age", "sayHello"] :返回對象的全部可枚舉成員
|
參數:
①object {object} :對象
返回值:
{object} 返回此對象
示例 :
1
2
3
4
5
6
7
|
var
obj = {
name:
'tom'
,
age: 22
};
Object.preventExtensions(obj);
// 設置對象不能添加新的屬性
obj.email =
'123@qq.com'
;
console.log(obj.email);
// => undefined :沒法向對象添加新的屬性
|
參數:
①object {object} :對象
返回值:
{object} 返回此對象
示例 :
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var
obj = {
name:
'tom'
,
age: 22
};
Object.seal(obj);
// 密封對象
obj.email =
'123@qq.com'
;
console.log(obj.email);
// => undefined :沒法向對象添加新的屬性
// 報異常:沒法修改對象屬性的特性
Object.defineProperty(obj,
'name'
, {
enumerable:
false
}
);
|
分爲數據屬性和訪問器屬性;
二者可相互轉換,若轉換後未設置enumerable和configurable特性(兩類屬性描述符都包含這2個特性),將默認採用轉換前的值。
說明:包含屬性的操做特性;如:設置值、是否可枚舉等等
特性名稱 | 描述 | 默認值 |
value | 設置屬性的值 | undefined |
writable | 是否可修改屬性的值;true:可修改屬性的值;false:不可修改屬性的值 | false |
enumerable | 是否可枚舉屬性;true:可枚舉,可經過for/in語句枚舉屬性;false:不可枚舉 | false |
configurable | 是否可修改屬性的特性;true:可修改屬性的特性(如把writable從false改成true);false:不可修改屬性的特性 | false |
默認值:
1)在使用Object.defineProperty、Object.defineProperties 或 Object.create 函數的狀況下添加數據屬性,writable、enumerable和configurable默認值爲false。
2)使用對象直接量建立的屬性,writable、enumerable和configurable特性默認爲true。
示例:
1
2
3
4
5
6
7
8
9
10
11
|
// 1)對象直接量;屬性特性默認爲true
var
o1 = {
name:
'tom'
};
console.log(Object.getOwnPropertyDescriptor(o1,
'name'
));
// => Object {value: "tom", writable: true, enumerable: true, configurable: true}
// 2)經過Object.create建立,屬性特性默認爲false
var
o2 = Object.create(
null
, {
name: {value:
'tom'
}
});
console.log(Object.getOwnPropertyDescriptor(o2,
'name'
));
// => Object {value: "tom", writable: false, enumerable: false, configurable: false}
|
說明:設置屬性的訪問方式;set、get特性等
特性名稱 | 描述 | 默認值 |
get | 屬性的返回值函數 | undefined |
set | 屬性的設置值函數;含有一個賦值參數 | undefined |
enumerable | 是否可枚舉屬性;true:可枚舉,可經過for/in語句枚舉屬性;false:不可枚舉 | false |
configurable | 是否可修改屬性的特性;true:可修改屬性的特性(如把writable從false改成true);false:不可修改屬性的特性 | false |
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
var
obj = {};
// 添加一個屬性,並設置爲訪問器屬性
Object.defineProperty(obj,
"name"
, {
get:
function
() {
return
this
._name;
// get和set裏的變量不要使用屬性,如:屬性爲name,get和set用的是_name
},
set:
function
(x) {
if
(isNaN(x)) {
this
._name = x;
}
else
{
this
._name =
'name不能爲純數字'
;
}
},
enumerable:
true
,
configurable:
true
});
console.log(Object.getOwnPropertyDescriptor(obj,
'name'
));
// => Object {get: function, set: function, enumerable: true, configurable: true}
obj.name =
'12'
;
console.log(obj.name);
// => name不能爲純數字
|