ES6新特性
- 1.let const 与 var的比较
- 2.数组的解构和对象的解构
- 3.模板字符串:` `
- 4.字符串的扩展方法:
- 5.函数的参数默认值
- ...展开符 / Spread / Rest展开符
- 箭头函数
- 对象字面量的增强:对象的属性可以是字符串,数字,方法,等等,还可以直接定义原型
- Proxy:监听对象。会自动调用get和set方法用来设置属性和获取属性。
- Reflect 属于一个静态类。不能通过new调用。通过Reflect调用API。类似Math对象API
- Set 类似于Array
- Map 键值对集合 类似于Object
- Symbol 是一种数据类型 ,适合用作对象的私有属性
- for of 循环:遍历任何数据类型的一种统一方式 some every
- Iterable类型:可迭代接口 迭代器模式 实现场景:使得for of循环可以遍历任何数据类型。?
- 生成器函数 :会自动返回一个生成器对象,调用对象的next方法,函数体才会执行,函数体会一旦遇到yield就会暂停执行,返回一个生成器对象。
- 生成器函数的应用:实现发号器
- Generator:更优的异步编程写法
- 类的继承:extends 继承
- 模块化
- promise 和 generator
- ES6中,为 Math,Number,String,Object 添加的新API ?
- Object的扩展方法:
- Number的扩展方法
- Array的扩展方法:
- 正则的扩展方法
1.let const 与 var的比较
- var声明的变量,存在变量提升。var可以重复声明一个变量。var声明的变量在块外面也有效,会污染全局作用域。
- let声明的变量不存在变量提升,必须先声明再使用。let不能重复声明一个变量。let声明的变量只在块内有效,具有块级作用域。
- const用来声明只读常量。具有块级作用域。const在声明时必须被赋值。如果const的是一个对象,对象所包含的值是可以被修改的。
- 关于变量提升/预解析: let 不存在【 变量提升 / 欲解析 】,var 存在 【 变量提升 / 欲解析 】
// var存在预解释
console.log(a); //undefined 相当于 var a; 变量声明未赋值 【 当脚本开始运行时,a 已经存在,但是还没有赋值,所以undefined。】
var a = 5;
//let const没有变量提升,必须先申明,再使用
console.log(a)//报错: a is not defined 语法错误【 let声明不存在变量提升,所以当脚本运行时,a 不存在,所以报错】
let a = 5;
- 关于是否可以重复声明:let 不可以重复声明,var 可以重复声明
var a = 5
var a = 12 //-->12 var可以重复声明一个变量
let a = 5
let a = 12 //-->error let不可以重复声明一个变量
//const定义常量,声明就要赋值,不允许修改。但如果const是一个对象,对象所包含的值可以被修改的。因为对象的话赋值存储的是引用指针地址,只要指针地址没变就行。
const student = { name: 'cc' }
student.name = 'yy';// 不报错
student = { name: 'yy' };// 报错
- 因为重复声明导致的问题:
for(var i = 0;i<3;i++) {
for(var i = 0;i<3;i++) {//因为var可以重复声明一个变量。 所以两个 for 循环的 i 是同一个变量
console.log(i)
}
}
//打印结果0 1 2 内层循环i执行完后,i的值为3,再去执行外层循环判断i时,i是3,直接跳出循环。
for(let i = 0;i<3;i++) {
for(let i = 0;i<3;i++) {//因为let不会重复声明一个变量。所以两个循环的i不是同一个i。是两个不同的对象
console.log(i)
}
console.log('内层循环结束');
}
// 打印结果:0 1 2 内层循环结束 0 1 2 内层循环结束 0 1 2 内层循环结束
for(let i = 0;i<3;i++) {
let i = 'foo';//let不可以重复声明,所以循环体内的i和循环遍历的i是不同的对象
console.log(i)
}
//会输出3次foo 因为:i = 0 1 2 和i = 'foo'其实是两个完全不一样的变量。
- 关于作用域的比较:var 定义的变量全局使用,let 只在作用域内有效
//var
var a = 5;
console.log(window.a); //5 var会污染全局作用域
{
var a = 1;
}
console.log(a); // 1
//let、const
let a = 5;
console.log(window.a); //undefined let 和 const只有块级作用域。不会污染全局。
{
let a = 0;
console.log(a); // 0
}
console.log(a); // 报错 ReferenceError: a is not defined
- var没有块级作用域带来的影响。
let ele = [{},{},{}];
for(var i = 0;i<ele.length;i++) {
ele[i].onclick = function() {
console.log(i)
}
// ele[i].onclick = (function(i) {//通过闭包,借助函数作用域来摆脱var声明的变量没有块级作用域带来的影响。
// return function() {
// console.log(i)
// }
// })(i)
}
ele[0].onclick();//输出3
ele[1].onclick();//输出3
ele[2].onclick();//输出3
//上述demo,为什么每次打印输出都是3?:因为通过var声明的i,可以重复声明,在循环结束时i的最终值是3。
// 使用let
let ele = [{},{},{}];
for(let i = 0; i<ele.length; i++) {
ele[i].onclick = function() {
console.log(i)
}
}
ele[0].onclick();//输出0
ele[1].onclick();//输出1
ele[2].onclick();//输出2
- 块级作用域内部的变量和外部的变量同名是互不影响的,相当于两个不同的变量
let n = 5;
if (true) {
let n = 10;
console.log(n); // 10
}
console.log(n); // 5
- ES6 引入了块级作用域,在外部无法访问到块级作用域申明的变量:
if(true) { //块级作用域
let flag = 123; //块内使用let定义的变量在外部是访问不了的
var ff = 456;
}
console.log(ff); // 456
console.log(flag); // 会报错说flag未定义
for(let i = 0;i<3;i++) {
console.log(i);// 0 1 2
}
console.log(i) //会报错i未定义,块级作用域
const:
const声明一个只读常量,声明后不允许改变,声明时必须初始化
const n = 1; //声明只读常量,必须初始化
n = 2;//报错 不允许重新赋值
const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不变:
-
对于简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的那个内存地址,因此 const 声明的简单类型变量等同于常量;
-
而复合类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针。所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了。
所以使用 const 声明复杂类型对象时要慎重。
在for循环中理解作用域
【注意:】
//尽管循环中的10个i是在各个迭代中分别定义的,但是它们都被封闭在一个共享的全局作用域中,因此实际上只有一个 i 。
for (var i = 0; i < 10; i++) {//【 var可以重复声明,全局使用,所以循环10次分别定义的对象i其实是同一个i 】
setTimeout(function(){
console.log(i);// 输出十个 10
})
}
for (let j = 0; j < 10; j++) { //【 let不可以重复声明,所以10次迭代定义的对象j是10个不同的j;若每次循环的变量 j 都是重新声明的,如何知道前一个循环的值?这是因为 JavaScript 引擎内部会记住前一个循环的值 】
setTimeout(function(){
console.log(j);// 输出 0123456789
})
}
暂时性死区:
var PI = "a";
if(true){
console.log(PI); // ReferenceError: PI is not defined
// const不存在变量提升.所以会报错
const PI = "3.1415926";
}
2.数组的解构和对象的解构
- 数组的解构
const [a, b, c] = [1,2,3];
console.log(a,b,c);// 1 2 3
const [ , , c] = [1,2,3];
console.log(c);// 3
const [name,,age] = ['wayou','male','secrect'];
console.log(name,age);// wayou secrect
// 给解构的成员提供一个默认值 如果解构没有得到值,就会使用默认值
const [a, b, c,d=77] = [1,2,3];
console.log(a,b,c,d);// 1 2 3 77
const path = '/foo/bar/baz';
const [, rootdir] = path.split('/'); // ["", "foo", "bar", "baz"]
console.log(rootdir);// foo ? rootdir是什么
- 对象的解构
const obj = {name:'111'};
const { name:objName = 'jack' } = obj;//name:objName表示修改变量名 console.log(objName);//'111'
const { a:objName = 'jack' } = obj;// = 表示赋予一个初始值 console.log(objName);//'jack'
const { a:objName } = obj;// console.log(objName);//undefined
const { a:objName } = obj;// console.log(a); 报错a is not defined
变量的解构赋值:
//let a = 1;
//let b = 2;
//let a=1,b=2;
//数组的解构赋值
let [a,b] = [1,2]; // a=1 b=2
let [a,b] = [,123] // a为undefined b=123
let [a=1,b] = [,123] //a=1 b=123
//对象的解构赋值
//---不强调顺序
let {foo,bar} = {foo:'hi',bar: 'hello'};
let {foo,bar} = {bar:'hello',foo:'hi'};
//对象的属性别名 相当于给对象重命名【如果有了别名,原来的名字就无效了】
let {foo:aaa,bar} = {bar:'hi',foo:'ha'};
console.log(aaa,bar); //输出的aaa就是变量foo的值'ha'
//对象的属性别名指定默认值
let {foo:aaa='ha',bar} = {bar:'hi'};
console.log(aaa,bar);
//对象直接赋值
let {cos,sin} = Math;
console.log(typeof cos);
console.log(typeof sin);
//字符串的解构赋值
let [a,b,c,d] = 'hello';
console.log(a,b,c,d); //输出的内容是h e l l 如果前面变量的个数和后面字符串的字符个数不对应,会把多余的忽略
//------------怎么得到字符串的字符的长度
let {length} = 'hi';
console.log(length); // 2
3.模板字符串:
- 可以被用作普通字符串;所有的空格、缩进和换行都会被保留在输出中
// 普通字符串
`In JavaScript '\n' is a line-feed.`
// 多行字符串
`In JavaScript this is
not legal.`
// 字符串中嵌入变量
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?` // Hello Bob, how are you today?
- 模板字符串中调用函数
function func() {
return 'Hello';
}
`${func()} World`;
// "Hello World"
- 支持换行符,并且可以通过
${}
获取变量值
const name = '77';
const msg = `hi,${name},
你开心吗
`
console.log(msg)
// 可以进行运算,以及引入对象属性。
var x = 1, y = 2;
`${x} + ${y} = ${x + y}`;
// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`;
// "1 + 4 = 5"
var obj = {x: 1, y: 2};
`${obj.x + obj.y}`
// "3"
- 使用标签的模板字符串:
const str = console.log`hello world`
//结果会输出['hello world']
let obj = {
username: 'lina',
age: '12',
}
let fn = function(info) {
return info;
}
let tag = '<div><span>'+obj.username+'</span><span>'+obj.age+'</span></div>';
let tpl = ' // 模板中的内容是可以在输出中显示格式的。通过${}的方式填数据
<div>
<span>${obj.username}</span>
<span>${obj.age}</span>
<span>${fn('nihao')}</span>
</div>';
console.log(tag); // <div><span>lina</span><span>12</span></div>
console.log(tpl);
//tpl输出的内容带格式的
//<div>
//<span>lina</span>
//<span>12</span>
//<span>nihao</span>
//</div>
- 模板中使用变量遵循一般规则
// 变量place没有声明
var msg = `Hello, ${place}`;//会报错
// 变量place不是字符串,会按照一般规则默认转字符串
var msg = `Hello, ${place}`;
// 变量place是对象,
var msg = `Hello, ${place}`;//会默认调用对象的toString()方法转字符串
4.字符串的扩展方法:
- str.startsWith(a) 判断a是否是字符串的的第一个字符 返回布尔值
- str.endsWith(a) 判断a是否是字符串的的最后一个字符 返回布尔值
- str.includes(‘ss’) 判断字符串中是否包含’ss’,返回布尔值
console.log('hello world'.includes('world')); //true
console.log('hello world'.includes('world',7)); //7表示从字符串的第7个字符开始找是否包含'world'字段 false
//判断字符串中是否包含某段字符
str.match(sonstr) //如果包含会返回数据,如果不包含会返回null
//startWith()
let url = 'admin/index.php';
console.log(url.startsWith('aadmin')); //判断字符串url是否以'aadmin'开始 true or false
//endsWith() 判断字符串是否以某字段结尾
5.函数的参数默认值
// ES6;
function printText(text = 'default') {
console.log(text);
}
printText('hello'); // hello
printText();// default
…展开符 / Spread / Rest展开符
function foo(...args) {
console.log(...args)
}
const arr = [1,2,3,4,5];
console.log(foo(arr));// [1, 2, 3, 4, 5]
console.log(...arr);// 1 2 3 4 5
function foo(...args) {
console.log(args);
}
foo( 1, 2, 3, 4, 5 ); // [1, 2, 3, 4, 5]
//将所有参数相加的函数
function add(...x){//通过...接收不定数量的未命名参数
return x.reduce((i,sum)=>i+sum);
}
//传递任意个数的参数
console.log(add(1,2,3));//输出:6
console.log(add(1,2,3,4,5));//输出:15
箭头函数
- 箭头函数不会改变this的指向。箭头函数的外层的this是什么,箭头函数里面的this的指向就是什么。
- 不需要function关键字,省略return。继承上一层的this。
const person = {
name:'tom',
sayHi: () => {
console.log(this.name);//
},
sayHiAsync: function() {
setTimeou(function() {
console.log(this.name);
},1000)
setTimeou( () => {
console.log(this.name);
},1000)
}
}
person.sayHiAsync();
对象字面量的增强:对象的属性可以是字符串,数字,方法,等等,还可以直接定义原型
const bar = [222,44];
const human = {
run() {
console.log('running');
}
};
const obj = {
__proto__:human,//设置obj对象的原型为human,相当于继承human
foo:'123',
bar,
method1:function() {
//...
console.log(this)
},
method2() {
///...
},
[Math.random()]:777 //属性名,使用方括号包裹,里面可以使用[任意表达式],函数等。
}
console.log(obj);
obj.method1();
human.run();// running
obj.run();// running 继承来自human的方法
Proxy:监听对象。会自动调用get和set方法用来设置属性和获取属性。
相比于defineProperty,Proxy可以监听到更多的对象操作【比如对删除操作进行处理和监听;】,可以更好的支持数组对象的监视
// Proxy( obj,{ get(){}, set(){} } )//监听对象obj,处理程序{}
const person = {
name:'77',
age:25
}
const myProxy = new Proxy(person,{
get(target,key) {
console.log('get...',key)
return key in target? target[key] : '默认值';
},
set(target,key,value) {
console.log('set...',key,value)
target[key] = value;
return true
}
})
console.log(myProxy.name);//get... name , return 77
myProxy.gender = 'femail';//set... gender femail, return target[gender]
console.log(myProxy.gender);//get... gender, femail
console.log(myProxy.aa);// get... aa,默认值
Reflect 属于一个静态类。不能通过new调用。通过Reflect调用API。类似Math对象API
Set 类似于Array
- Set.add(item) 不允许添加重复元素 类似Array.push
- Set.delete(item)
- Set.clear()
- Set.size 类似于 Array.length
const s = new Set();
s.add(1).add(2).add(2).add(7);//s: Set {1,2,7} 不会添加重复元素
const arr = [1,2,3,5,3,5]
const newarr = new Set(arr);//newarr: [1,2,3,5]
newarr.delete(3);//[1,2,5]
console.log(newarr.size);//3 类似于arr.length
newarr.clear();//[] 清空数组
Map 键值对集合 类似于Object
- Map与Object最大的区别是:Map的键可以是任意类型
- Map.set(key,value);设置对象的属性值 key可以是任意类型
- Map.get(key) 获取对象中某个属性的值
- Map.has(key) 判断对象中是否包含某个对象
- Map.delete(key); 删除对象中某个元素
- Map.clear() 清空对象
demo:
const m = new Map();
const tom = { name:'tom' };
m.set( tom, 90 );// 设置键值对
console.log(m); //Map { {name:'tom'} => 90 }
m.get(tom);//90
m.has(tom);// === true
const s = new Map();
s.set('hello',77);
s.set(m,00);
s.get('hello');//77
s.get(m);//0
console.log(s)
Symbol 是一种数据类型 ,适合用作对象的私有属性
- 通过Symbol创建的每一个对象都是唯一的,永远不会重复。所以它最主要的作用是[为对象添加独一无二的属性名,用作对象的私有属性]
// Symbol 和 String 一样,是一种数据类型
console.log(String('aaa'));
console.log(Symbol('bbb'));
// 通过Symbol创建的每一个值都是唯一的,永远不会重复
console.log( Symble('aaa') === Symble('aaa') );//false
- Symble.for接收一个字符串作为参数
// Symble.for接收一个字符串作为参数,相同的字符串返回的Symbol类型的值是一样的
const s1 = Symble.for('aaa');
const s2 = Symble.for('aaa');
console.log(s1 === s2);//true
// Symbol.for()接收字符串作为参数,所以布尔值作为参数传入会自动转为字符串。 所以最后结果是true
console.log(Symbol.for(true) === Symbol.for('true'));//true
- Symbol.toStringTag 是内置的一个Symbol常量
// Symbol.toStringTag 是内置的一个Symbol常量
const myobj = {
[Symbol.toStringTag]: 'aaa'
}
console.log(myobj.toString());//[object aaa]
- Symbol的主要作用是为对象添加私有属性。🔺
- 通过for…in…循环遍历不到Symbol类型;
- Object.keys获取不到Symbol类型;
- 通过JSON.stringify序列化对象获取不到Symbol类型;
所以说它的最主要作用是为对象添加独一无二的属性名,将它作为对象的私有属性。
const obj = {
[Symbol()]: 'my symbol value1',
a: 'ppp'
}
for(let key in obj) {//for...in... 循环遍历不到Symbol类型
console.log(key);//只会输出 a,
}
console.log(Object.keys(obj));//Object.keys获取不到Symbol类型
console.log(JSON.stringify(obj));//通过JSON.stringify序列化对象获取不到Symbol类型 输出结果是:{"a":"ppp"}
- 通过 Object.getOwnPropertySymbols(obj) 可以获取到对象中使用Symbol创建的属性名。
Object.getOwnPropertySymbols(obj);
ES6目前是7中数据类型,Array,Object,String,Boolean,Number,NAN,Symbol,[BigInt]
for of 循环:遍历任何数据类型的一种统一方式 some every
for(let item of arr) {
//获取数组中的元素
console.log(item);
break;
}
for(let key in arr) {
//获取的是数组中元素的key值
console.log(arr[key])
}
/*
- forEach()不能跳出循环
- arr.some() 中 return true 终止遍历
- arr.every() 中 return false 终止遍历
- for...of... 中使用 break 关键字终止循环
*/
Iterable类型:可迭代接口 迭代器模式 实现场景:使得for of循环可以遍历任何数据类型。?
const obj = { foo:123, bar:234 };
for(const item of obj) {
console.log(item);//obj is not iterable 意思是obj是不可以迭代的。不可以遍历的 【Map类型可以】
}
const iterator = arr[Symbol.iterator]();
console.log(iteretor.next());
const myobj = {
a:[],
b:[],
[Symbol.iterator] : //通过Symbol类型定义一个对象内的常量 迭代器的意义是:对外提供统一的遍历接口,使得外部不需要关系内部结构的变化
function() {
const all = [...a,...b];
let index = 0;
return {
next: function() {
return {
value: all[index],
done: index++ >= all.length//返回布尔值
}
}
}
}
}
生成器函数 :会自动返回一个生成器对象,调用对象的next方法,函数体才会执行,函数体会一旦遇到yield就会暂停执行,返回一个生成器对象。
function * foo() {
yield 'foo' //使用yield可以随时向外部返回一个值,并[暂停]当前生成器函数的调用。直到对象下一次再调用.next()时,函数才会从yield之后继续执行到结束。
return 100;
}//这就是一个生成器函数 返回的是一个对象,调用next()后返回的是 {value:100, done:true} 同迭代器返回值的结构一样
- 调用生成器函数不会立即执行函数,而是返回一个对象。通过对象调用.next()才会开始执行生成器函数。
const myfunc = foo();
myfunc.next();//才会执行函数
- 如果myfunc.next(11)传入一个参数时,参数会作为yield的返回值 相当于
js const b = yield a;//打印b为11
js myfunc.throw(new Error('抛出异常'))
生成器函数的应用:实现发号器
function * AA() {
let id = 1;
while(true) {//while true是个死循环,但里面使用了yield。会暂停执行,所以这么写不会造成死循环。只有等到生成器对象调用next之后才会继续执行
yield id++;
}
}
Generator:更优的异步编程写法
生成器函数
扁平化的异步编程,Generator函数执行后得到的是一个Generator对象[生成器对象],通过.next()方法调用执行结果
ES Modules:ES2015语言层面上的模块化规范
ES2016:小的提升,比如Array.includes(x) 判断数组中是否存在某个指定元素
- 比includes方法更早的方法,Array.indexOf(x) ,这个方法的弊端是无法查找NAN
- Math.pow(a,b) //a的b次幂
ES2017 :
- String.padStart(n,‘0’) 表示字符串共n位,不够n位的用0从头开始填充
- String.padEnd(n,’*’) 表示字符串共n位,不够的从后面用
*
填充 - Object.getOwnPropertyDescriptors() 获取对象的完整描述
- async await :本质上是使用promise的语法糖
-
const books = { html: 5, css: 6, javascript: 128 } for(const [name,count] of Object.entries(books)) { console.log( `${name.padEnd(16,'-')} | ${count.toString().padStart(5,'0')}` ); // html------------ | 00005 // interview.html:91 css------------- | 00006 // interview.html:91 javascript------ | 00128 } //get set 方法 //Object.getOwnPropertyDescriptors() 获取对象的完整描述
有关函数参数
- 函数中的默认参数最好写在其他参数的后面
rest
参数之后不能再有其他参数rest
参数可以替换arguments
类数组的使用
可以对对象的数据实施拦截的是:?
- Object.defineProperty()
- new Proxy()
类的继承:extends 继承
有关class的说法: 类的实现是原型链的语法糖表现形式。
- 子类的构造器中
super
关键字的前面不能出现this
关键字 new
实例对象的时候,其实就是调用类的构造器方法,且返回这个实例对象- 静态方法的实现需要在方法名的前面加上
static
关键字。静态方法只能被当前类和子类的实例对象访问 - 私有方法是能在当前类的内部使用
class Person {
constructor(name) {
this.name = name;
}
say() {
console.log(`my name is ${this.name}`)
}
}
class Student extends Person {
constructor(name,age) {
super(name);//super始终指向父类,在子类构造函数中使用super会去调用父类的构造函数
this.age = age;
}
hello() {
super.say();//指向父类的say方法
console.log(`hello ${this.age}`)
}
}
const ss = new Student('77',24);//my name is 77 hello 24
模块化
promise 和 generator
promise.all
promise.race
ES6中,为 Math,Number,String,Object 添加的新API ?
Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false
Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
"abcde".contains("cd") // true
"abc".repeat(3) // "abcabcabc"
Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1,2,3].findIndex(x => x == 2) // 1
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"
Object.assign(Point, { origin: new Point(0,0) })
Object的扩展方法:
1. Object.assign(target,source) 返回{}
- 合并两个对象,会改变目标对象。返回的对象就是目标对象。
- 如果源对象和目标对象都有相同的属性,目标对象中的属性值会被源对象的值覆盖掉。
- 如果源对象中存在目标对象中没有的属性,源对象中的该属性会添加到目标对象中。
- 总结就是:以第一个对象为基础,和后面一个对象作比较,第一个对象没有的内容会添加进来;两个对象重复的内容,第一个对象的内容就会被覆盖/替换。
- 使用场景:Object.assign({},obj); 对obj进行深拷贝,因为使用新Object{}复制了一份obj,返回的是新的Object,obj不受影响。
const target = { a:111, b:222 };
const source = { a:333, f:777 };
const newobj = Object.assign(target,source);//target理解为目标对象,source理解为源对象。
console.log(newobj);//{ a:333, b:222, f:777} 两个对象中都有a属性,目标对象中的值会被覆盖,所以a:333。
console.log(newobj === target);//true
Object.assign(obj1,obj2,obj3);//如果传递了多个对象,后面的每个对象会依次和第一个对象进行比较。
2. Object.is(val1,val2) 返回布尔值,用来判断两个值是否严格相等,
- 与(===)基本类似。 用的少,建议使用 == / ===
Object.is(+0,-0);//false
+0 === -0 //true
Object.is(NAN,NAM);//true
NaN === NaN //false
Object.is("q","q"); // true
Object.is(1,1); // true
Object.is([1],[1]); // false
Object.is({q:1},{q:1}); // false
3. Object.setPrototypeOf(child, parent) 对象超类:
let parent = {
foo() {
console.log("Hello from the Parent");
}
}
let child = {
foo() {
super.foo();
console.log("Hello from the Child");
}
}
Object.setPrototypeOf(child, parent);
child.foo(); // Hello from the Parent
// Hello from the Child
4. Object.defineProperty:监听属性的读写过程: 只能监听到数据的读取和写入。可理解为门卫的职责,不管是进入还是出去都必须经过门卫。
Number的扩展方法
Number.isInteger(value) 判断value是否是整数
console.log(Number.isInteger(8));//true
console.log(Number.isInteger('7'));//false
console.log(Number.isInteger(1.1));//false
Array的扩展方法:
Array.from();
Array.of()
Array.find()
Array.findIndex()
Array.includes()
Array.entries()
Array.keys()
Array.values()
正则的扩展方法
关于es6新特性的总结:
看完这篇HTTP,跟面试官扯皮就没问题了
Vue.js面试题整理
必须要会的 50 个React 面试题
前端ES6面试题
ES6 新特性 总结
ES6常用新特性总结
es6新特性有哪些
博客园大佬_龙恩0707
阮一峰 ES6入门教程