ES6对象、数组

前言

今天给大家介绍ES6中的对象、数组、函数(方法)新增的一些特性。废话不多说,进入正题!

1.对象

属性和函数的简洁表示法

//属性简洁表示
let name = "liusiyuan";
let age = 20;
const user = {name,age};
console.log(user);//{name:"liusiyuan",age:20}
//等同于
const user = {name:name,age:age};

//方法名简洁表示
let user2 = {
	sayHi(){
		return "Hello!";
	}
};
console.log(user2.sayHi());//Hello!
//等同于
let uoser2 = {
	sayHi:function(){
		return "Hello!";
	}
};

属性名表达式

let a = "say";
let b = "Hi";
let user = {
	[a+b](){//可以用变量名进行拼凑
		return "dashuaibi";
	}
};
console.log(user.sayHi());//输出"dashuaibi"

注意点:属性简洁表示法和属性名表达式不能一起使用,否则会报错!

let sayHi = "sayHi";
let user = {
	[sayHi]
};//SyntaxError: Unexpected token }
//正确用法
let a = "get";
let b = "Name";
let c = "id";
let user = {
	[c]:"1",
	[a+b](){
		return "liusiyuan";
	}
};//{id:1,getName:f[a+b]()}

扩展运算符
(…)用于取出参数对象中的所有可遍历属性拷贝(浅拷贝)到当前对象中

let object = {name:"liusiyuan"};
let object2 = {...object};
console.log(object2);//{name:"liusiyuan"}
//合并二个对象
let object = {name:"liusiyuan"};
let object2 = {age:20};
let user = {...object,...object2,weight:100};
console.log(user);//{name:"liusiyuan",age:20,weight:100}

注意点
当自定义属性和扩展运算符对象里的属性相同时(方法名相同时也是一样):当自定义属性在后面时,则覆盖掉扩展运算符对象里相同属性名的值。

let object = {name:"liusiyuan"};
let user = {...object,name:"lsy",age:20};//自定义属性在后面
console.log(user);//{name:"lsy",age:20}

自定义属性在前面,且属性名相同时,则使用扩展运算符的属性作为默认值。

let object = {name:"liusiyuan"};
let user = {name:"lsy",age:20,...object};//自定义属性在后面
console.log(user);//{name:"liusiyuan",age:20}

新方法

  • assign(target,source_1,…):将源对象中所有可枚举(可访问)属性拷贝到目标对象中。
  • is(value1,value2):比较两个值是否相等,和(===)基本类似。

1.1:assign()

let target = {name:"liusiyuan"};
let object = {age:20};
let object2 = {weight:100};
Object.assign(target,object,object2);//第一个参数为目标对象,后面所有的参数都为源对象。
console.log(target);//{name:"liusiyuan",age:20,weight:100}

注意点

  • 当目标对象和源对象存在相同属性名(方法名)时,又或者源对象存在相同属性名时,后面的会覆盖前面的属性。
  • 如果只有一个参数,那么会将参数转成对象后返回。如果为对象,那么直接返回该对象。
let target = {name:"liusiyuan"};
let object = {name:"六十元",age:20};
let object2 = {weight:100};
Object.assign(target,object,object2);
console.log(target);//{name:"六十元",age:20,weight:100}
//只有一个参数时
let a = Object.assing("3");
console.log(a);//String{"123"}
typeof(a);//"object"

null和undefined不能转化为对象,所以会报错。(不是第一个参数时,会跳过,不报错。)

//当null、undefined为目标对象时
Object.assign(null,object);
Object.assign(undefined,object);//TypeError: Cannot convert undefined or null to object
//为源对象时
Object.assign(target,null,undefined,object2);//{name:"六十元",weight:100}
Object.assign(target,null,object,object2);//{name:"六十元",age:20,weight:100}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
特别需要注意的是assign方法的拷贝是浅拷贝。这一点和(…)一样。

let object = {name:"lsy"};
let object2 = {age:20};
Object.assign(object,object2);
console.log(object);//{name:"lsy",age:20}
object.age = 25;
console.log(object2);{age:20}
console.log(object);//{name:"lsy",age:20}

通过上面这段代码,大家可能还不太清楚什么是浅拷贝。那么请看下面这段代码。

let object = {name:"lsy"};
let object2 = {age:{age1:20}};
Object.assign(object,object2);
console.log(object);//{name:"lsy",age:{age1:20}}
object.age.age1 = 25;
console.log(object2);//{age:{age1:25}}
console.log(object);//{name:"lsy",age:25}

可以看见我们在object2对象age属性中又声明了一个对象,对象里有个age1的属性。在assign方法进行拷贝时,它只拷贝了一层的属性(也就是浅拷贝)。age属性中的age1属性并没有拷贝到。那么就可以认定为object中的age属性的age1属性还是object2对象中age属性的age1属性的引用地址。

通俗的讲就是**object对象中的age属性里的age1属性的引用地址还是object2对象中age1属性的引用地址。**所以当我们修改了object对象中的age1属性的值,object2对象中的age1属性值也会改变。

我们怎么解决这种问题呢?当然,有浅拷贝,就有深拷贝。下面给大家介绍一种简单粗暴的一种深拷贝方法。

let object = {name:"lsy"};
let object2 = {age:{age1:20}};
Object.assign(object,JSON.parse(JSON.stringify(object2)));
console.log(object);//{name:"lsy",age:{age1:20}}
object.age.age1 = 25;
console.log(object2);//{age:{age1:20}}
console.log(object);//{name:"lsy",age:25}

这种方法,对于正则表达式类型和函数类型等就无法进行深拷贝了。

数组的处理

Object.assign([23,32],["六十元","大帅比",666]);//["六十元","大帅比",666]

在这里插入图片描述
首先会将[23,32]数组转换成对象{0:23,1:32},接着将[“六十元”]也转换成对象{0:“六十元”,1:“大帅比”,2:666}。这时就出现了属性同名的情况,上面也说过,当属性同名时,后面的属性会覆盖前面的属性。所以结果为[“六十元”,“大帅比”,666]。

1.1:is():比较两个值是否相等,和(===)基本类似。

Object.is(32,32);//true
Object.is("sdf","sdf");//true
Object.is([0],[0]);//false
let object = {name:"666"};
let object2 = object;
Object.is(object,object2);//true

与===的区别

Object.is(+0,-0);//false
+0 === -0; //true

Object.is(NaN,NaN);//true
NaN === NaN; //false

2.数组

Array.of():将所有值作为元素行成数组

let array = Array.of(1,'5',false);//[1,'5',false]

Array.from():将类数组对象或者所有可迭代的对象转换为数组。

参数:Array.from(arrayLike,[, mapFn[,thisArg]])

  • arrayLike:转换的对象
  • mapFn:对每个元素进行处理,转换后的数组是处理过的元素。可选
  • thisArg:指定执行mapFn函数时的this对象。可选
let array = Array.from([1,2]);//[1,2]
array = Array.from([1,,3]);//[1,undefined,3]

//两个参数时
let array2 = Array.from([1,5,3,6,8],item => item - 1);//[0,4,2,5,7]

//三个参数时
let map = {
	add(number){
		return number+2;
	}
};
let array3 = Array.from([1,5,3,6,8],function (item){
	return this.add(item);//这里一定要使用return返回元素,不然数组的值都会变成undefined
},map);//[3,7,5,8,10]

//转换Map
let myMap = new Map();
myMap.set(1,"666");
myMap.set('2',"555");
let mapArray = Array.from(myMap);//[[1,"666"],["2","555"]]

//转换Set
let mySet = new Set();
mySet.add(1);
mySet.add("666");
mySet.add({name:"六十元"});
let setArray = Array.from(mySet);//[1,"666",{name:"六十元"}]

//转换字符串
let string = "lsy";
let strArray = Array.from(string);//["l","s","y"]

类数组对象

该对象必须含有length属性,且属性名必须是数值或者是可转换为数值的字符。
let arrayObj = {
	0:1,
	1:2,
	2:"3",
	length:3
}
let array = Array.from(arrayObj);//[1,2,"3"]
//没有length属性时,返回空数组
arrayObj = {
	0:1,
	1:2,
	2:"3"
}
array = Array.from(arrayObj);//[]
//只要有一个属性名不为数值且转换不了数值时,返回长度length的元素值为undefined的数组
arrayObj = {
	a:1,
	b:2,
	3:5,
	c:"3",
	length:3
}
array = Array.from(arrayObj);//[undefined,undefined,undefined]

扩展的方法

2.1:查找

  • find():查询数组中符号条件的元素,如包含多个符号条件的元素,只返回第一个元素。
  • findIndex():查询数组中符号条件的元素索引,如包含多个符号条件的元素索引,只返回第一个元素索引。
  • includes(value,index):查询数组中是否包含此值。返回布尔值

注意点:当数组有空位时,会处理为undefined。

let array = Array.of(23,43,12,53);
console.log(array.find(item => item > 25));//43

console.log(array.findIndex(item => item == 12));//2

console.log(array.includes(43));//true
//查询该数组中是否有非数字NaN
console.log(array.includes(NaN));//false
console.log(array.includes(12,3));//false

2.2:填充

  • fill(value,start,end):将一定范围索引的元素内容填充为指定的单个值。

      参数value:填充的值
      参数start:填充范围的起始位置,默认为数组开头(可选)
      参数end:填充范围的结束位置-1,默认为数组末尾(可选)
    
let array = Array.of(1,45,23,53);
console.log(array.fill(3,1,2));//[1,3,23,53]
//此时array里面的数组为[1,3,23,53]
console.log(array.fill(5,1,3));//[1,5,5,53]
//此时array里面的数组为[1,5,5,53]
console.log(array.fill(3));//[3,3,3,3]
//此时array里面的数组为[3,3,3,3]
  • copyWithin():将一定范围索引的元素修改为此数组另一指定范围索引的元素。

      参数target:被修改的起始位置
      参数start:要复制的数据起始位置,默认为数组开头(可选)
      参数end:要复制的数据结束位置-1,默认为数组末尾(可选)
    
let array = Array.of(23,53,32,54);
console.log(array.copyWithin(1,2));//[23,32,54,54]
//此时array里面的数组为[23,32,54,54]
console.log(array.copyWithin(1));//[23,23,32,54]
//此时array里面的数组为[23,23,32,54]
console.log(array.copyWithin(0,2,3));//[32,23,32,54]
//此时array里面的数组为[32,23,32,54]

2.3:遍历

  • entries():遍历键值对
let array = Array.of(32,"六十元",66);
for(let [key,value] of array.entries()){
	console.log(key, value);
}
// 0 32
// 1 "六十元"
// 2 66

//不使用for-of
let arrEntries = array.entries();
console.log(arrEntries.next().value);// [0, 32]
console.log(arrEntries.next().value);// [1, "六十元"]
console.log(arrEntries.next().value);// [2, 66]
//数组空位,自动处理为undefined
array = Array.from([,23]);
console.log(array.entries().next().value);//[0,undefined]
  • keys():遍历键名
let array = Array.of(1,3,52);
for(let key of array.keys()){
	console.log(key);
}
//0
//1
//2
  • values():遍历键值
let array = Array.of(1,3,52);
for(let value of array.values()){
	console.log(value);
}
//1
//3
//52

2.4:嵌套数组转一维数组

  • flat(n):拉平嵌套数组,默认为一层,n参数代表拉平的层数,Infinity表示不管多少层,全部转为一维数组。
console.log([1,[2,[3,[5],64]]].flat());//[1,2,[3,[5],64]]

console.log([1,[2,[3,[5],64]]].flat(2));//[1,2,3,[5],64]]

console.log([1,[2,[3,[5],64]]].flat(Infinity));//[1,2,3,5,64]
  • flatMap():先对数组中的每个元素进行处理,然后在执行flat方法转为一维数组。只能用于一维数组。
console.log([1,3,52,42,64].flatMap(item => item+2));//[3, 5, 54, 44, 66]
//二维数组使用flatMap()
console.log([1,3,52,[42],64].flatMap(item => item+2));//[3, 5, 54, "422", 66]

2.5:数组缓冲区

是指在内存中的一段地址,定型数组的基础,实际字节数在创建时确定,之后只可修改其中的数据,不可修改大小。可通过构造函数进行创建。
let array = new ArrayBuffer(10);
console.log(array.byteLength);//数组字节长度为10

2.5.1视图

视图是用来操作内存的接口。
视图可以操作数组缓冲区或者缓冲区字节的子集,并按照其中一种数值数据类型来读取或写入数据。
DataView是一种常用的数组缓冲区视图,其支持所有8种数值数据类型。
let array = new ArrayBuffer(10);
let dataView = new DataView(array);
dataView.setInt8(0,1);
dataView.setInt16(1,82);
console.log(dataView.getInt8(0));
console.log(dataView.getInt16(1));
//可以通过偏移量(参数2)和长度(参数3)来指定DadaView可操作的字节范围
dataView = new DataView(array,0,4);//dataView可访问的范围有0-4(长度减一)
dataView.setInt8(3,123);
dataView.setInt32(4,12);//RangeError: Offset is outside the bounds of the DataView

2.5.2:定型数组

数组缓冲区中特定类型的视图。
可以强制使用特定的数据类型,而不是使用DataView来操作数组缓冲区。
可接受参数包括定型数组、类数组对象、可迭代对象、数组。
//通过数组缓冲区生成
let arrayBuf = new ArrayBuffer(10);
let arrView = new Int8Array(arrayBuf);
//通过构造函数生成
let view = new Int32Array(10);
//不传参的话,默认为0,这种情况下数组缓冲区不会在内存中分配空间,所以不能用来操作数据
let view = new Int32Array(0);
console.log(view.byteLength);//0
console.log(view.length);//0
view.set(0,12);//TypeError: invalid_argument

注意点:length属性是不可修改的,一但创建数组缓冲区,length属性就是只读的。在非严格模式下,修改会直接跳过,但在严格模式下会报错。

let arrayBuf = new ArrayBuffer(10);
let arrView = new Int12Array(arrayBuf);
console.log(arrView.length);//10
arrView.length = 15;//15
console.log(arrView.length);//10

定型数组也可用entries()、keys()、values()进行迭代。

let view = new Int16Array([123, 23]);
for(let [k, v] of view.entries()){
    console.log(k, v);
}
//0 123
//1 23

定型数组中新增的方法

  • set():用于将其他数组复制到定型数组。
  • subarray():用于提取定型数组中的一部分行成新的定型数组。
let view = new Int16Array([123, 23]);
console.log(view);//123,23
view.set([32,54]);
console.log(view);//32,54
view.set([23,53,32]);//RangeError: offset is out of bounds

//subarray()
//参数1:可选,提取开始位置
//参数2:可选,提前结束位置-1.
console.log(view.subarray());//[32,54]
console.log(view.subarray(1));//[54]
console.log(view.subarray(0,2));//[32,54]

结束语

今天ES6的对象、数组就介绍到这里了。下面还会持续更新ES6中的其他内容。谢谢大家的观看!

在这里插入图片描述
参考文档:菜鸟教程

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值