您的位置:首页 > Web前端 > JavaScript

JavaScript深入浅出————对象(四)

2017-02-07 20:14 417 查看
一、javascript对象概述

对象中包含一系列属性,这些属性时无序的.

   每个属性都有一个字符串key和对应的value.

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

   obj.x;//1

   obj.y;//2

   

   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}

   

   var obj={};

   obj.y=2;

   obj.x=1;

   

   function foo(){};

   foo.prototype.z=3;

   var obj=new foo();

二、创建对象,原型链

1.对象创建-字面量

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

 var obj2={

  x:1,

  y:2,

  o:{z:3,n:4}

 }

 2.创建对象-new/原型链

 function foo(){}//函数对象会默认带有prototype属性,改、该属性为一个对象属性,该对象也是有原型的,指向Object.prototype,Object.prototype也是有原型的,其值为null

 foo.prototype.z=3;//为对象添加属性z=3

 

 var obj=new foo();//创建新对象obj的原型会指向构造器的原型(即foo.prototype)

 obj.y=2;

 obj.x=1;

 

 obj.x;//1

 obj.y;//2

 obj.z;//3

 typeof obj.toString();//"function"

 "z" in obj;//true

 obj.hasOwnProperty("z");//false

 //通过原型链的方法可以继承原型链上的属性,同时又不会修改原型链上的属性

 

 3.对象创建-Object.create()

 var obj=Object.create({x:1});//创建一个对象,并且对象的原型指向{x:1},{x:1}的原型指向Object.prototype,Object.prototype指向null

 obj.x;//1

 typeof obj.toString;//"function"

 obj.hasOwnProperty("x");//false

 

 并不是所有的对象都含有Object.prototype

 var obj=Object.create(null);//此时obj的原型直接指向null,不包含Object.prototype,也不会包含Object的toString方法

 obj.toString;//undefined

 

三、属性操作

1.属性读写

 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

 }

 

 var p;

 for(p in obj){

  console.log(obj[p]);

 }

 //注意:用for-in遍历时有可能会把原型链上的属性也遍历出来,并且其顺序不确定

 

2.属性读写-异常

 var obj={x:1};

 obj.y;//undefined

 var yz=obj.y.z;//TypeError:Cannot read prototype "z" of undefined

 obj.y.z=2;//TypeError:Cannot set property "z" of undefined

 

 var yz;

 if(obj.y){

  yz=obj.y.z;

 }

 

 var yz=obj && obj.y && obj.y.z;//三个条件连接起来判断真假,都为真,则返回最后一个值;

 

3.属性删除

 var person={age:28,title:"fe"};

 delete person.age;//true

 delete person["title"];//true

 person.age;//undefined

 delete person.age;//true,重复删除某个属性时,仍返回true

 //注意:删除属性时返回true并不表示删除属性成功,而是表示该属性已经不存在了

 

 delete Object.prototype;//false,每个属性会有一系列标签来控制它的权限

 

 var descriptor=Object.getOwnPropertyDescriptor(Object,"prototype");

 descriptor.configurable;//false,configurable表示是否可配置,其值为false决定了delete Object.prototype的值也为false并且不会生效

 

4.属性检测

 var cat=new Object;

 cat.legs=4;

 cat.name="Kitty";

 

 "legs" in cat;//true

 "abc" in cat;//false

 "toString" in cat;//true,inherited property!!!

 

 cat.hasOwnProperty("legs");//true

 cat.hasOwnProperty("toString");//false

 

 cat.propertyIsEnumerable("legs");//true,是否可枚举

 cat.propertyIsEnumerable("toString");//false

 

 自定义一个属性,并让它的枚举标签为false

 Object.defineProperty(cat,"price",{enumerable:false,value:1000});//Object.defineProperty中的enumerable默认为false

 cat.propertyIsEnumerable("price");//false

 cat.hasOwnProperty("price");//true

5.属性枚举

 var o={x:1,y:2,z:3};

 "toString" in o;//true

 o.propertyIsEnumerable("toString");//false

 var key;

 for(key in o){

  console.log(key);//x,y,z

 }

 

 var obj=Object.create(o);

 obj.a=4;

 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方法

例1:

var man={

  name:"Bosn",

  weibo:"@Bosn",

  get age(){

   return new Date().getFullYear()-1988;

  },

  set age(val){

   console.log("Age can not be set to "+val);

  }

 }

 console.log(man.age);//27

 man.age=100;//Age can not be set to 100

 console.log(man.age);//27

 

例2:

var man={

  weibo:"@Bosn",

  $age:null,

  get age(){

   if(this.$age==undefined){

    return new Date().getFullYear()-1988;

   }else{

    return this.$age;

   }

  },

  set age(val){

   val= +val;//将字符串转为数字

   if(!isNaN(val)&&val>0&&val<150){

    this.$age=+val;

   }else{

    throw new Error("Incorrect val="+val);

   }

  }

 }

 console.log(man.age);//27

 man.age=100;

 console.log(man.age);//100

 man.age="abc";//error:Incorrect val=NaN

get/set与原型链

function foo(){}

 Object.defineProperty(foo.prototype,"z",{get:function(){return 1;}});

 

 var obj =new foo();

 

 obj.z;//1

 obj.z=10;

 obj.z;//1

 //注意:obj的对象上没有z属性并且向上查找时有对于的get或set方法时,当我们尝试赋值时,实际上会走get或set方法

 

 //通过下面的方法可以为当前对象添加属性

 Object.defineProperty(obj,"z",{value:100,configurable:true});

 obj.z;//100

 delete obj.z;

 obj.z;//1

