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) }