js-面向对象------属性类型
2017-08-14 10:36
253 查看
JS内部在定义只有内部才用的特性时,描述了对象属性的各种特征,我把这些特征分为两种属性类型:数据属性,访问器属性。
1,数据属性
通常我们通过字面量这种方式定义一个对象的时候,其属性都是数据类型的,比如:
这段代码等于下面这一段
我们看到了其执行结果是一样的。通过上面的代码可以看到数据属性是包含了4种特性的,下面来介绍一下这4种特性:
1 , [ [ Configurable ] ] 表示能否使用delete删除属性,能否修改属性的特性,或者能否把属性修改成访问器属性。用字面量来定义属性时,其值默认为true
2 , [ [ Enumerable ] ] 表示能否通过for-in遍历返回属性。用字面量来定义属性时,其值默认为true
3,[ [ Writable ] ] 表示能否修改属性的值。用字面量来定义属性时,其值默认为true
4 , [ [ Value ] ] 这个包含了属性所对应的值,写入和读取属性的值时,都会使用该值。默认值是undefined,但是在我们用字面量来创建属性的时候就已经给它赋值了,
如果我们要修改属性的这些默认特性,应该使用defineProperty方法,在上面我们使用该方法创建了一个属性,现在也可以使用这个方法来修改属性的默认特性。
在非严格模式下,赋值操作将被忽略。在严格模式下,赋值操作将会导致报错。
如果将Configuarble设置为false后,将不能通过delete删除该属性。而一旦把这个属性定义为不可配置,就在也不能把它变为可配置了,此时再修改除Writable之外的特性,都会导致报错
2,访问器属性
访问器属性也包含了4种特性,下面介绍这4种特性:
1 ,[ [ Configurable ] ] 表示能否使用delete删除属性,能否修改属性的特性,或者能否把属性修改成数据属性。用字面量来定义属性时,其值默认为true
2 ,[ [ Enumerable ] ] 表示能否通过for-in遍历返回属性。用字面量来定义属性时,其值默认为true
3,[ [ Get ] ] 在读取属性时调用的方法,默认值为undefined
4,[ [ Set ] ] 在写入属性时调用的方法,默认值为undefined
访问器属性不能直接定义,需要通过Object.defineproperty()来定义,看下面的例子:
首先我们访问了updateAll属性,将其值设置为2005,这个时候触发了该属性定义的set方法。其this指向了对象本身,在该方法里将对象book的属性year设置为2005,edition设置为1+2005-2004。在最后读取updateAll的时候,调用了get方法,返回了book对象。
set方法的参数自动接收一个将要设置的值
不一定要同时指定get和set。但是只指定get,意味着该属性是只读的,在严格模式下尝试修改该属性,将会导致错误。相反,如果只指定set,会造成该属性不能读。
在defineProperty这个方法之前,要创建访问器属性,一般都是两个非标准的方法,_defineGetter()_,_defineSetter_()这两个方法来实现。
3,定义多个属性
在实际开发过程中,通常会遇到一次定义多个属性的情况。这个时候我们就需要使用到Object.defineProperties这个方法 。该方法,第一个参数是一个需要添加和修改属性的对象,第二个参数是所要添加或者修改到第一个参数的对应属性。例如:
在使用defineProperty,defineProperties定义属性的过程中如果没有给configurable,enumerable赋值的话,默认将会是false。
该方法只支持IE9+以及其他的现代浏览器
4,获取属性的特性
之前设置了属性的特性,现在来谈谈如何获取对象属性的特性。
js 提供了一个方法:Object.getOwnPropertyDescriptor(),需要两个参数,第一个参数是需要获取属性特性的对象,第二个参数是需要获取属性描述符的属性名称。例如:
数据属性会返回value,writable等属性,而访问器属性则会返回get,set等属性。
判断对象属性是什么类型:
1,数据属性
通常我们通过字面量这种方式定义一个对象的时候,其属性都是数据类型的,比如:
var a = { name : 'javascript' } console.log(a.name) // ===>'javascript'
这段代码等于下面这一段
var a = {} Object.defineProperty(a,'name',{ Configurable : true, Enumerable : true, Writable : true, value : 'javascript }) console.log(a.name) //===>'javascript'
我们看到了其执行结果是一样的。通过上面的代码可以看到数据属性是包含了4种特性的,下面来介绍一下这4种特性:
1 , [ [ Configurable ] ] 表示能否使用delete删除属性,能否修改属性的特性,或者能否把属性修改成访问器属性。用字面量来定义属性时,其值默认为true
2 , [ [ Enumerable ] ] 表示能否通过for-in遍历返回属性。用字面量来定义属性时,其值默认为true
3,[ [ Writable ] ] 表示能否修改属性的值。用字面量来定义属性时,其值默认为true
4 , [ [ Value ] ] 这个包含了属性所对应的值,写入和读取属性的值时,都会使用该值。默认值是undefined,但是在我们用字面量来创建属性的时候就已经给它赋值了,
如果我们要修改属性的这些默认特性,应该使用defineProperty方法,在上面我们使用该方法创建了一个属性,现在也可以使用这个方法来修改属性的默认特性。
var a = { name : 'javascript' } Object.defineProperty(a,'name',{ writable : false //修改该属性为不可修改 }) a.name = 'php' console.log(a.name) // ===>'javascript'
在非严格模式下,赋值操作将被忽略。在严格模式下,赋值操作将会导致报错。
如果将Configuarble设置为false后,将不能通过delete删除该属性。而一旦把这个属性定义为不可配置,就在也不能把它变为可配置了,此时再修改除Writable之外的特性,都会导致报错
2,访问器属性
访问器属性也包含了4种特性,下面介绍这4种特性:
1 ,[ [ Configurable ] ] 表示能否使用delete删除属性,能否修改属性的特性,或者能否把属性修改成数据属性。用字面量来定义属性时,其值默认为true
2 ,[ [ Enumerable ] ] 表示能否通过for-in遍历返回属性。用字面量来定义属性时,其值默认为true
3,[ [ Get ] ] 在读取属性时调用的方法,默认值为undefined
4,[ [ Set ] ] 在写入属性时调用的方法,默认值为undefined
访问器属性不能直接定义,需要通过Object.defineproperty()来定义,看下面的例子:
var book = { year: 2004, edition: 1 } Object.defineProperty(book, 'updateAll', { get: function () { return book;//此处可以自定义 别人访问时候返回什么,如果什么都不写 就代表这个属性不让访问 }, set: function (val) { if (val > 2004) { this.year = val; this.edition += val - 2004; } } }); book.updateAll = 2005; console.log(book.edition); // ===>2 console.log(book.year); // ===>2005 console.log(book.updateAll); //===>{year:2005,edition:2}
首先我们访问了updateAll属性,将其值设置为2005,这个时候触发了该属性定义的set方法。其this指向了对象本身,在该方法里将对象book的属性year设置为2005,edition设置为1+2005-2004。在最后读取updateAll的时候,调用了get方法,返回了book对象。
set方法的参数自动接收一个将要设置的值
不一定要同时指定get和set。但是只指定get,意味着该属性是只读的,在严格模式下尝试修改该属性,将会导致错误。相反,如果只指定set,会造成该属性不能读。
在defineProperty这个方法之前,要创建访问器属性,一般都是两个非标准的方法,_defineGetter()_,_defineSetter_()这两个方法来实现。
3,定义多个属性
在实际开发过程中,通常会遇到一次定义多个属性的情况。这个时候我们就需要使用到Object.defineProperties这个方法 。该方法,第一个参数是一个需要添加和修改属性的对象,第二个参数是所要添加或者修改到第一个参数的对应属性。例如:
var book = {} Object.defineProperties(book,{ author : { writable : true, value : 'pojie' }, content :{ get :function(){ return this }, set :function(){ this.author = 'liuGG' } } })
在使用defineProperty,defineProperties定义属性的过程中如果没有给configurable,enumerable赋值的话,默认将会是false。
该方法只支持IE9+以及其他的现代浏览器
4,获取属性的特性
之前设置了属性的特性,现在来谈谈如何获取对象属性的特性。
js 提供了一个方法:Object.getOwnPropertyDescriptor(),需要两个参数,第一个参数是需要获取属性特性的对象,第二个参数是需要获取属性描述符的属性名称。例如:
var book = {}; Object.defineProperties(book,{ author : { writable : true, value : 'pojie' }, authorAge : { writable : true, value : '20' }, edition : { get : function(){ return this; }, set : function(val){ if(val > 1995){ this.authorAge = '20+' } } } }) var descriptor = Object.getOwnPropertyDescriptor(book,'authorAge'); console.log(descriptor) //===>{ value: '20', writable: true,enumerable: false,configurable: false } var descriptor2 = Object.getOwnPropertyDescriptor(book,'edition'); console.log(descriptor2 )//==>{ get: [Function: get],set: [Function: set],enumerable: false,configurable: false }
数据属性会返回value,writable等属性,而访问器属性则会返回get,set等属性。
判断对象属性是什么类型:
//引用上面的descriptor 对象 if(descriptor.value){ console.log('数据类型') }else{ console.log('访问器类型') }
相关文章推荐
- js面向对象(一)-类的四种类型属性及使用
- js面向对象一些不为人知的属性类型
- JS基础之String包装类型的属性和方法
- js中判断数据类型的属性typeof、instanceof、 constructor、 prototype
- 关于数据序列化(5),定制FastJSON序列化(解决Java大Long类型js的Number接收丢失数据的问题,不序列化某些属性)
- 面向对象(属性,值类型和引用类型,常量,静态成员)
- JS中的属性类型理解
- JS前端检测上传文件类型以及属性大小,并生成预览
- js里面的属性和方法类型
- javascript自学之路(四)————js对象类型之prototype属性的探索
- JS模拟面向对象全解(二、类型与赋值)
- JS面向对象的数据属性的用法
- [用js写java jvm]1.js解析java bean中的属性和基本类型
- js中为什么不能为值类型的变量动态添加属性呢?
- js面向对象---基本的概念、属性、方法
- JS模拟面向对象全解(一、类型及传递)
- js面向对象之静态方法和静态属性实例分析
- js高级程序设计笔记 -- 属性类型以及创建对象
- JavaScript高级程序设计【面向对象-属性类型】
- JS通过分析userAgent属性来判断浏览器的类型及版本