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

js-面向对象------属性类型

2017-08-14 10:36 253 查看
JS内部在定义只有内部才用的特性时,描述了对象属性的各种特征,我把这些特征分为两种属性类型:数据属性,访问器属性

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('访问器类型')
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 属性 对象