對象
JavaScript 提供多個內建對象,比如 Object、String、Date、Array 等等,此外 JavaScript 允許自定義對象。
對象:帶有屬性和方法的特殊數據類型。
1.創建 JavaScript 對象
1.1 通過new關鍵字創建對象
var obj = new Object();
// 添加屬性
obj.name = "小明";
// 添加方法
obj.sleep = function () {
console.log(this.name + "在睡覺");
};
1.2通過字面量創建對象
var obj = {
name : "xiaoming",
age : "18",
show : function (girlfriend) {
console.log(this.name + "的女朋友是" + girlfriend);
}
};
注意: 屬性名字可以加雙引號也可以不加雙引號。
1.3 通過構造函數創建對象
// 注意:此處建議方法名首字母大寫
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function(name) {
console.log("你好: " + name + "!");
};
}
// 創建兩個Person對象
var person1 = Person("ande", 18);
var person2 = Person("dahuan", 28);
2.訪問對象的屬性
2.1 通過點語法訪問對象屬性
var obj = {
name : "xiaoming",
age : 18,
show : function (girlfriend) {
console.log(this.name + "的女朋友是" + girlfriend);
}
};
// 訪問屬性值
console.log(obj.name); // 輸出:"xiaoming"
console.log(obj.age); // 輸出:18
2.2 通過中括號法訪問對象屬性
[ ] 法可以用變量或者數字作爲屬性名,而點方法不可以;
var obj = {
name : "xiaoming",
age : 18,
110 : "110",
show : function (girlfriend) {
console.log(this.name + "的女朋友是" + girlfriend);
}
};
// 訪問屬性值
console.log(obj["name"]); // 輸出:"xiaoming"
var age = "age";
console.log(obj[age]); // 輸出:18
console.log(obj["110"]); // 輸出:"110"
3.訪問對象的方法
var obj = {
name : "xiaoming",
age : 18,
show : function (girlfriend) {
console.log("xiaoming的女朋友是" + girlfriend);
},
sleep : function () {
console.log("xiaoming在睡覺")
}
};
// 訪問對象方法
obj.show("小紅");
obj.sleep();
4. this關鍵字
this是JavaScript語言的一個關鍵字。
它代表函數運行時,自動生成的一個內部對象,只能在函數內部使用。
隨着函數使用場合的不同,this的值會發生變化。但是有一個總的原則,那就是this指的是,調用函數的那個對象。
4.1 純粹的函數調用
這是函數的最通常用法,屬於全局性調用,因此this就代表全局對象(Global)。
var index = 0;
function fun() {
// 此處的this代表就是全局對象window
this.index = 1;
}
fun();
console.log(index); // 輸出:1
因爲我們使用window.fun()來調用函數,調用函數的那個對象是window,所以this指向的也是window。
4.2 在對象內使用
作爲對象方法的調用,this 指向當前實例對象。
var point = {
x : 0,
y : 0,
moveTo : function(x, y) {
this.x += x;
this.y += y;
}
};
point.moveTo(10, 10);
console.log("x: " + point.x + " y: " + point.y); // 輸出:x: 10 y: 10
4.3 作爲構造函數調用
所謂構造函數,就是通過這個函數生成一個新對象(object),這時this就指這個新對象。
function Student() {
this.name = "ande";
}
var stu = new Student();
console.log(stu.name); // 輸出:"ande"
5、遍歷對象
5.1 使用for...in循環遍歷
var obj = {
name : "xiaoming",
age : 18,
sex : "男",
tel : "18911450210"
};
// for...in循環遍歷
for(var attr in obj) {
if (typeof obj[attr] != "function") {
console.log("屬性操作:" + obj[attr]);
}
}
5.2 使用Object.keys()遍歷
返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性).
var obj = {'0':'a','1':'b','2':'c'};
Object.keys(obj).forEach(function(key){
console.log(key,obj[key]);
});
5.3 使用Object.getOwnPropertyNames(obj)遍歷
返回一個數組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性).
var obj = {'0':'a','1':'b','2':'c'};
Object.getOwnPropertyNames(obj).forEach(function(key){
console.log(key,obj[key]);
});
5.4 使用Reflect.ownKeys(obj)遍歷
返回一個數組,包含對象自身的所有屬性,不管屬性名是Symbol或字符串,也不管是否可枚舉.
var obj = {'0':'a','1':'b','2':'c'};
Reflect.ownKeys(obj).forEach(function(key){
console.log(key,obj[key]);
});
6 判斷屬性是否存在
判斷對象中是否有某屬性的常見方式總結,不同的場景要使用不同的方式。
6.1點( . )或者方括號( [ ] )
通過點或者方括號可以獲取對象的屬性值,如果對象上不存在該屬性,則會返回undefined。當然,這裏的“不存在”指的是對象自身和原型鏈上都不存在,如果原型鏈有該屬性,則會返回原型鏈上的屬性值。
// 創建對象
let test = {name : 'lei'}
// 獲取對象的自身的屬性
test.name //"lei"
test["name"] //"lei"
// 獲取不存在的屬性
test.age //undefined
// 獲取原型上的屬性
test["toString"] //toString() { [native code] }// 新增一個值爲undefined的屬性test.un = undefinedtest.un //undefined 不能用在屬性值存在,但可能爲 undefined的場景
所以,我們可以根據 Obj.x !== undefined 的返回值 來判斷Obj是否有x屬性。
這種方式很簡單方便,侷限性就是:不能用在x的屬性值存在,但可能爲 undefined的場景。 in運算符可以解決這個問題
6.2 如果指定的屬性在指定的對象或其原型鏈中,則in
運算符返回true
。
let test = {
name:'lei',
un:undefind
}
'name' in test //true
'un' in test //true
'toString' in test //true
'age' in test //false
示例中可以看出,值爲undefined的屬性也可正常判斷。
這種方式的侷限性就是無法區分自身和原型鏈上的屬性,在只需要判斷自身屬性是否存在時,這種方式就不適用了。這時需要hasOwnProperty()
6.3 hasOwnProperty()
Object的hasOwnProperty()
方法返回一個布爾值,判斷對象是否包含特定的自身(非繼承)屬性。
let test = {
name:'zhangsan'
}
test.hasOwnProperty('name') //true 自身屬性
test.hasOwnProperty('age') //false 不存在
test.hasOwnProperty('toString') //false 原型鏈上屬性
總結
三種方式各有優缺點,不同的場景使用不同的方式,有時還需要結合使用,比如遍歷自身屬性的時候,就會把 for ··· in ···和 hasOwnProperty()結合使用。
7 對象合併
7.1ES6提供了Object.assign()
,用於合併/複製對象的屬性。
|
它會修改target對象,然後將它返回:先將source_1對象的所有可枚舉屬性複製給target,然後依次複製source_1等的屬性。
let form = {name: 'liming', sex: '男'};
let obj = {class: '一班', age: 15};
console.log('before', form);
Object.assign(form, obj);
console.log('after', form);
注意
直接拿原有一個對象作爲目標對象,合併後,原對象會被改變。例如上面的“form“, 通過最後一句after的打印可以看出,form被改變了,有可能會影響頁面中用到它的地方。所以,如果是兩個對象在其他處還有用,建議聲明一個額外的空對象作爲目標對象,這樣不會影響到2個原對象。
let form = {name: 'liming', sex: '男'};
let obj = {class: '一班', age: 15};
console.log('before', form);
Object.assign({},form, obj);
console.log('after', form);
7.2 擴展運算符(...)用於取出參數對象的所有可遍歷屬性,拷貝到當前對象之中。
<script>
let obj1 = {
name:'zhang',
age:20
}
let obj2 = {
sex:'男'
}
let obj = {...obj1,...obj2}
//等同於
// let obj = Object.assign({},obj1,obj2)
console.log(obj)
</script>