1.易错点
1.1 if语句中的变量提升
// 从结果对比可以看出,if语句里面虽然无法执行,但是还是可以有预编译,即变量b得到提升
if(false){
var b = "df";
}
console.log(b)
// undefined
console.log(a);
// Uncaught ReferenceError: a is not defined
1.2 形参不能给自己赋值
// 此处貌似可以这样理解:既然参数里面中 w + 1的 w 都能向全局找到var w;
// 那为什么 z + 1 中的 z 不可以找到var z 的呢?
// 正确的理解:(z + 1 中的z发现z是一个此刻还没有初始化的参数变量,
// 所以它永远不会试图从外层作用域寻找z;
// 形参不能给自己赋值;
var w = 1, z = 2;
function foo(x = w + 1, y = x + 1, z = z + 1) {
console.log(x + y + z);
}
foo()
// Uncaught ReferenceError: z is not defined
1.3.解构默认值 + 参数默认值
function foo({x = 10} = {},{y} = {y : 10}){
console.log(x,y)
}
// 函数中实参为空或者undefined,函数形参自行解构赋值的x = 10,y =10
foo()
foo(undefined,undefined)
// 第一个参数为{}时,形参函式为{x = 10} = {}
foo({},undefined)
// 上面三个结果均为10,10
foo({},{})
foo(undefined,{})
// 这两个均为10, undefined
2.let , const, ...args要点
2.1 let 声明
- 不提升变量
- 创建块级作用域
- for循环中的使用:let声明的i,作用域为for循环“上下文”
// 使用let相当于创建了一个块级作用域
{
for (let i = 0; i < 5; i++) {
console.log(i)
}
}
- 暂时性死区:let声明应该放在对应作用域的前面
{
console.log(a)
// Uncaught ReferenceError: a is not defined
// let a 前面都属于暂时性死区
let a = 4;
}
- 不能重复声明
2.2 const 声明
- 同let一样是在块级作用域中声明,不过创建的是常量
- 创建的是复杂值,则可对该值的内容做修改
- 通过const创建的值不易被垃圾回收。原文:将一个对象或数组作为常量赋值,意味着这个值在这个常量的词法作用域结束之前不会被垃圾回收,因为指向这个值得引用没有清除。
2.3 spread或rest
- 概念:运算符...,通常被称为spread或rest(展开或收集)运算符,取决于它在哪/如何使用。即扩展运算符/收集运算符。
- 代替函数中arguments使用。...args在函数作为参数使用,被称为“rest参数”,相比较arguments是真正的数组。
- 字符串的展开成数组。
var arr = [..."sdff"] 展开后为
["s", "d", "f", "f"]
- 合并数组
var arr = [3, 5, 3], arr1 = [3, 3, 3, 6];
// 合并数组,相当于contact函数
arr.push(...arr1);
// 二维数组展开成一维
var arr3 = [...arr, ...arr1];
console.log(arr)
// [3, 5, 3, 3, 3, 3, 6]
console.log(arr3)
// [3, 5, 3, 3, 3, 3, 6, 3, 3, 3, 6]
- 在call()函数中使用,等价于使用apply()
var args = [2,4,5,2,5]
fn.call(null,...args)
fn.apply(null,[2,4,5,2,5])
function fn(...args){
console.log(...args)
}