对象的查询和设置(JS高级)
2017-09-06 23:11
281 查看
对象的查询和设置
对象的查询和设置属性特性
属性描述符
概念
获取方式
属性描述符设置方式
访问描述符
概念
基于对象属性的几大特性
对象常量属性
禁止属性扩展
密封对象
冻结对象
对象属性的遍历
对象的设置和获取
伪数组
属性特性
属性描述符
概念
属性描述符又叫元属性,也可以认为它是属性的属性。对象属性的属性描述符一共有四个:
configurable: 表示能否通过delete来删除属性从而重新定义属性,能够修改属性的特性,默认为true;
var damu = {}; Object.defineProperty(damu,'wife',{ value:'zdy', configurable: true }) var result = Object.getOwnPropertyDescriptor(damu,'wife'); console.log(damu);//{wife: "zdy"} delete damu.wife; console.log(damu)//{}
configurable设置决定是否可删除属性:
configuarable:false:不能删
configuarable:true:能删
configurable设置决定是否可配置属性描述符:
configuarable:true:可以配置
configurable:false
writ
4000
able:可以从ture变为其他,不能从false变为其他;
configurable:不能动
enumerable:不能动
enumberable: 表示是否能通过for-in循环返回属性。默认为true;
var damu={}; Object.defineProperty(damu,"a",{enumerable:true});//可遍历 Object.defineProperty(damu,"b",{enumerable:false});//不可遍历 Object.defineProperty(damu,"c",{enumerable:true}); Object.defineProperty(damu,"d",{enumerable:false}); Object.defineProperty(damu,"e",{enumerable:true}); Object.defineProperty(damu,"f",{enumerable:false}); Object.defineProperty(damu,"g",{enumerable:true}); for(item in damu){ console.log(item); }//aceg
writable: 是否可以修改属性, 默认为true;
var damu = {}; //通过Object.defineProperty设置的对象,属性秒速服都是false,在此特意将writable: true改为true; Object.defineProperty(damu,'wife',{ value:'zdy', writable: true }) var result = Object.getOwnPropertyDescriptor(damu,'wife'); console.log(damu);//{wife: "zdy"} damu.wife = 'fbb'; //如果writable: false,设置属性值的话,会失败,叫做:静默失败。 //因为设置可改写,所以可以改写属性值。 console.log(damu)//{wife: "fbb"}
value: 包含这个属性的数据值。读取属性值时3,从这个属性读,写入属性时,把新值保存到这个位置。默认值为undefine.
获取方式
获取属性描述符:Object.getOwnPropertyDescriptor(obj, prop);
obj:属性所在的对象;
prop:对象属性名称;
返回值:对象属性的描述符对象。返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性);
var obj = {name:'kobe',age:29}; //字面量形式定义对象 console.log(Object.getOwnPropertyDescriptor(obj, 'name')); //{value: "kobe", writable: true, enumerable: true, configurable: true} var obj1 = {}; obj1 = Object.create(obj) console.log(obj1);//{} obj1 = Object.create(obj,{ sex:{ value:'男' } }) //通过creat,以指定对象为原型创建新的对象。 console.log(obj1);//{sex: "男"} console.log(Object.getOwnPropertyDescriptor(obj1, 'sex')); //{value: "男", writable: false, enumerable: false, configurable: false} var obj2 = {}; //通过definedProperty定义的对象 Object.defineProperties(obj2, {'wife2':{value:'lbb',}, 'wife3':{value:'zdy'} }); console.log(obj2);//{wife2: "lbb", wife3: "zdy"} console.log(Object.getOwnPropertyDescriptor(obj2, 'wife2')); //{value: "lbb", writable: false, enumerable: false, configurable: false}
属性描述符设置方式
属性描述符设置的区别如果是字面量形式定义对象;此时得到的三种(除了value)属性描述符都为true;即,可配置,可写,可遍历。
var damu = {wife:'fbb'}; var result = Object.getOwnPropertyDescriptor(damu,'wife'); console.log(result); //{value: "fbb", writable: true, enumerable: true, configurable: true} //此时所有的属性描述符都是true
使用Object.defineProperty()定义对象的属性,得到的三种属性描述符都是false(使用creat方法也是);
var damu1 = {}; Object.defineProperty(damu1,'wifeagain',{value:'libb'}); var result = Object.getOwnPropertyDescriptor(damu1,'wifeagain'); console.log(result);//{value: "libb", writable: false, enumerable: false, configurable: false}
注意:当在全局中使用var定义变量以及不使用var定义变量时的属性描述符默认的区别:
使用var在全局中定义变量时,可配置描述符(configurable)为false,即不可配置,剩下的属性描述符(enumberable、writable)为true,即可写、可遍历。
var a=1; var result=Object.getOwnPropertyDescriptor(window,'a'); window.a = 5;//无作用 console.log(result);//{value: 1, writable: true, enumerable: true, configurable: false}
不使用声明在全局中赋值变量时,三个属性描述符都为true,即,可配置、可写、可遍历。
b=2; var result1=Object.getOwnPropertyDescriptor(window,'b'); // 帮助理解:隐含全局变量(无var的)严格来说不是真正的变量,而是全局对象的属性,因为属性可以通过 delete 删除,而变量不可以。 console.log(result1);//{value: 2, writable: true, enumerable: true, configurable: true}
访问描述符
概念
当你给一个属性定义setter或者getter,或者两者都有时,这个属性会被定义为“访问描述符”。对于访问描述符来说,Javascript会忽略他们的value和writable特性。取而代之的是set和get函数。
get: 在读取属性时,调用的函数。在读取属性时调用的函数。只指定get则表示属性为只读属性。默认值为undefined。
注意,get属性只有在调用它掌控的属性的时候,才会被调用该get方法的。
set: 在写入属性时调用的函数。在写入属性时调用的函数。只指定set则表示属性为只写属性。默认值为undefined。
var obj2 = {}; Object.defineProperties(obj2, {'wife2': {get : function () {return 'lbb';}}, 'wife3':{value:'zdy'} } ); obj2.wife2 = 'zly'; obj2.wife3 = 'zly'; console.log(obj2);//{wife3: "zdy"} console.log(obj2.wife2);//lbb console.log(Object.getOwnPropertyDescriptor(obj2, 'wife2')); //{set: undefined, enumerable: false, configurable: false, get: ƒ} console.log(Object.getOwnPropertyDescriptor(obj2, 'wife3')); //{value: "zdy", writable: false, enumerable: false, configurable: false} //set的理解 var obj2 = {}; Object.defineProperties(obj2, {'wife2': {get : function () {return 'lbb';} ,set : function (data) { //此时传入的实参就是想要改变的obj2.wife2的值obj2.wife2 = 'chenhao'。data就是用来接收它的。 console.log(data);//chenhao } }, 'wife3':{value:'zdy',writable:true} } ); console.log(obj2.wife2);//lbb obj2.wife2 = 'chenhao'; console.log(obj2.wife2);//lbb //set和get理解 var obj2 = {}; Object.defineProperties(obj2, {'wife2': {get : function () { this.value = 80; //return出的值是什么,obj2.wife2的结果就会是什么。 return this.value; } ,set : function (data) { //data用来接收修改的值,obj2.wife2 = 'chenhao'; console.log(data);//chenhao //此时将get中的return出去的值改成data,即chenhao。 //但是注意,因为之前的this.value = 80,这次的赋值覆盖了其它的值,所以输出的依然是80. this.value = data; } },'wife3':{value:'zdy',writable:true} } ); console.l fbd7 og(obj2.wife2);//80 obj2.wife2 = 'chenhao'; console.log(obj2.wife2);//80 //get和set的理解3 var obj2 = {wname:'xiannv1',wname2:'xiannv2'}; Object.defineProperties(obj2, {'wife2': {get : function () { //确定了obj2.wife2输出的值是return后面的内容,即this.wname = 'xiannv1'。 //get是读取对象属性值的方法。obj2对象的wife2通过get得到值。 return this.wname; } ,set : function (data) { //想修改obj2.wife2,通过data接收到修改的属性值。 //set是修改属性值的方法,想要修改obj2.wife2,就是修改get中ruturn的内容,即this.wname。然后将想要修改的属性值data=chenhao,赋值给this.wname。 console.log(data);//chenhao this.wname = data; } }} ); console.log(obj2.wife2);//xiannv1 obj2.wife2 = 'chenhao'; console.log(obj2.wife2);//chenhao
基于对象属性的几大特性
对象常量属性
概念:将属性的writable和configurable设置为false;//将属性的writable和configurable设置为false var damu={}; Object.defineProperty(damu,"wife",{ value:"fbb" }) Object.defineProperty(damu,"wife",{ value:"fbb2" }); //无法更改,无法删除。可以添加 //console.log(damu);//报错,Cannot redefine property damu.wife="damu" delete damu.wife; console.log(damu);//{wife: "fbb"} damu.wife2="fbb2"; console.log(damu);//{wife2: "fbb2", wife: "fbb"}
禁止属性扩展
概念如果一个对象可以添加新的属性,则这个对象是可扩展的,让这个对象变的不可扩展,也就是不能再有新的属性;
由于属性描述符是对属性的管理,所以想禁止对象扩展,不能使用属性描述符来控制,而是需要调用其他的对象的方法。
两种有关对象属性扩展的对象方法:
Object.isExtensible 方法:Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
语法: Object.isExtensible(obj)
参数: obj 需要检测的对象;
默认情况下,创建的对象默认是可扩展
//新对象默认是可扩展的无论何种方式创建的对象 //使用的是字面量方式 var empty = {a:1}; console.log(Object.isExtensible(empty) === true);//true //等价于 使用属性描述符 empty = Object.create({},{ "a":{ value : 1, configurable : true,//可配置 enumerable : true,//可枚举 writable : true//可写 } }); console.log(Object.isExtensible(empty) === true);//true //创建属性的方式 var damu={}; Object.defineProperty(damu,"wife",{ value:"fbb" }) console.log(Object.isExtensible(damu) === true);//true
Object.preventExtensions 方法:方法让一个对象变的不可扩展,也就是永远不能再添加新的属性,并且返回原对象。
语法:Object.preventExtensions(obj);
参数:obj 将要变得不可扩展的对象;
var damu = {}; Object.defineProperty(damu,'wife',{ value:'lbb' }); console.log(damu);//{wife: "lbb"} Object.preventExtensions(damu); // damu.age = 18; // console.log(damu);//{wife: "lbb"} (function fail(){ "use strict"; damu.d = "4";//throws a TypeError })(); console.log(damu);//Cannot add property d, object is not extensible
描述:
如果一个对象可以添加新的属性,则这个对象是可扩展的。preventExtensions 可以让这个对象变的不可扩展,也就是不能再有新的属性。
需要注意的是不可扩展的对象的属性通常仍然可以被删除。
尝试给一个不可扩展对象添加新属性的操作将会失败,不过可能是静默失败(默认情况),也可能会抛出 TypeError 异常(严格模式)。
注意:Object.preventExtensions 只能阻止一个对象不能再添加新的自身属性,仍然可以为该对象的原型添加属性。
密封对象
概念:密封对象是指那些不可扩展的,且所有自身属性都不可配置的(non-configurable)对象。
或者可以说,密封对象是指那些不能添加新的属性,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可能可以修改已有属性的值的对象。
可用方法:在禁止对象扩展(Object.preventExtensions(obj);的基础上把现有属性的configurable都调整为false;
//设置对象即使不可扩展又不可配置 var damu = {}; Object.defineProperty(damu,'wife',{ value:'lbb' //此时默认的configurable和writable都为false的。 }); console.log(damu);//{wife: "lbb"} Object.preventExtensions(damu); damu.age = 18; delete damu.wife;//{wife: "lbb"} console.log(damu);//{wife: "lbb"}; //证明不可配置、不可扩展。但是这种设置的过程很麻烦,尝试使用简单的对象方法来设置密封对象。
两种有关密封属性的方法
Object.isSealed 方法:方法判断一个对象是否是密封的(sealed)。
语法 :Object.isSealed(obj);
参数:obj 将要检测的对象;
描述:如果这个对象是密封的,则返回 true,否则返回 false。
//使用Object.preventExtensions设置为不可扩展,再设置不可配置,则成为密封了。 var damu = {}; Object.defineProperty(damu,'wife',{ value:'lbb' //此时默认的configurable和writable都为false的。 }); Object.preventExtensions(damu); console.log(Object.isSealed(damu));//true
Object.seal() 方法:可以让一个对象密封,并返回被密封后的对象。
语法:Object.seal(obj)
参数:obj 将要被密封的对象
var damu = {}; Object.defineProperty(damu,'wife',{ value:'lbb' //此时默认的configurable和writable都为false的。 }); console.log(Object.getOwnPropertyDescriptor(damu,"wife"));//{value: "lbb", writable: false, enumerable: false, configurable: false} Object.seal(damu); console.log(Object.isSealed(damu));//true //静默失败 damu.d = 'd'; delete damu.wife; console.log(damu);//{wife: "lbb"} console.log(Object.getOwnPropertyDescriptor(damu,"wife"))
描述:
通常情况下,一个对象是可扩展的(可以添加新的属性)。
密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。
属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。
尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出TypeError 异常(严格模式)。
不会影响从原型链上继承的属性。但 proto ( ) 属性的值也会不能修改。
冻结对象
概念:一个对象是冻结的(frozen)是指它不可扩展,所有属性都是不可配置的(non-configurable),且所有数据属性(data properties,指那些没有取值器getter或赋值器setter的属性)都是不可写的(non-writable);
或则说 冻结对象是指那些不能添加新的属性,不能修改已有属性的值,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性的对象。也就是说,这个对象永远是不可变的;
可用方法:在密封对象(Object.seal(obj))的基础上把现有属性的writable都调整为false:
//在密封对象(Object.seal(obj))的基础上把现有属性的writable都调整为false var damu = {}; Object.defineProperty(damu,'wife',{ value:'lbb', //writable:true }); //密封 Object.seal(damu); //防扩展 Object.preventExtensions(damu); damu.age = 18; delete damu.wife; damu.wife = 'zdy'; console.log(damu);//{wife: "lbb"};
两种有关密封属性的方法
Object.isFrozen 方法:方法判断一个对象是否被冻结(frozen)。
语法: Object.isFrozen(obj)
参数:obj 被检测的对象
Object.freeze() 方法:可以冻结一个对象。
语法:Object.freeze(obj);
参数:obj 将要被冻结的对象;
var damu = {wife:'lbb'}; console.log(Object.getOwnPropertyDescriptor(damu,"wife")); //{value: "lbb", writable: true, enumerable: true, configurable: true} //冻结对象 Object.freeze(damu); console.log(Object.getOwnPropertyDescriptor(damu,"wife")); //{value: "lbb", writable: false, enumerable: true, configurable: false} damu.age = 18; delete damu.wife; damu.wife = 'zdy'; console.log(damu);//{wife: "lbb"}
描述:
冻结对象的所有自身属性都不可能以任何方式被修改。
任何尝试修改该对象的操作都会失败,可能是静默失败,也可能会抛出异常(严格模式中)。
数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。
如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。
//浅不变形 var damu={wifes:{wife1:"fbb",wife2:"lyf",wife3:"zdy"}}; damu.wifes.wife1="lbb"; console.log(damu);//wifes:{wife1: "lbb", wife2: "lyf", wife3: "zdy"} //深层次冻结 var damu={ wifes:{wife1:"fbb",wife2:"lyf",wife3:"zdy"} }; Object.freeze(damu); //遍历调用冻结方法,将对象属性内的对象全部冻结。 for(item in damu){ Object.freeze(damu[item]); } damu.wifes.wife1="lbb"; console.log(damu);//wifes:{wife1: "fbb", wife2: "lyf", wife3: "zdy"}
对象属性的遍历
三种方式obj.propertyIsEnumerable(属性名);
判断是否可遍历出指定的对象属性;
如果设置的是不被遍历,则直接返回false;
Object.keys(obj);
检索所有的可被检索的对象属性;
返回值是所有的属性名组成的数组;
Object.getOwnPropertyNames(obj);
检索所有的对象属性,无论是否可被检索;
返回值是所有的属性名组成的数组;
var damu={wifes:{wife1:"1"}}; Object.defineProperty(damu,"a",{enumerable:true}) Object.defineProperty(damu,"b",{enumerable:false}) Object.defineProperty(damu,"c",{enumerable:true}) Object.defineProperty(damu,"d",{enumerable:false}) Object.defineProperty(damu,"e",{enumerable:true}) Object.defineProperty(damu,"f",{enumerable:false}) Object.defineProperty(damu,"g",{enumerable:true}) console.log(damu.propertyIsEnumerable("f"));//false 判断是否可遍历出这个对象属性 console.log(Object.keys(damu));// ["wifes", "a", "c", "e", "g"] 检索所有的可被检索的对象属性名 console.log(Object.getOwnPropertyNames(damu));//["wifes", "a", "b", "c", "d", "e", "f", "g"] 检索所有的属性名,无论是否可被检索
对象的设置和获取
伪数组
var wei = {length:3,0:0,1:1,2:2}; var arr =Array.prototype.slice.call(wei); //Array.prototype.slice()新截取的一个空数组。尽量不要定义新数组,这样可以节省空间。 console.log(Array.prototype.slice()); console.log(Array);//数组函数 ƒ Array() { [native code] } arr.push(3); console.log(arr); //常用定义兼容方法 function test(arr,fn){ arr =arr||Array.prototype; fn =fn||Function.prototype; return arr.map(fn).join(" "); } console.log(test());
相关文章推荐
- 对象的查询和设置(JS高级)
- 对象的查询和设置(JS高级)
- 对象的查询和设置(JS高级)
- 对象的查询和设置(JS高级)
- 对象的查询和设置(JS高级)
- 对象的查询和设置(JS高级)
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
- MongoDB高级查询(二):对一个表中的2个字段中的"内嵌对象"中的字段进行比较----------- aggregate聚合查询
- js面向对象程序设置
- js高级——原型对象继承的实现
- js 高级对象
- JavaScript高级程序设计(第3版)学习笔记6 初识js对象
- js高级篇1之prototype原型对象的应用
- 快速获取/设置iframe内对象元素的几种js实现方法
- JS获取/设置iframe内对象元素、文档的几种方法
- 《JS高级程序设计》PART3.对象基础
- JavaScript高级程序设计(第3版)学习笔记11 内建js对象
- JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
- JS高级程序设置笔记(一)
- JS高级程序设计--读书笔记(js对象创建)