1. let、const、var定义变量的区别是什么?
let
- 块作用域
- 没有变量提升
- 不能重复声明
- 属于顶层对象
const
- 声明常量,不能修改
- 必须初始化
- 块作用域
- 没有变量提升
- 不能重复声明
- 属于顶层对象
var
- 没有块的概念
- 可以夸块访问,但是不能跨函数访问
- 会进行变量提升
2. promise分为几种状态?什么时候会进入catch方法?
三种状态
- pending
- fulfulled
- rejected
状态变为rejected的时候会进入catch方法
3. 箭头函数和普通函数的区别是什么?
声明方式不同
- 普通函数通过function声明
- 箭头函数通过=>声明
箭头函数不能用于构造函数
this指向不同
- 普通函数this指向调用这个函数的地方
- 箭头函数this指向声明这个函数的地方
4. == 和 === 有什么区别?
- == 比对值
- === 比对值和类型
5. 如何在多个Promise执行完成之后做一些操作?多个Promise同时执行有一个执行完了就进行一些操作?
- Promise.all([多个Promise]).then(res=>{})
- Promise.race([多个Promise]).then(res=>{})
6. 如何获取对象的所有key值?
包含Symbol使用Reflect.ownKeys()
不包含Symbol使用Object.keys()
只有Symbol使用Object.getOwnPropertySymbols()
7. 扩展运算符(对象展开符)的一些操作
const obj = {
id:123,
age:20,
name:"cyrus",
school:"河北科技大学"
}
let obj1 = {
age:18,
...obj,
name:"李四"
}
console.log(obj1.age); //20
console.log(obj1.id); //123
console.log(obj1.name); //李四
扩展运算符提供了数组合并的新写法。
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
var arr1 = ['a', 'b'];
var arr2 = ['c'];
var arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]
与解构赋值结合的一些应用,实现数组操作。但注意如果将扩展运算符用于数组赋值,只能放在参数的最后一位。
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
下面是另外一些例子。
const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]
const [first, ...rest] = [];
first // undefined
rest // []:
const [first, ...rest] = ["foo"];
first // "foo"
rest // []
扩展运算符内部调用的是数据结构的 Iterator 接口,因此只要具有 Iterator 接口的对象,都可以使用扩展运算符,比如 Map 结构。
8. Promise简单例子
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve(3);
console.log(2);
reject(4)
})
promise.then((res) => {
console.log(res);
}).catch(err=>{
console.log(err);
})
console.log(5);
// 1 2 5 3
9. Symbol
凡是使用 symbol 命名的属性都是独一无二的,保证不与其他属性名产生冲突。
JavaScript 中大多数的数值都支持隐式转换为字符串,但 symbol 不会转换,如果有需要仍可以调用toString方法转换。
Symbol.for(key) 方法会根据给定的键 key,来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。
let name = Symbol('name')
let name1 = Symbol.for('name')
console.log(name == name1);// false
10. yield
yield 关键字用来暂停和恢复一个生成器函数((function* 或遗留的生成器函数)。
yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
简单使用
function* countAppleSales () {
var saleList = [3, 7, 5];
for (var i = 0; i < saleList.length; i++) {
yield saleList[i];
}
}
var appleStore = countAppleSales(); // Generator { }
console.log(appleStore.next()); // { value: 3, done: false }
console.log(appleStore.next()); // { value: 7, done: false }
console.log(appleStore.next()); // { value: 5, done: false }
console.log(appleStore.next()); // { value: undefined, done: true }
复杂使用
next() 传参是对yield整体的传参,否则yield类似于return
function* test(x) {
let y = 2*(yield (x+1))
ley z = yield(y/3)
return (x + y + z)
}
let b = test(5)
b.next()
b.next(12)
c.next(13) // {value:42, done:true}
在前端项目中,用的机会很少,完全可以忽略他的存在,但是在后台项目中,就显得比较重要了,因为其优越的可控性,可是极大的提升线程的效率。
目前只是根据官网,ES6规范,大站等总结出来的,但是很遗憾,目前我们的项目中由于node项目较简单,并不需要进行实际改造。
11. Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
12. 解构赋值
使用解构赋值,实现两个变量的值的交换。
他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。
let a=5;
let b=3;
[a,b]=[b,a]
console.log(a);
console.log(b);
13. Set
Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
使用set实现数组去重
let list = [1,3,4,6,2,2,2,3,1,2,3,4]
let set = new Set(list)
let newList = Array.from(set)
14. ES6导入导出模块
// a.js
// 默认导出
const test = "测试"
export default {
name:"李白",
age:18,
test
}
// 普通导出
export function getName(){
console.log(123)
}
export const cat = "皮皮"
// b.js
// 默认导入
import aObj from './a.js'
console.log(aObj.name) //李白
// 普通导入
import {getName,cat} from './a.js'
console.log(cat)
getName()
15. ES6数组新增的方法
filter、find、map、some
const list = [
{id:3,name:"张三丰"},
{id:5,name:"张无忌"},
{id:13,name:"杨逍"},
{id:33,name:"殷天正"},
{id:12,name:"赵敏"},
{id:97,name:"周芷若"},
]
console.log(list.filter(item => item.name.startsWith("杨")))
console.log(list.filter(item => item.name.includes("天")))
console.log(list.find(item => item.name == '周芷若').id)
const list = [
{id:3,name:"张三丰"},
{id:5,name:"张无忌"},
{id:13,name:"杨逍"},
{id:33,name:"殷天正"},
{id:12,name:"赵敏"},
{id:97,name:"周芷若"},
]
console.log(list.map(item=>({...item,id:item.id*2,updateTime:new Date()})));
function f(value, index, ar) {
if (value % 2 == 0) {
return true;
}
}
var a = [1,15,4,10,11,22];
var evens = a.some(f);
if (evens) {
console.log("不全是奇数。");
} else {
console.log("全是奇数。");
}
16. 循环新增的 for of 和 for in
记忆方式 foreign key ,意思是 in是key值。
const arr = ["xiaoxi", "xiaoxi233"]
for(let value of arr){
console.log(value) //xiaoxi xiaoxi233
}
for(let key in arr){
console.log(key) //0 1
}