博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
原 2017/5 JavaScript基础6--- 对象
阅读量:6905 次
发布时间:2019-06-27

本文共 8500 字,大约阅读时间需要 28 分钟。

hot3.png

一、对象概述

1、定义

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

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

2、对象的 key

访问对象的属性时,无论是 数字,还是字符串都是指向同一个key属性,使用空对象,或有属性的对象,作为key,都会转化为字符串 toString然后处理。

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}

3、对象结构

1)属性标签

对象的属性可以动态添加和删除的,对象的每一个属性,都有很多的属性标签、get、set方法。

writable 、enumerable、configurable、value、get/set

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]】表示对象属于哪一个种类

【[extensible]】对象是否允许增加新的属性

二、创建对象、原型链

1、字面量 花括号

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

2、new构造器 /原型链

1)原型链

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

 

2)获取值

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

3)赋值

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

当设置 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对象

3、Object .create 创建对象

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

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

四、属性操作

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

1、普通读写操作

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

//创建一个对象var  obj = { x:1, y:2};obj.x; //1obj["y"]; //2 obj["x"] =3obj.y = 4

2、动态处理拼接属性名

var obj = {x1:1, x2:2};var i = 1, n = 2;for( ; i<=n; i++){  console.log(obj['x' + i])}

输出:1,2

3、for in遍历

注意用for in遍历,有可能遍历出原型链上的属性。

var p;for( p in obj){  console.log(obj[p])}

4、读写异常

var  obj = {x:1}; //创建一个对象//访问一个不存在的属性yobj.y; //先进行原型链查找,如果找到末端还是找不到,返回undefined//obj.y为undefined 再.z报错var yz =obj.y.z ;//TypeError:Cannot read property 'z' of undefinedobj.y.z = 2; //TypeError:Cannot set property 'z' of undefined

1)、读写前判断

var  yz;if(obj.y){ //先判断是否有y属性  yz= obj.y.z}//或者 && 判断 每个都是true 整体返回truevar yz = obj && obj.y && obj.y.z//obj存在则继续向右找,如果为空直接返回 undefined

5、删除属性

1)delete意义 :

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

var person = {age:28,title:'fe'};delete person.age ;               //true  删除成功delete person['title'];           //true  中括号传入key删除成功person.age ;                      //undefineddelete 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; //1delete ohNo;//true 成功删除 但不推荐

6、属性操作

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'); //truecat.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//第一个参数:添加属性的对象。2、属性的名字,3、对象,设置标签cat.propertyIsEnumerable('price'); //falsecat.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; //trueo.propertyIsEnumerable('toString'); //falsevar 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方法

1、属性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

2、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 = falsevar obj = Object.create(o); //创建一个以o为原型的新对象obj.x ;//1obj.x =200; //修改obj.x; //still 1 can't change it//给obj添加属性xObject.defineProperty( obj ,'x',{writable:true,condigurable:true, value :100});obj.x = 100;obj.x = 500; //修改obj.x = 500; //修改成功

六、属性标签

1、查看属性标签

  1. getOwnPropertyDescriptor 接收两个参数 1、要判断的对象 2、字符串类型的属性名
  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

2、设置属性标签

Object.definedProperty 创建属性,

var person = {} ;//空对象//传入对象,属性名,配置对象{}Object.definedProperty(person,'name',{  configurable:false,  writable:false,  enumerable:true,  value:'lalala'})person.name;// lalalaperson.name = 1; //修改后仍然为1delete person.name; //false

继续添加属性

Object.definedProperty(person,'type',{  configurable:true,  writable:true,  enumerable:false, //不可枚举,在for in  中不显示type属性  value:'hahaha'})//获取对象上所有的keyObject.keys(person); //['name']

3、添加多个属性标签

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; //1000person.promote = 2; //调用set方法 person.salary ;12000;

只要configurable:true, 就可以用Object.defineProperties修改值 或标签值

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

1、对象标签

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

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

2、序列化其他对象的方法

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]" 返回 objectobj.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"

转载于:https://my.oschina.net/u/2991733/blog/899349

你可能感兴趣的文章
innobackupex 备份数据搭建 MySQL Slave
查看>>
CentOS 6.5安装KVM虚拟化
查看>>
centos6构建XFS文件系统
查看>>
服务器硬件监控之Check_openmanage
查看>>
获取免费Windows Store开发者账户方法
查看>>
程序员杂记系列
查看>>
参加“北向峰会”后对SOC之感言
查看>>
ASP.NET vNext MVC 6 电商网站开发实战
查看>>
马化腾IT领袖峰会力推,微信小程序即将迎来爆发拐点
查看>>
javascript js 判断页面是否加载完成
查看>>
【机器学习算法-python实现】决策树-Decision tree(1) 信息熵划分数据集
查看>>
最新的goldengate monitor 12.1.3已经发布
查看>>
ASP.NET防止用户多次登录的方法
查看>>
2D多边形碰撞器优化器
查看>>
webBrowser 模拟登录
查看>>
idea 配置多个tomcat
查看>>
weblogic 整合cxf 报错:cannot create a secure XmlInputFactory
查看>>
Nancy 返回值详解
查看>>
架构思维案例:速学正则
查看>>
记录一则FGA审计“A用户对B用户某张表的更新操作”需求
查看>>