原 2017/5 JavaScript基础6--- 对象

1、对象概述

一、定义

对象中包含一系列属性,这些属性是无序的。每一个属性都有一个字符串 key 和 对应的 valuejavascript

var obj = { x :1, y:2};
obj.x //1
obj.y //2

二、对象的 key

访问对象的属性时,不管是 数字,仍是字符串都是指向同一个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}

三、对象结构

1)属性标签

对象的属性能够动态添加和删除的,对象的每个属性,都有不少的属性标签、get、set方法。数组

writable 、enumerable、configurable、value、get/setdom

2)对象原型.

建立一个函数 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

2、建立对象、原型链

一、字面量 花括号

var obj1 = {x:1 ,y:2};

var obj2 ={
  x:1,
  y:2
  o:{ //对象嵌套
    z:3,
    n:4
  }
};

二、new构造器 /原型链

1)原型链

function foo(){}
//函数对象默认带一个 对象属性 prototype
foo.protptype.z =3

 

2)获取值

使用new构造器构造新的对象,每个对象后含有一个标签原型【proto】,原型指向构造器的 ptototype属性。当烦那个吻对象的属性时,若是对象自己没有这个属性,对象会继续查找原型,直到null,没有返回undefined,有获取到值。prototype

3)赋值

当给对象赋值时不会查找原型链,有则修改,没有则添加。code

当设置 obj.z = undefined  ;再次获取 obj.z ;// undefined对象

想要访问原型上的z 则 delete obj .z ; //删除对象上的属性,不会影响到原型链,而后获取 obj.z //3。

4)new建立对象

var o =new Object(); //建立一个空对象 ,和{}同样
var a = new Array();//建立一个空数组,和[] 同样
var d = new Date();//建立一个表示当前时间Date对象

三、Object .create 建立对象

Object.create()是一个系统内置函数,接收一个参数,通常为对象,返回一个新建立的对象,而且新建立的对象的原型指向参数。参数{ x : 1} 的原型指向 Object.prototype , obj.x x是从原型链继承的。 

若是传入一个null,则对象的原型为 null ,不包含任何方法。

4、属性操做

  • 读写对象属性
  • 属性异常
  • 删除属性
  • 检测属性
  • 美剧属性

一、普通读写操做

对象 . 或者 对象[] 均可以

//建立一个对象
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遍历

注意用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

1)、读写前判断

var  yz;
if(obj.y){ //先判断是否有y属性
  yz= obj.y.z
}

//或者 && 判断 每一个都是true 总体返回true
var yz = obj && obj.y && obj.y.z
//obj存在则继续向右找,若是为空直接返回 undefined

五、删除属性

1)delete意义 :

当对象上不存在要删除的属性时就会返回true,重复删不会报错

var person = {age:28,title:'fe'};
delete person.age ;               //true  删除成功
delete person['title'];           //true  中括号传入key删除成功
person.age ;                      //undefined
delete person.age;                //true 重复删除不存在的属性不会报错,返回true

2)不容许删除的属性

delete Object.prototype; //false 

//getOwnPropertyDescriptor 第一个参数时要查看对象,第二个参数是要检测的属性
var descriptor = Object.getOwnPropertyDescriptor(Object,"property"); //获取属性中全部的标签
descriptor.configurable ;//false 是否可配置:false ,因此delete Object.prototype返回false

3)var 定义的全局变量 局部变量也不能被删除。

var globalVal = 1; //定义全局变量
delete globalVal; //false 不能够删除

(function(){
  var localVal = 1;
  return delete localVal; //不能够删除
}());//false

4)全局函数,局部函数也不能够delete

function fd(){}
delete fd;//false  删除失败


(function(){
  function fd(){
    return delete fd;
  }
}());  //false

5)隐式建立全局变量能够删除

ohNo = 1; //隐式建立全局变量
window.obNo; //1
delete ohNo;//true 成功删除 但不推荐

六、属性操做

1)查看属性是否存在

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,原型链上存在

2)查看属性是否可枚举

cat.propertyIsEnumerable('legs'); //true 能够枚举
cat.propertyIsEnumerable('toString'); //false

3)设置属性

Object.defineProperty

Object.defineProperty(cat,'price',{enumerable:false,value:1000});
Object.defineProperty 建立对象标签都默认为false
//第一个参数:添加属性的对象。二、属性的名字,三、对象,设置标签

cat.propertyIsEnumerable('price'); //false
cat.haOwnProperty('price');//true

5)操做属性时判断属相是否存在

if( cat && cat.legs){ //存在
 cat.legs*=2; 
}

//或 !=时 null 和undefined是相等的

if(cat.legs != undefined){
 //还能够写为 !==undefined
}

6)属性枚举

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
  }
}

5、另外一种读写方式 get/set方法

一、属性getter/setter方法

定义 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

二、get/set与原型链

当访问 obj.z,因为对象上没有z属性,会向原型链上查找,给z赋值后,发现obj.z仍然为1。 当obj对象上没有z属性,而且发如今原型链上有对应的get 或 set 方法时,当尝试赋值时会走get/set方法,而不会给对象添加新的属性。

1)原型链上的属性具备get/set方法

用 Object.defineProperty( obj,'z',{}); 来给obj对象添加z属性,这时 obj.z为100 ,删除obj.z ,再次获取 obj.z 得到原型链上 z的get方法 返回1

2)原型链上的writable 为false

定义一个空的对象 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; //修改为功

6、属性标签

一、查看属性标签

  1. getOwnPropertyDescriptor 接收两个参数 一、要判断的对象 二、字符串类型的属性名
  2. writable:属性是否可修改
  3. enumerable:属性是否可遍历,在for in中是否可显示
  4. configurable:属性标签是否可再被修改,是否能够delete
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修改值 或标签值

7、对象标签、对象序列化

一、对象标签

对象的每个属性都是有标签的,对象也有

[ [proto] ]  、[ [class ] ]、  [[extensible]]

1)原型标签 _proto_

2)class标签

表示对象时哪一个类型的

slice(8,-1); //从第8个字符截取直到最后,去掉最后一个字符,toString 会把值转换为对象

3)extensible标签

对象是否可扩展,preventExtension (obj) ;//设置为禁止扩展,对象不能够在添加对象,但对象属性的标签值不会改变。

Object.seal(obj); //将全部对象的configurable属性设置为 false。

Object.freeze(obj); //冻结,writable,configurable 都为false

二、序列化其余对象的方法

1)序列化

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

2)序列化自定义

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}"

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"
相关文章
相关标签/搜索