1、let 和const(定义变量)
(1)var 、let 、const的区别
a、作用域区别
var 变量声明会被提升,
let、const变量声明不会被提升,并是块级作用域
b、定义的次数区别
var 可以重复声明,后面声明的值会赋盖前面声明的值
let、const在同一作用域中,只能声明一次
c、分配的内存区别
var 会直接在栈内存里预分配内存空间
let const 都不会在栈内存里预分配内存空间,在栈内存分配变量时,做一个检查,如果已经有相同的变量名就会报错
(2)let 、const的区别
a.变量修改的区别
let定义的变量是可以修改的
const定义的变量
对于基本类型来说,无法修改定义的值,
对于引用类型来说,无法修改栈内存里分配的指针,但可以修改指针指向的对象里面的属性值
b、const声明之后必须立马赋值,否则会报错
总结:
在let和const之间,建议优先使用const,尤其是在全局环境,不应该设置变量,只应设置常量。
JavaScript 编译器会对const进行优化,所以多使用const,有利于提高程序的运行效率,也就是说let和const的本质区别
其实是编译器内部的处理不同。
所有的函数都应该设置为常量。
2、扩展运算符
平时开发更多用于数组的合并,还有数组的复制
3、字符串模板
你好啊
相当于 '你好啊'
var a = 1
var html = `今天是几号,是${a}`
console.log(html) //今天是几号,是1
4、字符串新增的方法 includes(), startsWith(), endsWith()
includes():返回布尔值,表示是否找到了参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
let s = 'Hello world!';
s.startsWith('Hello') // true
s.endsWith('!') // true
s.includes('o') // true
let s = 'Hello world!';
s.startsWith('world', 6) // true
s.endsWith('Hello', 5) // true
s.includes('Hello', 6) // false
5遍历对象
(1)for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
(2)Object.keys(obj)
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
(3)Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
(4)Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
(5)Reflect.ownKeys(obj)
Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
首先遍历所有数值键,按照数值升序排列。
其次遍历所有字符串键,按照加入时间升序排列。
最后遍历所有 Symbol 键,按照加入时间升序排列。
Reflect.ownKeys({ [Symbol()]:0, b:0, 10:0, 2:0, a:0 })
// ['2', '10', 'b', 'a', Symbol()]
6、对象新增的方法
(1)Object.assign()(对象的合并去重,浅拷贝)
Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
注:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
7、Symbol
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
8、Set 数组去重 Map数据结构
// 例一
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5
// 例三
const set = new Set(document.querySelectorAll('div'));
set.size // 56
// 类似于
const set = new Set();
document
.querySelectorAll('div')
.forEach(div => set.add(div));
set.size // 56
上面代码也展示了一种去除数组重复成员的方法。
// 去除数组的重复成员
[...new Set(array)]
//上面的方法也可以用于,去除字符串里面的重复字符。
[...new Set('ababbc')].join('')
// "abc"
9、Promise
(1)promise的出现解决了什么问题
消灭嵌套调用(解决回调地狱):通过 Promise 的链式调用可以解决 .then();
合并多个任务的请求结果:使用 Promise.all 获取合并多个任务的错误处理。
Promise 解决的是异步编码风格的问题
(2)Promise 基本特征
a、promise状态不受外界的影响。
promise对象代表一个异步操作,有三种状态:
pending(进行中)
fulfilled/resolved(已成功)
rejected(已失败)
只有异步操作结果,可以决定当前是哪一种状态 ,任务其他操作都无法改变这个状态。
b、promise状态一旦改变,就不会发生变化,任何时候都可以得到这个结果。
promise状态改变,只有两种可能
从pending变为fulfilled(进行中变为已成功)
从pending变为rejected(进行中变为已失败)
promise.then(res=>{
//对于成功回调接受数据做处理
},err{
//对于失败的回调数据做处理
})
(3)asyc await 和promise有什么不同
(4)promise的缺点
1)无法取消Promise,一旦新建它就会立即执行,无法中途取消
2)如果不设置回调函数,Promise内部抛出的错误,不会反映到外部
3)当处于pending状态时,无法得知目前进展到哪一个阶段,是刚刚开始还是即将完成
10、箭头函数
// bad
[1, 2, 3].map(function (x) {
return x * x;
});
// good
[1, 2, 3].map((x) => {
return x * x;
});
// best
[1, 2, 3].map(x => x * x);
注:箭头函数没有this指向