JavaScript红宝书第8章:对象、类与面向对象编程(1/4)

理解对象

定义:对象为一组属性的无序集合,严格来说,对象就是一组没有特定顺序的值。它的每个属性或方法都由一个特定的名称来标识,一个名称映射到一个值,这个值可以是函数或数组,也可以是普通的原始值。
使用对象字面量创建对象实例:

let obj={
	name:'Jack',
	age:18,
	eat(){
		console.log('Eating')
	}
}

还可以使用new Object()创建对象,这里就不赘述了,上述就是对象的name、age就是对象的具体属性,而eat则是一个方法。这个方法用于打印出Eating值。

属性类型

属性类型是指用于描述属性特征的内部属性,一般用双重中括号进行标识,不能用JavaScript进行显性调用出来,了解这些只是为了更好的使用JavaScript开发。属性分两种,数据属性和访问器属性。

数据属性

数据属性包含一个保存数据值的位置,值会从这个位置读取和写入,数据属性中有四个特性描述它们的行为。
[[configurable]]:属性是否可以通过delete删除,是否可以修改成访问器属性,是否可以修改它的特性,默认都为true。
[[Enumerable]]:是否可以通过for-in遍历,默认都为true。
[[Writable]]:属性值是否可以被修改,默认都为true。
[[value]]:包含属性实际值,这就是刚才提到的读取和写入数据的值,默认值为undefined。
举例:

let obj={
	name:'Jack'
}

我们定义了一个属性name值为Jack,而这个值就会放在[[value]]这个位置中,无论这个值如何修改或删除都会放在[[value]]这个位置中。

如果想要修改属性的默认特征,可以通过Object.defineProperty属性,举例

let obj={}
Object.defineProperty(obj,'name',{
	writable:false,
	value:'Tom'
})
console.log(obj.name);//Tom
obj.name='Jack'
console.log(obj.name);//Tom

在上述代码中,我们可以发现,在defineProperty属性中定义name的内部特性writeable为false后,name就不能被修改了,在非严格模式下,它不会报错,只会忽略,但是在严格模式下,它会报错。而其他属性也是一样的。

访问器属性

访问器属性不包含数据值,它们包含一个获取get和一个设置set函数,这两个函数不是必需的,这两个函数默认值为undefined。
get函数是在属性读取时候会默认调用,set函数则是在写入属性时会默认调用。举例:

let obj={
	name:'Tom'
}
Object.defineProperty(obj,'newName',{
	get(){
		return this.name+this.name;
	},
	set(newValue){
		this.name=newValue+'Tom'
	}
})
console.log(obj.newName);//TomTom
obj.newName='Jack'
console.log(obj.newName);//JackTomJackTom

上述代码中,我们重构了set和get方法,在get方法中,我们令newName属性获取值,等于两个name属性值,而set更新方法中,我们让name属性值等于修改后newName属性值。

定义多个属性

语法:Object.defineProperties
如果想定义多个属性并且设置它们的数据特性和访问器属性时,可以使用上述方法。

let obj={
			name:'Tom'
		}
		Object.defineProperties(obj,{
			age:{
				value:18
			},
			food:{
				value:'coco happy'
			},
			method:{
				get(){
					return age;
				},
				set(){
					aget=++method;
				}
			}
		})

最终的值,是不可修改、不可删除、不可使用for-in迭代器的。也就是说,使用definedProperty或者definedProperties,默认所有属性都为false,而不是都为true。所以在慎用这两个属性。

读取属性特征

语法:Object.getOwnPropertyDescriptor()

let obj={
	name:'Tom'
}
let description=Object.getOwnPropertyDescriptor(obj,'name')
console.log(description.value);//Tom
console.log(description.configurable);//true
console.log(description.enumerable);//true
console.log(description.get);//undefined
console.log(description.set);//undefined
console.log(description.writable);//true

这个方法传递一个对象则输出这个对象的所有属性的特性值,传递一个对象加其中的一个属性名,则输出该属性的特性值。

合并对象

Object.assign(合并对象,被合并对象)
它只能实现一层深拷贝,多层就变浅拷贝了,深拷贝就是指复制对象中属性值发生改变,原对象属性值不变,浅拷贝就是说复制对象属性值发生改变,原对象属性值也改变,深浅就在于它俩是否在同一个内存空间中,浅拷贝是把它的引用和内存空间都复制了,而深拷贝是把它的引用复制到新对象的内存空间中。实现深拷贝可以通过序列化、反序列化和递归操作实现,这里就不赘述了。

let obj={
	name:'Tom',
	food:{
		drink:'coco'
	}
}
let newObj=Object.assign({},obj)
newObj.name='tom'
newObj.food.drink='jojo'
console.log(newObj.name,obj.name);//tom Tom
console.log(newObj.food.drink,obj.food.drink);//jojo jojo

对象标识及相等判定

ES6新推出的用于相等判定方法,Object.is(参数,参数)返回的是true、false;

console.log(Object.is(NaN, NaN)); // true

对象新语法

ES6新增对象语法

属性值简写

let name='tom'
let obj={
	name
}

动态给属性命名

let miniName='name'
let obj={}
obj[miniName]='Tom'
console.log(obj.name);//Tom

简写方法

ES6前,需要用 匿名函数方式写对象方法,方法名:function(){},ES6中则简化成
方法名(){}

对象解构

ES6前

let person={
	name:1,
	name1:2,
}
let name=person.name,name1=person.name1;

let {name:name,name1:name1}=person

小结

本章主要讲解红宝书第八章第一部分对象。包含对象内部特性和对象的一些新语法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃巧克li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值