Object 以及 object 的属性类型

本文探讨JavaScript中的对象创建方式,包括使用Object构造函数和字面量语法,并着重讲解对象的属性类型,如数据属性和访问器属性。数据属性涵盖[[Configurable]]、[[Enumerable]]、[[Writable]]和[[Value]]特性,而访问器属性则包含[[Get]]和[[Set]]函数。文章还介绍了如何使用Object.defineProperty()和Object.defineProperties()进行属性特性的修改和多个属性的定义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面向对象语言的的特性就是有类(class)的概念,通过类可以创建任意多个具有相同属性或方法的对象,然而 javascript 中没有类(class)的概念,所以它不是真正的面向对象

对象

由N组键值对组合起来的无序属性顺序的结合,其属性值可以是任意类型。

//采用生成一个 Object 的实例来创建一个对象

var obj = new Object();
obj.name = "大毛";
obj.eat = function(){
    console.log("吃鱼")
}

//采用字面量方式创建新对象

var obj = {
    name: "大毛",
    eat: function(){
        console.log("吃鱼")
    }
}

以上我我们利用 Object 的构造函数和字面量方式创建了单个对象,但,这种模式创建出来的对象有个明显的缺陷:

同一个接口创建多个对象,会有很多重复代码,那如何解决呢?带着这个问题,我们继续探究…

属性类型

数据属性
修改获取属性值时

  • [[Configurable]] :是否能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,能够把属性改为访问器属性。能够直接在对象上定义的属性,默认值是true
  • [[Enumerable]] : 能否通过 for-in 循环返回属性。能够直接在对象上定义的属性,默认值是true
  • [[Writable]] : 能否修改属性的值,能够直接在对象上定义的属性,默认值是true
  • [[Value]] :属性的值,读取属性时,从这里读,写入的时候把新值保存在这里,默认是Undefined

修改属性的默认特性,需要使用 Object.defineProperty() ,接受三个参数,属性所在对象、属性名称、描述符对象。描述符对象的属性必须是configurable、enumerable、writable、value。设置其中的一个或多个值

Object.defineProperty() 是 IE8 最先实现的,但这个版本只能在DOM对象上使用,而且只能创建访问器属性,由于实现的不彻底,不建议在 IE8 使用。

var person = {}
Object.defineProperty(person,"name",{
	writeable:false, //不能修改属性值,严格模式下会报错,非严格忽略修改的值
	configurable:false,//不能删除该属性
	value:"Nic"
})
alert(person.name) //Nic
person.name = "Gre";
alert(person.name); //Nic
delete person.name;//返回false,不能够删除属性
alert(person.name); //Nic

访问器属性
访问器属性不包含数据值,他们包含一对 getter 和 setter 函数(但这2个函数不是必须),在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值,在写入访问器属性时,会调用 setter 函数并传入新值,这个函数负责如何处理新值。

访问器属性具体 4 个特性:

  • [[Configurable]] :能否通过 detele 删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改为数据属性,对于直接在对象上定义的属性,默认值是 true
  • [[Enumerable]] :能否通过 for-in 循环返回属性列表,对于直接在对象上定义的属性,默认值是 true
  • [[Get]] :在读取属性时调用的函数,默认值是 Undefined。
  • [[Set]] :在写入属性时调用的函数,默认值是 Undefined。

访问器属性不能直接定义,只能用 Object.defineProperty() 来定义

var book = {
_year:2004,
edition:1
}
Oject.defineProperty(book,"year",{
	get:function(){
		return this._year;
	}
	set:function(){
		if(newValue > 2004){
			this._year = newValue;
			this.edition  += newValue - 2004;
		}
	}
})
book.year = 2005;
alert(book.edition); //2

_year 前面的下划线是一种常用的记号,表示只能通过对象方法访问的属性。而访问器属性 year 包含一个 getter 和 setter 函数。getter 函数返回 _year 属性的值,setter 函数则通过计算来确定正确的版本。因此 this.edition 会变成2,这是使用访问器属性的常见方式,设置一个属性的值会导致其他属性发生变化。

不一定非要同时指定这2个函数,只指定 getter 意味属性不能写,严格模式下写入会报错,非严格下忽略。只指定了 setter 函数属性不能读,严格模式下会报错,非严格下返回Undefined。

在不支持 Object.defineProperty() 方法的浏览器中不能修改 [[Configurable]] 和 [[Enumerable]]

Object.defineProperies() 可以通过描述符一次定义多个属性。接受2个参数,一个对象的要添加的和修改的属性的对象。第二个是对象的属性与第一个对象中添加和修改的属性一一对应
这样定义的属性都是同一时间创建的。

var book = {}
Object.defineProperies(book,{
	_year:{
		value:2004
	}
	edition:{
		value:1
	}
	year:{
		get:function(){
			return this._year;
		}
		set:function(){
			if(newValue > 2004){
				this._year = newValue;
				this.edition  += newValue - 2004;
			}
		}
	}
})

读取属性特性
Object.getOwnPropertyDescriptor() 方法,可以取得属性的描述。接受2个参数,属性所在对象和读取描述符的属性名称。返回值是一个对象。

如果是访问器属性,这个对象的属性有,configurable、enumerable、get 和 set。
如果是数据属性,这个对象的属性有,confiurable、enmuerable、writable 和 value。

var obj = {}
obj.name = 22;
Object.getOwnPropertyDescriptor(obj,"name") 
// {value: 22, writable: true, enumerable: true, configurable: true}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值