標籤:turn 進位 並且 string nbsp 個數 desc cti java
JavaScript權威指南學習筆記,禁止轉載!
5、對象
對象的屬性是無序的,每個屬性都有一個字串key和值value,
資料屬性的標籤:writable、enumerable、configurable、value
訪問器屬性的標籤:enumerable、configurable、get、set。get表示屬性可讀,set表示屬性可寫。屬性前面有底線表示只能通過對象方法get/set訪問的屬性,也就是訪問器屬性。
(1)建立對象
1)字面量var obj={x:1,y:2};
2)new:var obj=new foo(); (obj的proto指向建構函式foo的foo.prototype)
如,function foo(){};
var obj=new foo();
typeof obj; //"object"
typeof obj.toString; //"function"(toString方法是obj原型鏈上Object.prototype上的方法)
注意:若(obj.z; //undefined)不代表obj對象及其原型鏈上沒有屬性z,可能有屬性z但值是undefined。
3)Object.create(原型)
如,var obj= Object.create({x:1}); 此時{x:1}時obj的原型。
typeof obj.toString; //"function"
注意:但不是每個對象的原型鏈上都有Object.prototype,因此不是每個對象都有toString方法,如,var obj= Object.create(null); 此時null是obj的原型,也是原型鏈的頂端,因此,typeof obj.toString; //undefined
(2)屬性操作
~~屬性讀:
如, var obj={x:1,y:2};
obj.x; //1
obj[“x”]; //1(不常用)
var p; for(p in obj){console.log(obj[p]); }
//1
//2
(這種方法會讀出obj原型鏈上的屬性,並且屬性的順序不確定。可以用hasOwnProperty過濾掉原型鏈上的屬性。)
讀屬性會向原型鏈上尋找。
~~檢測屬性是否存在:
obj.hasOwnProperty(屬性名稱):判斷對象obj自身上是否有該屬性,返回true或false。
obj.propertyIsEnumerable(屬性名稱):判斷對象obj的該屬性是否可枚舉。原型鏈上的屬性通常不可枚舉。
(3)get/set方法和原型鏈
如,var obj = {};
Object.defineProperty(obj,‘x‘,{value: 1,writable: false,configurable: false,enumerable: false});
var obj1 = Object.create(obj);
obj1.x = 10;
console.log(obj1.x); //1
當給對象的屬性賦值時(obj1.x = 10;):
如果obj1上有x屬性,修改其值。
如果obj1上沒有x屬性,會向其原型鏈尋找,如果原型鏈上也沒有x屬性,那麼x屬性會被添加到obj1對象上;如果原型鏈上有x屬性,則分三種情況:
a、原型鏈上x屬性writable:true,會在obj1上添加x屬性,並屏蔽原型鏈上的屬性,
b、原型鏈上x屬性writable:false,這條指派陳述式會被忽略,如果是在strict 模式下會報錯,所以上述obj1.x還是1,
c、原型鏈上x有set/get方法,還是走原型鏈上的set/get方法,而不會給obj1上添加新的x屬性。此時如果需要給obj1添加x屬性,使用Object.defineProperty(obj1,’z’,{value:10,configurable:true});
MARK!
(4)屬性標籤
Object.getOwnPeopertyDescriptor(對象名,‘屬性名稱‘):返回一個對象,包含這個屬性的所有標籤。
Object.defineProperty(對象名,”屬性名稱”,屬性的標籤)(通過這個方法定義的屬性,configurable、enumerable、writable的預設值為false)
如,var b={};
Object.defineProperty(b,‘b‘,{configurable:false,writable:true});
Object.getOwnPropertyDescriptor(b,‘b‘);//Object {value: undefined, writable: true, enumerable: false, configurable: false}
如,var person={};
Object.defineProperties(person,{
salary:{value:50000,writable:true},
promote:{
set:function(level){
this.salary*=1+level*0.1;
}
} //promote結束處
});
//Object {salary: 50000}
salary:50000
set promote:function (level)
__proto__:Object
person.promote=2; //調用set方法傳值到函數的參數level
person.salary; //6000
Object.keys(對象):返回一個數組,包含該對象上的所有可枚舉的屬性名稱。
注意:如果writable:false,configurable:true,可以通過Object.defineProperties重新設定屬性的value標籤來變相地修改屬性值;當然writable標籤也可以被修改為true。
(5)對象標籤
_proto_:原型
class:物件類型
Object.prototype.toString.call() 檢測資料類型,包括對象的類型。
注意:Object.prototype.toString.call(new Number(1)); //"[object Number]"
Object.prototype.toString.call(1); //"[object Number]"
extensible:對象上的屬性是否可被添加
Object.isExtensible(obj); 判斷對象是否可擴充
Object.preventExtensions(obj); 使對象不可擴充
Object.seal(obj):使對象上屬性configurable變為false
Object.isSealed(obj)判斷
Object.freeze(obj):使對象上屬性configurable和writable都變為false
Object.isFrozen(obj)判斷
這些都不影響對象的原型鏈。
(6)對象序列化JSON
把對象轉換為位元組序列(資料以二進位序列的形式在網路上傳送)的過程
JSON.stringify():將javascript值轉換為JSON字串,
如果屬性值是undefined,將不會出現在結果字串中;如果屬性值是NaN或Infinity,會轉換成null;如果是Date會轉換為UTC時間格式,
如,var obj={x:1, y:true, z:[1,2,3], nullval:null, val:undefined, a:NaN, b:Infinity,c:new Date() };
JSON.stringify(obj);
//"{"x":1,"y":true,"z":[1,2,3],"nullval":null,"a":null,"b":null,"c":"2017-05-20T11:48:28.044Z"}"
序列化自訂
var obj={x:1, y:2, o:{
o1:1, o2:2, toJSON:function(){return this.o1+this.o2; }
}
};
JSON.stringify(obj);
// "{"x":1,"y":2,"o":3}"
JSON.parse():將一個 JSON字串轉換為對象。
如,var str=‘{"x":1,"y":2}‘;
JSON.parse(str);
//Object {x: 1, y: 2}(單引號寫在{}外面,每個屬性名稱都必須要雙引號,否則會拋出異常Uncaught SyntaxError: Unexpected identifier)
(7)valueOf、toString方法
如,var obj={x:1, y:2};
obj.toString=function(){return this.x+this.y; }
+obj; //3(+加號操作符強制將對象轉換為基本類型)
obj.valueOf=function(){return this.x+this.y+100; }
+obj; //103
“result”+obj; //“result103”
當valueOf和toString方法都存在時,先尋找valueOf,如果valueOf傳回值為基本類型,以此為準,結束;如果valueOf傳回值為對象再尋找toString,如果toString傳回值也為對象,就會報錯。
JavaScript對象-學習筆記