對象中包含一系列屬性,這些屬性是無序的。每一個屬性都有一個字符串 key 和 對應的 valuejavascript
var obj = { x :1, y:2}; obj.x //1 obj.y //2
訪問對象的屬性時,不管是 數字,仍是字符串都是指向同一個key屬性,使用空對象,或有屬性的對象,做爲key,都會轉化爲字符串 toString而後處理。java
var obj ={}; obj[1] = 1; obj['1'] =2; obj; //Object{1:2} obj[{}] = true; obj[{x:1}] =true; obj;// Object{1:2,[object Object]:true}
對象的屬性能夠動態添加和刪除的,對象的每個屬性,都有不少的屬性標籤、get、set方法。數組
writable 、enumerable、configurable、value、get/setdom
建立一個函數 foo,每個函數都有一個 prototype屬性,假設給 foo.prototype.z賦值爲3,這是new一個foo, 這時 obj的原型【[ proto]】就會指向他的構造器的 prototype屬性。這時訪問 obj.x 獲得 1,obj.z 在obj對象上沒有,這時會繼續找他的原型 z=3。函數
function foo(){} foo.prototype.z =3; var obj = new foo();
對象中還有【[class]】表示對象屬於哪個種類this
【[extensible]】對象是否容許增長新的屬性spa
var obj1 = {x:1 ,y:2}; var obj2 ={ x:1, y:2 o:{ //對象嵌套 z:3, n:4 } };
function foo(){} //函數對象默認帶一個 對象屬性 prototype foo.protptype.z =3
使用new構造器構造新的對象,每個對象後含有一個標籤原型【proto】,原型指向構造器的 ptototype屬性。當煩那個吻對象的屬性時,若是對象自己沒有這個屬性,對象會繼續查找原型,直到null,沒有返回undefined,有獲取到值。prototype
當給對象賦值時不會查找原型鏈,有則修改,沒有則添加。code
當設置 obj.z = undefined ;再次獲取 obj.z ;// undefined對象
想要訪問原型上的z 則 delete obj .z ; //刪除對象上的屬性,不會影響到原型鏈,而後獲取 obj.z //3。
var o =new Object(); //建立一個空對象 ,和{}同樣 var a = new Array();//建立一個空數組,和[] 同樣 var d = new Date();//建立一個表示當前時間Date對象
Object.create()是一個系統內置函數,接收一個參數,通常爲對象,返回一個新建立的對象,而且新建立的對象的原型指向參數。參數{ x : 1} 的原型指向 Object.prototype , obj.x x是從原型鏈繼承的。
若是傳入一個null,則對象的原型爲 null ,不包含任何方法。
對象 . 或者 對象[] 均可以
//建立一個對象 var obj = { x:1, y:2}; obj.x; //1 obj["y"]; //2 obj["x"] =3 obj.y = 4
var obj = {x1:1, x2:2}; var i = 1, n = 2; for( ; i<=n; i++){ console.log(obj['x' + i]) }
輸出:1,2
注意用for in遍歷,有可能遍歷出原型鏈上的屬性。
var p; for( p in obj){ console.log(obj[p]) }
var obj = {x:1}; //建立一個對象 //訪問一個不存在的屬性y obj.y; //先進行原型鏈查找,若是找到末端仍是找不到,返回undefined //obj.y爲undefined 再.z報錯 var yz =obj.y.z ;//TypeError:Cannot read property 'z' of undefined obj.y.z = 2; //TypeError:Cannot set property 'z' of undefined
var yz; if(obj.y){ //先判斷是否有y屬性 yz= obj.y.z } //或者 && 判斷 每一個都是true 總體返回true var yz = obj && obj.y && obj.y.z //obj存在則繼續向右找,若是爲空直接返回 undefined
當對象上不存在要刪除的屬性時就會返回true,重複刪不會報錯
var person = {age:28,title:'fe'}; delete person.age ; //true 刪除成功 delete person['title']; //true 中括號傳入key刪除成功 person.age ; //undefined delete person.age; //true 重複刪除不存在的屬性不會報錯,返回true
delete Object.prototype; //false //getOwnPropertyDescriptor 第一個參數時要查看對象,第二個參數是要檢測的屬性 var descriptor = Object.getOwnPropertyDescriptor(Object,"property"); //獲取屬性中全部的標籤 descriptor.configurable ;//false 是否可配置:false ,因此delete Object.prototype返回false
var globalVal = 1; //定義全局變量 delete globalVal; //false 不能夠刪除 (function(){ var localVal = 1; return delete localVal; //不能夠刪除 }());//false
function fd(){} delete fd;//false 刪除失敗 (function(){ function fd(){ return delete fd; } }()); //false
ohNo = 1; //隱式建立全局變量 window.obNo; //1 delete ohNo;//true 成功刪除 但不推薦
var cat = new Object; //構造一個對象 cat.legs = 4; cat.name = "Kitty" 'legs' in cat ;// true cat中有legs屬性 'abc' in cat ; //false "toString" in cat; //true, inherited property cat原型是Object.prototype,中toString存在 //表示查找對象上的屬性 cat.hasOwnProperty('legs'); //true cat.hasOwnProperty('toString'); //false,原型鏈上存在
cat.propertyIsEnumerable('legs'); //true 能夠枚舉 cat.propertyIsEnumerable('toString'); //false
Object.defineProperty
Object.defineProperty(cat,'price',{enumerable:false,value:1000}); Object.defineProperty 建立對象標籤都默認爲false //第一個參數:添加屬性的對象。二、屬性的名字,三、對象,設置標籤 cat.propertyIsEnumerable('price'); //false cat.haOwnProperty('price');//true
if( cat && cat.legs){ //存在 cat.legs*=2; } //或 !=時 null 和undefined是相等的 if(cat.legs != undefined){ //還能夠寫爲 !==undefined }
var o = { x:1, y:2,z:3} 'toString' in o; //true o.propertyIsEnumerable('toString'); //false var key; for(key in o){ //遍歷屬性,因爲toString是不可枚舉的因此不顯示 console.log(key) ;//x,y,z }
利用 Object.create(o) 建立一個 obj對象 原型指向o。此時原型鏈o上的屬性夜默承認枚舉
var obj = Obj.create(o); //原型鏈上的屬性也默承認枚舉 obj.a = 4; //添加一個屬性a 默承認枚舉 var key; for(key in obj) { console.log(key) ; // a,x,y,z }
只操做本對象上的屬性
var obj = Object.create(o); obj.a = 4; var key; for(key in obj){ if(obj.hasOwnProperty(key)){ //過濾掉原型鏈的屬性 console.log(key);//a } }
定義 get 、set方法訪問屬性age()
var man = { name:'Bosn', weibo:'@Bosn', get age(){ // get關鍵字 屬性名 函數體 return new Date().getFullYear() - 1995; //返回當前日期年份減去生日,算出當前年齡 }, set age(val){ console.log('Age can\'t be set to' +val ); } } console.log(man.age); //22 獲取值時自動調用 get方法 man.age = 100; //Age can't be set to 100 賦值時自動調用set方法 console.log(man.age); // still 22
當訪問 obj.z,因爲對象上沒有z屬性,會向原型鏈上查找,給z賦值後,發現obj.z仍然爲1。 當obj對象上沒有z屬性,而且發如今原型鏈上有對應的get 或 set 方法時,當嘗試賦值時會走get/set方法,而不會給對象添加新的屬性。
用 Object.defineProperty( obj,'z',{}); 來給obj對象添加z屬性,這時 obj.z爲100 ,刪除obj.z ,再次獲取 obj.z 得到原型鏈上 z的get方法 返回1
定義一個空的對象 o,定義屬性x ,注意經過 Object.defineProperty() 定義的對象,各個標籤的默認是false ---writable = false, configurable = false。在建立一個以o做爲原型的新對象, 修改x的值,不起做用,由於原型鏈上的writable = false,不可改
給obj對象添加屬性,使用Object.defineProperty()
var o {}; Object.defineProperty(o,'x',{value :1});//writable = false, configurable = false var obj = Object.create(o); //建立一個以o爲原型的新對象 obj.x ;//1 obj.x =200; //修改 obj.x; //still 1 can't change it //給obj添加屬性x Object.defineProperty( obj ,'x',{writable:true,condigurable:true, value :100}); obj.x = 100; obj.x = 500; //修改 obj.x = 500; //修改爲功
Object.getOwnPropertyDescriptor({pro:true},'pro'); //返回一個對象 Object {value:true,writable:true,enumerable:true,configurable:true} Object.getOwnPropertyDescriptor({pro:true},'a'); //不存在a屬性 undefined
Object.definedProperty 建立屬性,
var person = {} ;//空對象 //傳入對象,屬性名,配置對象{} Object.definedProperty(person,'name',{ configurable:false, writable:false, enumerable:true, value:'lalala' }) person.name;// lalala person.name = 1; //修改後仍然爲1 delete person.name; //false
繼續添加屬性
Object.definedProperty(person,'type',{ configurable:true, writable:true, enumerable:false, //不可枚舉,在for in 中不顯示type屬性 value:'hahaha' }) //獲取對象上全部的key Object.keys(person); //['name']
Object.defineProperties ( 定義屬性的對象,{ 屬性名:{設置值},屬性名:{...} })
Object.defineProperties(person,{ title:{ value:'chapter1' , enumerable:true}, //默認值爲false salary: {value:10000,enumerable:ttue}, luck:{ //隨機一個數,通常機率good get : function(){ return Math.random()>0.5 ? 'good','bad'} }, promote :{ //升一級,工資漲10% set: function(level){ this.salary* = 1+level*0.1} } }) Object.getOwnPropertyDescriptor(person,'title'); //獲得一個 Object {value:'chapter1' , enumerable:true, writable:true,configurable:false}; person.salary; //1000 person.promote = 2; //調用set方法 person.salary ;12000;
只要configurable:true, 就能夠用Object.defineProperties修改值 或標籤值
對象的每個屬性都是有標籤的,對象也有
[ [proto] ] 、[ [class ] ]、 [[extensible]]
表示對象時哪一個類型的
slice(8,-1); //從第8個字符截取直到最後,去掉最後一個字符,toString 會把值轉換爲對象
對象是否可擴展,preventExtension (obj) ;//設置爲禁止擴展,對象不能夠在添加對象,但對象屬性的標籤值不會改變。
Object.seal(obj); //將全部對象的configurable屬性設置爲 false。
Object.freeze(obj); //凍結,writable,configurable 都爲false
JSON 屬性要用 " " 引發來
var obj = { x:1,y:true,z:[1,2,3],nullVal:null}; JSON.stringify(obj); // 返回一個字符串 "{"x":1 , "y":true, "z":[1,2,3],"nulVal" :null}" //若是序列化的值爲undefined,則這個值不會出如今序列化對象中 obj ={ val :undefined, a :NaN , b:Infinity, c:new Date()}; JSON.stringify(obj); // "{"a":null , "b":null, "c":"2017-04-20T14:14:43.910Z"}"; //值爲 notNumber 、Infinity 得到 null 。時間得到UTC時間格式 //反解對象 obj = JSON.parse('{"x" :1 }'); obj.x; //1
var obj = { x:1, y:2, o:{ o1:1, o2:2, toJSON : function(){ //固定toJSON return this.o1 + this. o2 ; //this 指向o } } }; JSON。stringify(obj); //"{ "x":1, "y" :2, "o" :3}"
var obj = {x:1,y:2}; obj.toString(); //"[ object object]" 返回 object obj.toString = function(){ return this.x + this.y}; //定義本身的toString方法 "Result" + obj; //"Result3, 理解爲字符串拼接,調用 toString +obj; //調用tostring方法,轉化爲數字,相加 得3 //valueOf 嘗試把對象變爲基本類型時調用 obj.valueOf = function () { return this.x + this.y + 100; }; //不管是 轉化爲數字,仍是拼接都會嘗試把對象轉化爲基本類型,先去找valueOf,若是valueOf不存在,或返回對象, 則toString,若是toString也不存在,或者返回對象則報錯 +obj; //103 從 valueOf來的 "Result" + obj ;// "Result103"