JS面向对象篇1、理解对象及属性特性(属性描述符)

本文内容
一、理解对象;
二、ECMAScript有两种属性类型:数据属性和访问器属性(getter和setter函数);
三、数据属性的属性特性:[[Configurable]]、[[Enumerable]]、[[Writable]]、[[value]];
四、访问器属性的属性特性:[[Configurable]]、[[Enumerable]]、[[get]]、[[set]];
五、Object.defineProperty()、Object.defineProperties()、Object.getOwnPropertyDescriptor()设置或读取属性特性(属性描述符)的方法javascript

理解对象

ECMA-262把对象定义为:无序属性的集合,其属性能够包含基本值、对象或者函数。 也就是说对象是一组没有特定顺序的名值对,一个名字对应一个值,值能够是数据(包括基本值以及引用类型值)和函数,每个名值对都是这个对象的属性。java

var person = {
	name: 'youyang',
	age: 25,
	job: 'coder',
	sayName: function() {
		console.log(this.name)
	}
}
复制代码

以上代码建立了一名为person的对象,它有四个属性:name、age、job和sayName。注意虽然一般咱们说name、age、job为属性,而sayName称做person对象的方法,其实它也是属性,只不过值为函数而已。框架

属性类型及属性特性

一、首先须要明确javascript对象中有哪些属性类型?

ECMAScript中有两种属性:数据属性和访问器属性。函数

二、什么是属性特性?

每一个对象的属性(包括方法)在建立时都带有一些特征值,ECMA-262定义这些特性值是为了实现javascript引擎用的,即内部使用的,因此该规范把它们放在两对方括号中:如[[Enumerable]]。ui

三、那么属性都有哪些描述行为的特性呢?不一样的属性类型的属性特性又有什么不一样呢?

数据属性

数据属性有四个描述其行为的特性:this

  1. [[configurable]]:表示可否经过delete关键字删除属性从而从新定义属性,可否修改属性的特性(包括[[configurable]]特性自己以及下面三个其余特性),或者可否把属性修改成访问器属性。像上面例子中那样直接定义在对象上的属性默认值为true.
  2. [[Enumerable]]:是否可枚举(for-in循环中可否返回该属性),上面那样直接定义在对象上的属性默认值为true。
  3. [[Writable]]:是否可修改属性的值,默认为true;
  4. [[value]]:对应属性值,读取的时候从这里读取,写入的时候将新值保存在这里,默认值为undefined;
var obj = {
	num: 10
}
复制代码

这里建立了一个名为num的属性,它的 [[configurable]]、 [[Enumerable]]、 [[Writable]]均为true,而[[value]]为10。spa

访问器属性

相比数据属性,访问器属性没有[[value]]这一属性特性,而是拥有一对函数:getter()和setter(),在读取访问器属性的时候,调用getter(),该函数负责返回有效的值,在写入即设置属性的值的时候调用setter()并传入新值,由setter()负责执行处理数据的操做。code

访问器属性包含4个属性特性:对象

  1. [[configurable]]:表示可否经过delete删除属性,可否修改属性的特性(包括[[configurable]]特性自己以及下面三个其余特性),或者可否把属性修改成数据属性。直接定义在对象上的属性默认值为true;
  2. [[Enumerable]]:是否可枚举(for-in循环中可否返回该属性),上面那样直接定义在对象上的属性默认值为true;
  3. [[Get]]:在读取属性时调用的函数,默认为undefined;
  4. [[Set]]:在写入属性时调用的函数,默认为undefined。

Object.defineProperty()

这个方法有两个做用,一个是修改属性的默认属性特性,另外一个就是定义属性,由于若是你想在定义一个属性的同时指定它的一些属性特性那么就必须使用这个方法,而且当你想定义一个访问器属性时只能使用Object.defineProperty()来实现,由于访问器属性是不能直接定义的。 此方法接收的参数:对象,指定的属性名称,一个描述符对象(用来设置属性特性的对象) 使用方法以下: 一、要修改一个属性的默认特性ip

var obj = {
	num: 10
}
Object.defineProperty(obj, 'num', {
	value: 20,
	writable: false
})
console.log(obj.num) // 20
obj.num = 30
console.log(obj.num) // 20
复制代码

上面的例子中,咱们将对象obj的属性num的[[writable]]是否可修改特性设置为了false,因而num属性不能被修改,当尝试为它写入新值(obj.num = 30)时,非严格模式下,此操做会被忽略,严格模式下则会报错。

二、定义访问器属性 访问器属性不能直接定义,必须使用Object.defineProperty()。

var obj = {
	num: 10
}
Object.defineProperty(obj, 'data', {
	get: function() {
		return this.num
	},
	set: function(newVal) {
		if (newVal > 10) {
			this.num = newVal
		}
	}
})
console.log(obj.data) // 10
obj.data = 20
console.log(obj.data) // 20
console.log(obj.num) // 20
复制代码

getter和setter函数或许你常据说,可是并不知道它们究竟是什么,由于咱们确实在平常开发中不多有机会用到它们,可是在一些框架的源码中常见到它们的应用。

Object.defineProperties()

与Object.defineProperty()方法相同,Object.defineProperties()方法也有一样做用:设置和修改属性特性,只不过Object.defineProperties()方法能够设置多个属性。 使用方法以下:

var obj = {
	num: 10
}
Object.defineProperties(obj, {
	name: {
		writable: false,
		value: '张三'
	},
	data: {
		get: function () {
			return this.num
		},
		set: function (newVal) {
			if (newVal > 10) {
				this.num = newVal
			}
		} 
	}
})
复制代码

以上代码使用Object.defineProperties()定义了一个数据属性和一个访问器属性。

Object.getOwnPropertyDescriptor()

这个方法的做用就是获取指定属性的属性描述符,所谓属性描述符就是咱们以前一直提到的属性特性。 接收两个参数:属性所在对象和指定属性名称 返回值:一个对象,若是是访问器属性,对象的属性包括:configurable,enumerable,get和set,若是是数据属性,则返回的这个对象的属性有:configurable,enumerable,writable,value。

var obj = {
	num: 10
}
console.log(Object.getOwnPropertyDescriptor(obj, 'num')) // {value: 10, writable: true, enumerable: true, configurable: true}
复制代码
相关文章
相关标签/搜索