var o={};

 Object.defineProperty(o,"x",{value:1});//writable=false,configurable=false

 var obj=Object.create(o);

 obj.x;//1

 obj.x=200;

 obj.x;//still 1,can't change it

 

 Object.defineProperty(obj,"x",{writable:true,configurable:true,value:100});

 obj.x;//100

 obj.x=500;

 obj.x;//500

五、属性标签

通过Object.getOwnPropertyDescriptor("对象","属性")来查看对象属性的属性标签

 例:Object.getOwnPropertyDescriptor({pro:true},"pro");//Object{value:true,writable:true,enumerable:true,configurable:true}

 Object.getOwnPropertyDescriptor({pro:true},"a");//undefined

 

 管理或设置属性标签

 Object.defineProperty("对象","属性","属性标签对象")

 Object.defineProperties("对象","复杂对象")

 例1:

 var person={};

 Object.defineProperty(person,"name",{

  configurable:false,

  writable:false,

  enumerable:true,

  value:"Bosn Ma"

 });

 person.name;//Bosn Ma

 person.name=1;

 person.name;//still Bosn Ma

 delete person.name;//false

 Object.defineProperty(person,"type",{

  configurable:true,

  writable:true,

  enumerable:false,

  value:"Object"

 });

 Object.keys(person);//["name"],通过Object.keys()可以查看对象的属性

 

 例2:

 var person={};

 Object.defineProperties(person,{

  title:{value:"fe",enumerable:true},

  corp:{value"BABA",enumerable:true},

  salary:{value:50000,enumberable:true,writable:true}

 });

 Object.getOwnPropertyDescriptor(person,"salary");//Object{value:50000,writable:true,enumerable:true,configurable:false}

 Object.getOwnPropertyDescriptor(person,"corp");//Object{value:"BABA",writable:false,enumerable:true,configurable:false}

 

 例3:

 var person={};

 Object.defineProperties(person,{

  title:{value:"fe",enumerable:true},

  corp:{value:"BABA",enumerable:true},

  salary:{value:50000,enumerable:true,writable:true},

  luck:{

   get:function(){

    return Math.random()>0.5?"good":"bad";

   }

  },

  promote:{

   set:function(level){

    this.salary*=1+level*0.1;

   }

  }

 });

 Object.getOwnPropertyDescriptor(person,"salary");//Object{value:50000,writable:true,enumerable:true,configurable:false}

 Object.getOwnPropertyDescriptor(person,"corp");//Object{value:"BABA",writable:false,enumerable:true,configurable:false}

 person.salary;//50000

 person.promote=2;

 person.salary;//60000

属性标签可以重复被设置:

  var person={};

 Object.defineProperty(person,"name",{

  value:1111,

  configurable:false//configurable为false时,除了writable从true改为false其他属性修改不允许

 });

 console.log(person.name);

 console.log(Object.getOwnPropertyDescriptor(person,"name"));

 Object.defineProperty(person,"name",{

  enumerable:true

 });

 console.log(Object.getOwnPropertyDescriptor(person,"name"));

六、对象标签

对象标签主要有3个:[[proto]],[[class]],[[extensible]]

1.原型标签[[proto]]

2.class标签,没有直接的方法来查看class,可以通过Object.prototype.toString来间接地查看

var toSting=Object.prototype.toString;

 function getType(o){return toSting.call(o).slice(8,-1);};

 

 toSting.call(null);//"[object Null]"

 getType(null);//"Null"

 getType(undefined);//"undefined"

 getType(1);//"Number"

 getType(new Number(1));//"Number"

 typeof new Number(1);//"object"

 getType(true);//"Boolean"

 getType(new Boolean(true));//"Boolean"

3.extensible标签表示对象是否可以扩展,属性是否可以添加

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

 Object.isExtensible(obj);//true

 Object.preventExtensions(obj);

 Object.isExtensible(obj);//false

 obj.z=1;

 obj.z;//undefined,add new prototy failed

 Object.getOwnPropertyDescriptor(obj,"x");//Object{value:1,writable:true,enumerable:true,configurable:true}

 

 Object.seal(obj);

 Object.getOwnPropertyDescriptor(obj,"x");//Object{value:1,writable:true,enumerable:true,configurable:false}

 Object.isSealed(obj);//true

 

 Object.freeze(obj);

 Object.getOwnPropertyDescriptor(obj,"x");//Object{value:1,writable:false,enumerable:true,configurable:false}

 Object.isFrozen(obj);//true

序列化、其他对象方法

var obj={x:1,y:true,z:[1,2,3],nullVal:null};

 JSON.stringify(obj);//"{"x":1,"y":true,"z":[1,2,3],"nullVal":null}"

 

 obj={val:undefined,a:NaN,b:Infinity,c:new Date()};

 JSON.stringify(obj);//"{"a":null,"b":null","c":"2015-01-20T14:12:45.910Z"}"

 //注意:值为undefined时不会被显示,值为NaN和Infinity时显示为null,值为时间会被转为UTU的时间格式

 

 obj=JSON.parse("{"x":1}");

 obj.x;//1

序列化-自定义

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

其他对象方法

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

 obj.toString();//"[object Object]"

 obj.toString=function(){return this.x+this.y};

 console.log("Result "+obj);//"Result 3" ,by toString

 

 console.log(+obj);//3,form toString

 

 obj.valueOf=function(){return this.x+this.y+100;};

 console.log(+obj);//103,from valueOf

 

 console.log("Result "+obj);//still "Result 103"

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: