文章目录

  • 解构
    • 1、什么是解构
    • 2、数组解构
      • 拓展运算符
      • 数组解构
    • 3、对象解构
    • 4、字符串解构
    • 5、其他不咋用解构
      • 数值解构
      • 布尔类型解构
  • 常用扩展
    • 1、对象扩展
    • 2、函数扩展
      • 函数参数
      • rest参数
      • 箭头函数
    • 3、数组扩展
    • 4、数值扩展

解构

1、什么是解构

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring),解构的本质属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于undefined。

2、数组解构

拓展运算符

拓展运算符使用三个点(…)表示。将一个数组转为用逗号分隔的参数序列。
例如:

let arr1 = [1,2,3];
let arr2 = [4,5,6];// 数组合并
let arr = [...arr1,...arr2];
console.log(arr);
// 打印出:[1,2,3,4,5,6]//数组复制
let arr3 = [...arr1];
console.log(arr3); //[1,2,3]// 字符串转换为数组
let temp = [..."hello"];
console.log(temp);
// 打印出:['h','e','l','l','o']// 将为数组转为真数组
/*
<div></div>
<div></div>
<div></div>
*/
const divs = document.querySelectorAll("div");
const divArr = [...divs];
console.log(divArr);

为数组转为真数组结果:

数组解构

以前为变量赋值时只能直接指定值,如下

let a = 1;
let b = 2;
let c = 3;

ES6 允许写成下面这样。等号左边的变量放到中括号内部,匹配右侧数组中的元素。

let [a, b, c] = [1, 2, 3];

上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
看如下例子:

//注意变量与值会按照索引一一对应
let [foo, [[bar], baz]] = [1, [[2], 3]];
//结果如下:
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3//当未指定变量名时
let [ , , third] = ["foo", "bar", "baz"];
//结果如下:
console.log(third); // "baz"//与索引一一对应
let [x, , y] = [1, 2, 3];
x // 1
y // 3//...变量名 表示匹配前面变量未匹配到的值,存在数组中
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]//如果解构不成功,变量的值就等于undefined
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []let [bar, foo] = [];
let [bar, foo] = [1];
//以上两种情况都属于解构不成功,`foo`的值都会等于`undefined`

不完全解构

不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [x, y] = [1, 2, 3];
x // 1
y // 2let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2    //[b]和[2,3]的模式相同,但只会匹配到2
d // 4

如果等号的右边不是数组(或者严格地说,不是可遍历的结构)那么将会报错.

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};// 可以正常解构
let [a] = 'hello';
a // 'h'

上面的六个表达式都会报错,因为等号右边的值,要么转为对象以后不具备 Iterator 接口(前五个表达式),要么本身就不具备 Iterator 接口(最后一个表达式)。

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。原生具备 Iterator 接口的数据结构:Array、Map、Set、String、TypedArray、arguments、NodeList 等。

默认值
解构赋值允许指定默认值。注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let [x, y = 'b'] = ['a'];
// x='a', y='b’//默认值也可以为函数
function f() { console.log('aaa'); }
let [x = f()] = [1];
// x = 1,该f函数不会执行,函数在x取到undefined的时候才会执行,并将返回值赋值给x,如下
let [y = f] = [];
// y = f
let [z = f()] = [];
// z = undefined

3、对象解构

对象解构指的是将等号左边的变量放到大括号内部,匹配右侧数组中的元素。
对象的属性没有次序,变量必须与属性同名,才能取到正确的值。如下:

let { foo, bar } = { foo: "aaa", bar: "bbb" };
// foo = "aaa"; bar = "bbb"

重命名结构
如果变量名与属性名不一致,必须写成下面这样进行重命名。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
// baz = "aaa"

这实际上说明,对象的解构赋值是下面形式的简写。

let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

嵌套解构

let obj = { p: [ "Hello", { y: "World" } ] };
let { p: [x, { y }] } = obj;
// x = "Hello”; y = "World"

默认值

默认值生效的条件是,对象的属性值严格等于undefined

let {x: y = 3} = { x: 1 };
// y = 1
let {x: y = 3} = {};
// y = 3

运算符…
…用到等号左侧是聚合, …用到等号右侧就是展开

let obj = { name: 'zhangsan', age: 12 }
//==========================================let {...person} = obj // 赋值console.log(person); // { name: 'zhangsan', age: 12 }console.log(person === obj) // false 说明person是一个新对象person.gender = "男" // 给person对象添加新的属性和属性值
console.log(person) // { name: 'zhangsan', age: 12, gender: '男' }//==========================================
let stu = {...obj,gender: '1'
}
console.log(stu) //{ name: 'zhangsan', age: 12, gender: '1' }let {gender="2",...zs} = stu;
console.log(gender,zs)//1 { name: 'zhangsan', age: 12 }

4、字符串解构

等号左边的变量如果放在中括号内进行的类似于数组解构,从字符串中获取指定字符;如果放在大括号内进行的类似于对象解构,从实例属性获方法中解构。

const [a, b, c, d, e] = 'hello';
// a = h;b = e;c = l;d = l;e = o//将string字符串转成数组
let [...arr] = 'hello';
console.log(arr); //[ 'h', 'e', 'l', 'l', 'o' ]

5、其他不咋用解构

数值解构

等号左边的变量放在大括号中进行解构,可以获取到数值包装器构造函数原型中指定的方法。

let { valueOf } = 12;
// valueOf = Number.prototype.valueOf

布尔类型解构

等号左边的变量放在大括号中进行解构,可以获取到布尔包装器构造函数原型中指定的方法。

let { valueOf } = true;
// valueOf = Boolean.prototype.valueOf

常用扩展

1、对象扩展

ES6中对于Object的拓展主要是静态方法的拓展。

  1. Object.is()
    该方法用来判断两个值是否“完全相等”,或者说是否为同一个值。
    格式:Object.is(value1,value2);
    结果:返回一个Bolean类型表示两个参数是否为同一个值。为true则相同,为false表示不同

该方法和"=="有区别:
"==“在判断相等前对两边的变量(如果不是同一类型)进行强制转换,而Object.is()方法不会这么做
该方法和”==="也有区别:
“===“先比较类型,类型不相同则结果一定不等,如果类型相同,则继续比较值,值相等,则结果相等。并且”===” 将数字 -0 和 +0 视为相等,而将Number.NaN 与NaN视为不相等,而Object.is()方法将这两个均视为不等。

Object.is('foo', 'foo');  // true
Object.is(window, window);  // true
Object.is('foo', 'bar');   // false,这是两个对象,存放的地址位置不同
Object.is([], []);  // false,这是两个对象,存放的地址位置不同let foo = { a: 1 };
let bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false,这是两个对象,存放的地址位置不同Object.is(null, null); // true
console.log(1 === 1);//true
console.log(Object.is(1, 1));//true
console.log(Object.is(1, 2)); //falseconsole.log(+0 === -0);  //true
console.log(Object.is(+0, -0));  //falseconsole.log(0 === -0);  //true
console.log(Object.is(0, -0));  //falseconsole.log(NaN === NaN); //false
console.log(Object.is(NaN, NaN));  //trueconsole.log(isNaN(NaN)); //trueconsole.log(NaN === 0/0); //falseconsole.log(Object.is(NaN, 0/0));  //true

简单理解就是Object.is()方法比较值其实就是看两个值的存储位置是不是一样,一样则相等。

  1. Object.assign()
    该方法用于将所有可枚举类型的值从一个或多个源对象分配到目标对象。返回目标对象。简而言之就是合并对象。
    语法:object.assign(target,...sources);target是目标对象,sources源对象,而可以为一个或多个。

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性,此外需要注意Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。看如下例子

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// Object { a: 1, b: 4, c: 5 }

补充:该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。
如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
Object.assign()拷贝的是(可枚举)属性值。假如源值是一个对象的引用,它仅仅会复制其引用值。

  1. Object.getPrototypeOf()
    该方法返回指定对象的原型。
    语法:Object.getPrototypeOf(object);object是要返回其原型的对象
    返回的是给定对象的原型,如果没有继承属性则返回null
let obj = {};
// 获取obj的原型对象
console.log(Object.getPrototypeOf(obj));
// 打印出:obj的原型对象
console.log(Object.getPrototypeOf(obj)===Object.prototype);
//打印出:true
console.log(Object.getPrototypeOf(obj)===obj.__proto__);
//打印出:true
  1. Object.setPrototypeOf()
    该方法设置一个指定的对象的原型到另一个对象或 null。
    语法:Object.setPrototypeOf(obj,prototype);obj是要设置其原型的对象,protoType是该对象obj的新原型
let dict = Object.setPrototypeOf({}, null);

由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]在各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.proto = … 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果关心性能,应该避免设置一个对象的 [[Prototype]]。相反,应该使用 Object.create()来创建带有想要的[[Prototype]]的新对象。

  1. Object.keys()
    该方法用于获取所有可枚举属性名,并且返回一个由给定对象自身可枚举属性组成的数组,数组中属性名的排序和正常循环遍历该对象时返回的顺序一致。
    语法:object.keys(obj); obj是要返回其枚举自身属性的对象。
//例如一个简单的数组
let arr = ['a', 'b', 'c'];
console.log(Object.keys(arr));
// 打印出: ['0', '1', '2']// 例如一个对象
let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // ['0', '1', '2']
//遍历
Object.keys(obj).forEach((item) => {console.log(item, obj[item]);
})
// 0 a
// 1 b
// 2 c//一个带有随机排序key的对象
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));  // ['2', '7', '100']// getFoo is a property which isn't enumerable
let myObj = Object.create({}, {getFoo: {value: function () { return this.foo; }}
});
myObj.foo = 1;
console.log(Object.keys(myObj));
// 打印出: ['foo']

当然,如果想获取一个对象的所有属性,甚至包括不可枚举的,请使用Object.getOwnPropertyNames()方法。

  1. Object.values()
    该方法可以获取所有可枚举属性的属性值,并返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同(区别在于for-in循环枚举原型链中的属性)。
    语法:Object.values(obj); obj表示可以枚举属性值的对象。
let obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj));  // ['a', 'b', 'c']// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
let an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj));  // ['b', 'c', 'a']// getFoo is property which isn't enumerable
let my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj));
// 打印出: ['bar']// non-object argument will be coerced to an object
console.log(Object.values('foo'));
// 打印出: ['f', 'o', 'o']
  1. Object.entries
    该方法获取所有的可枚举属性名和属性值键值对,返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
    语法:Object.entries(obj);obj 可以返回其可枚举属性的键值对的对象。
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]// array like object
const obj2 = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj));
// 打印出: [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj));
// 打印出: [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]// getFoo is property which isn't enumerable
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj));
// 打印出: [ ['foo', 'bar'] ]// non-object argument will be coerced to an object
console.log(Object.entries('foo'));
// 打印出: [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]// iterate through key-value gracefully
const obj3 = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {console.log(`${key} ${value}`); // 打印出: "a 5", "b 7", "c 9"
}// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {console.log(`${key} ${value}`);
// 打印出: "a 5", "b 7", "c 9"
});
  1. Object.fromEntries()
    传入二维数组或者Map集合,返回一个对象
// 二维数组
const result1 = Object.fromEntries([['name','jack'],['course','English'],
]);
console.log(result1); // { name: 'jack', course: 'English' }
// Map
const m = new Map();
m.set('name','jack');
const result2 = Object.fromEntries(m);
console.log(result2); // { name: 'jack' }

2、函数扩展

函数参数

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。通常情况下,定义了默认值的参数,应该是函数的尾参数,并且注意:函数的length属性,将返回没有指定默认值的参数个数

  • 设置参数默认值
function log(x, y = 'World') { console.log(x, y);// 打印出:1,'World'
}
log(1);
  • 参数结构
    参数默认值可以与解构赋值的默认值,结合起来使用。
function foo({x, y = 5}) { console.log(x, y); // 打印出:1,5
}
foo({x:1});

此外,函数参数对象解构、数据结构等。

function test({ name, age = 1, ...obj }) {console.log(name, age, obj);
}
test({ name: 'zhangsan', age: 12, gender: 1,weight:40 });
//zhangsan 12 { gender: 1, weight: 40 }

rest参数

ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,得到的是一个数组

function add(a,b,...values) {console.log(a);console.log(b);console.log(values);
}
add(1,2,3,4,5,6,7);
结果为:
1
2
[3,4,5,6]

rest参数必须要放到参数最后

箭头函数

JavaScript中,经常使用回调函数,箭头函数的出现大大简化了回调函数的写法,当然,除了作为函数参数,箭头函数也可以出现在其他地方。
语法:(0个或1个或多个参数)=>{代码块部分}

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号括参数部分如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。其实箭头函数还可以继续省略,当形参只有一个参数的时候,可以省略圆括号;当代码块只有一条语句的时候,可以省略花括号。

let f = v => v;
// 等价于
let f = function(v) { return v;
};

主要特性:
1、箭头函数里面没有自己的this,而是引用外层作用域中的this,且不可以改变this指向,因此箭头函数不适合与this有关的回调,例如事件回调,对象的方法回调。
2、箭头函数里面不能使用arguments、super变量
3、不能使用new关键字创建实例化对象
4、没有原型prototype
5、不支持重复的命名参数。

例如:箭头函数里面没有自己的this,而是引用外层作用域中的this,且不可以改变this指向

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>箭头函数</title>
</head><body><script>function getName1() {console.log(this.name);}let getName2 = () => {console.log(this.name);}// 设置window对象的name属性window.name = "rose";// 创建另一个对象objconst obj = {name: "jack"}// 直接调用时getName1(); //rosegetName2(); //rose//使用call()方法调用函数时(此时会修改this指向的对象)getName1.call(obj); //jack//普通方式定义的函数this指向改变。getName2.call(obj); //rose //箭头函数的this指向的依然是外层的且为原来的那个对象--这里是window对象(即不会改变原来this指向)</script>
</body>
</html>

例如:箭头函数中不能使用new关键字创建实例化对象

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>箭头函数</title>
</head><body><script>let Person = (name, age) => {this.name = name;this.age = age;}let me = new Person("jack",20);console.log(me); //报错:Uncaught TypeError: Person is not a constructor</script>
</body>
</html>

如果将普通函数和箭头函数分别定义在setTimeout(function(),时间)延时方法中。那么区别在哪里?如下:

var obj = {x: 100,show() {setTimeout(function () {console.log(this.x); // undefinedconsole.log(this); // window对象}, 1000);}
}obj.show();

普通函数中的this总是指向它的直接调用者,而匿名函数function()并没有被直接调用,所以这里this应该是指向window对象,而全局作用域没有定义x变量,所以this.x结果为undefined。

如果想要this指向obj,则需要在setTimeout()方法和show()方法之间定义一个引用:let _this = this;,接收全局的的this。

       var obj = {x:100,show(){setTimeout(() => {console.log(this.x); //100console.log(this); //obj对象}, 1000);}}obj.show();

使用箭头函数简写时,this指向的对象是作用域链上的对象,此时的this会沿着作用域链一层一层往上找,直到找到含有x的对象,然后进行调用。可以再obj对象中添加一个变量来判断为什么延时函数中的this代表了obj对象,如下:

var obj = {x: 100,y:this,show() {setTimeout(() => {console.log(this.x); //100console.log(this); //obj对象}, 1000);}}obj.show();console.log(obj.y); //obj对象

可以看到其实obj中的this指向的也是obj对象,而this沿着作用域链不断向上找,找到x=100;

关于普通函数和箭头函数中的this指向问题

3、数组扩展

数组在静态方法与实例方法中都有所拓展。

  • Array.from()
    该方法将类似数组或可迭代对象转为数组,从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
    语法:Array.from(arrayLike[, mapFn[, thisArg]])
    参数:

    • arrayLike 想要转换成数组的伪数组对象或可迭代对象。
    • mapFn 可选 如果指定了该参数,新数组中的每个元素会执行该回调函数。
    • thisArg 可选 执行回调函数 mapFn 时 this 对象。

Array.from() 可以通过以下方式来创建数组对象:
伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

Array.from('foo');
// [ "f", "o", "o" ]function f() {return Array.from(arguments);
}
f(1, 2, 3);
// [ 1, 2, 3 ]
  • Array.of()
    该方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
    语法:Array.of(element0[, element1[, ...[, elementN]]])
    参数:
    elementN 任意个参数,将按顺序成为返回数组中的元素。
Array.of(7);       // [7]
Array.of(1, 2, 3); // [1, 2, 3]Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]Array.of(1);         // [1]
Array.of(1, 2, 3);   // [1, 2, 3]
Array.of(undefined); // [undefined]

该方法和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 表示创建一个具有单个元素 7 的数组,而Array(7)
表示创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

  • Array.prototype.find()
    该方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
    语法:arr.find(callback,[thisArg])
    参数:
    callback 在数组每一项上执行的函数,接收3个参数:

    • tem 当前遍历到的元素。
    • index 可选 当前遍历到的索引。
    • array 可选 数组本身。
      thisArg 可选 执行回调时用作this 的对象。
  • Array.prototype.findIndex()
    该方法找到一个元素在数组中的位置,返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
    语法:arr.findIndex(callback[, thisArg])
    参数:
    callback 在数组每一项上执行的函数,接收3个参数:

    • tem 当前遍历到的元素。
    • index 可选 当前遍历到的索引。
    • array 可选 数组本身。
      thisArg 可选 执行回调时用作this 的对象。
//查找等于2的元素
let arr = [10,8,3,2,4,2,5];
//find方法返回第一个满足条件的元素或者undefined
let resultNum = arr.find((item, index) => {return item === 2;
});
console.log(resultNum);//2
// findIndex返回第一个满足条件的元素的索引或者-1
let resultIdx = arr.findIndex((item, index) => {return item === 2;
});
console.log(resultIdx);//3
function isPrime(element, index, array) {let start = 2;while (start <= Math.sqrt(element)) {if (element % start++ < 1) {return false;}}return element > 1;
}console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
  • Array.prototype.includes()
    该方法找到一个元素是否存在于数组中,用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。使用 includes()比较字符串和字符时是区分大小写。
    语法:arr.includes(valueToFind,[ fromIndex])
    参数:

    • valueToFind 需要查找的元素值。
    • fromIndex 可选 从fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜 (即使从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。如果 fromIndex 大于等于数组的长度,则会返回 false,且该数组不会被搜索。
      返回值:
      返回一个布尔值 Boolean ,如果在数组中找到了(如果传入了 fromIndex ,表示在 fromIndex 指定的索引范围中找到了)则返回 true 。
[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
  • Array.prototype.fill()
    该方法用来填充数组,用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
    语法:
    arr.fill(value[, start[, end]])
    参数:

    • value 用来填充数组元素的值。
    • start 可选 起始索引,默认值为0。
    • end 可选 终止索引,默认值为 this.length。
      如果 start和end 是个负数, 则开始索引会被自动计算成为 length+start
[1, 2, 3].fill(4);  // [4, 4, 4]
[1, 2, 3].fill(4, 1);  // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);  // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);  // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);  // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);  // [4, 2, 3]
  • Array.prototype.keys()
    该方法获取数组key,返回一个包含数组中每个索引键的Array Iterator对象。
    语法:arr.keys()
let arr = ["a", , "c"];
let sparseKeys = Object.keys(arr);
let denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys);  // [0, 1, 2]
let arr = [2, 3, 4, 5, 6, 2];
// 遍历
let keys = arr.keys();
console.log(keys);
//keys变量当前是迭代器对象Object [Array Iterator] {}// 遍历迭代器对象
let result;
while (!(result = keys.next()).done) {console.log(result);
}/*
console.log(keys.next());// { value: 0, done: false }
console.log(keys.next());// { value: 0, done: false }
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());//{ value: undefined, done: true }
console.log(keys.next());//{ value: undefined, done: true }
*/// 迭代器实现了Iterator接口,只要有实现了Iterator接口就可以for-of遍历
for (let key of keys) {console.log(key);
}
  • Array.prototype.values()
    Array.prototype.values()方法获取数组元素,返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
    语法:arr.values()
let arr = ['w', 'y', 'k', 'o', 'p'];
let eArr = arr.values();for (let letter of eArr) {console.log(letter);
}
//"w" "y "k" "o" "p"
  • Array.prototype.entries()
    该方法获取数组中的key、value键值对,返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
    语法:arr.entries()
    一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(proto:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。
let arr = ["a", "b", "c"];
let iterator = arr.entries();
console.log(iterator);
// 打印出:Array Iterator {  }
for (let letter of iterator) {console.log(letter);
}
// 打印出:
// Array [ 0, "a" ]
// Array [ 1, "b" ]
// Array [ 2, "c" ]
  • flat()
    将多维数组转为低维数组
// 二维转一维
const arr1 = [1,2,3,4,[5,6]]; // 二维数组
console.log(arr.flat()); // [1,2,3,4,5,6]; // 三维转二维
const arr2 = [1,2,3,[4,5,[6,7]]]; // 三维数组
console.log(arr.flat()); // [1,2,3,4,5,[6,7]]; // 三维转一维
const arr3 = [1,2,3,[4,5,[6,7]]];
console.log(arr.flat(2)); // 参数2表示深度
// [1,2,3,4,5,6,7]

4、数值扩展

  • Number.EPSILON
    该方法表示JavaScript中数值的最小精度,EPSILON无限接近于2.2204460492503130808472633361816E-16。当两个数进行大小比较时,如果差值小于这个EPSILON,那么就将这两个数看做相等。

有如下代码:

console.log(0.1+0.2);

其结果并不是我们想象中的0.3,而是如下结果:

function equal(a, b){if(Math.abs(a-b) < Number.EPSILON){return true;}else{return false;}
}
console.log(0.1+0.2); //0.30000000000000004
console.log(0.1 + 0.3); // 0.4
console.log(0.1 + 0.3 === 0.4); // true
console.log(equal(0.1 + 0.3,0.4)); // true
console.log(0.1 + 0.2 === 0.3); // false
console.log(equal(0.1 + 0.2,0.3)); // true
  • 二进制、八进制
let b = 0b1010; //二进制
console.log(b); // 10
let o = 0o777;  // 八进制
console.log(o); // 511
let d = 100;    // 十进制
console.log(d); // 100
let x = 0xff;   // 十六进制
console.log(x); // 255
  • Number.isFinite
    检测一个数值是否为有限数
console.log(Number.isFinite(100)); // true
console.log(Number.isFinite(100/0)); // false
console.log(Number.isFinite(Infinity)); // false
  • Nuber.isNaN
    检测一个值是否为NaN
console.log(Number.isNaN(123)); // false
  • Nuber.parseInt和Number.parseFloat
    字符串转整数(从左往右,在碰到字母后,后面的内容全部神略)
console.log(Number.parseInt('432423love')); // 432423
console.log(Number.parseFloat('4.32423love')); // 4.32423
console.log(Number.parseInt('432423love3434')); // 432423
console.log(Number.parseFloat('4.32423love342')); // 4.32423
  • Nubmer.isInteger
    判断一个数是否为整数
console.log(Number.isInteger(5));
console.log(Number.isInteger(2.5));
  • Math.trunc
    直接将数字的小数部分省略
console.log(Math.trunc(2.4)); // 2
  • **
    求幂
console.log(Math.pow(2,10)); // 1024
console.log(2 ** 10); // 1024

ES6新特性:解构、对象扩展、函数扩展、数组扩展、数值扩展相关推荐

  1. ES6新语法--解构赋值

    对象解构赋值 ※很重要 /*** 对象解构赋值:获取元素中属性的值,然后赋值给变量*///声明一个对象 let obj = {name:'chen',age:38,gender:'man',score ...

  2. ES6新特性_ES6的对象扩展方法---JavaScript_ECMAScript_ES6-ES11新特性工作笔记040

    然后我们看一下es6中的对象扩展方法 可以看到有个Object.is(120,121); 这个相当于判断是否相等,也就是是否是某个对象. 可以看到120,和121 不相等. 然后120和120相等. ...

  3. 前端开发的ES6新特性(学生党必看)

    一:ES6新特性-let&const 1.常量const const常量(声明之后不允许改变,一旦声明必须初始化, 否则报错) 2.let变量 let声明的变量有严格的作用域 var声明的变量 ...

  4. 【JavaScript】32_解构对象与对象的解构

    1.解构对象 数组中可以存储任意类型的数据,也可以存数组, 如果一个数组中的元素还是数组,则这个数组我们就称为是二维数组 解构对象,方便两数交换数值:可以反向赋值对象,数组 可以在解构的同时,进行声明 ...

  5. ES6新特性总结(2)解构赋值、模板字符串、Symbol

    ES6新特性总结(2)解构赋值.模板字符串.Symbol 1 解构赋值 1.1 Spread / Rest 操作符 1.2 数组的解构 1.3 对象的解构 1.4 解构的默认值和参数的解构 2 模板字 ...

  6. 第五节:一个令人兴奋的ES6新特性:解构赋值

    端午节刚刚过,大家是回家陪家人吃粽子,还是约好朋友一起出去浪了?昨天上了一天班,不知道大家有没有把出去玩耍的心思收回来,准备接下来的学习. 继续学习吧骚年们...... 学完了前4节,今天我给大家带来 ...

  7. es6 获取对象的所有值_前端开发必备 - ES6 新特性之 Set和Map数据结构

    往期回顾: 前端开发必备 - ES6 新特性之 let 和 const 命令 前端开发必备 - ES6 新特性之 变量的解构赋值 前端开发必备 - ES6 新特性之 字符串的拓展 前端开发必备 - E ...

  8. javascript ES6 新特性之 扩展运算符 三个点 ...

    对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了: 对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中. 作用类似于 Object.assign() ...

  9. ES6-4/5 解构赋值、函数默认值、数组解构、对象解构

    ES-4 解构赋值.函数默认值.数组解构.对象解构 ES-5 隐式转换.函数参数解构.解构本质.()用法 一 解构赋值 1 虚值 含义:在Boolean转换结果为假的值falsy 2 函数默认值 ES ...

  10. ES6新特性(函数默认参数,箭头函数)

    ES6新特性之 函数参数的默认值写法 和 箭头函数. 1.函数参数的默认值 ES5中不能直接为函数的参数指定默认值,只能通过以下的变通方式:   从上面的代码可以看出存在一个问题,当传入的参数为0或者 ...

最新文章

  1. javascript 事件对象
  2. 英特尔用ViT做密集预测效果超越卷积,性能提高28%,mIoU直达SOTA|在线可玩
  3. python opencv 官方文档里LaTeX公式不能正常显示怎么办?
  4. 补发《超级迷宫》站立会议三
  5. Apache Camel简介
  6. 立即执行函数(IIFE)闭包
  7. python tkinter frame加入窗口_Python ---(五)Tkinter窗口组件:LabelFrame
  8. mockwebserver java_在Java中使用WireMock和SOAP Web服务
  9. ubuntu amd64 的锐捷连接解决办法---武汉大学
  10. 人脸识别 Face Recognition安装使用
  11. 32款 jQuery UI框架开源软件
  12. oracle+in条件优化,Oracle语句优化30个规则详解
  13. 群晖文件存储服务器os系统,NAS探索 篇二:群晖NAS系统 最简单选择方法
  14. 美规Homekit插座
  15. 美亚杯赛前小训练,分享一套小模拟练习,弘连软件使用学习,供大家赛前训练,题目非常简单,很适合大家练手(非常推荐!)(新手手荐!)题目入门非常合适,也是了解软件很好的办法!
  16. 【绿色版软件】出现应用程序无法启动,并行配置不正确
  17. wincc做皮带动画_WINCC中制作管道流体流动动画的一种方法
  18. 阿里云ECS服务器使用要求及不可以进行的操作
  19. 【Docker】Docker镜像是什么?浅谈对Docker镜像的理解
  20. python的冒泡排序

热门文章

  1. 谁知道qq会员怎么退款呢
  2. sucess - money - freedom
  3. Lake Shore低温温度传感器之超低温 Rox
  4. 学习软件技术的五大技巧
  5. Markdown标记语言知识梳理
  6. 四级英语口语模拟测试软件,英语四级口语模拟题:非常有用
  7. 【Rust日报】 2020-01-10 track_caller 錯誤處理大突破
  8. 猫眼电影票房爬取到MySQL中_Scrapy爬取猫眼电影并存入MongoDB数据库
  9. Swift:一个简单的货币转换器App在iOS10中的分析和完善
  10. FTP服务器搭建报错Warning: FTP over TLS is not enabled, users cannot securely log in.