题: (function fn() {
var a=b=1
})();
console.log(b);
console.log(a);
解: 本例可以分解为 window.b = 1; var a = window.b
(1) JS的连等赋值是从右往左执行的
(2) 对未声明变量的赋值将使其成为全局变量
(3) 外部作用域无法访问内部作用域中定义的变量, 因此 a 未定义
答: 1, not defined
题: var a = b = 1;
console.log(delete a);
console.log(delete b)
解: 可分解为 window.b=1; var a=b;
(1) JS的连等赋值是从右往左执行的
(2) delete 不能删除 var 定义的变量(let/const/function 也不行)
答: false true
注: delete 删除 数字、字符串、不存在的变量、null 等也会返回 true, 删除 undefined、NaN 返回 false
题: var a = {n: 1};
题: var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x);
console.log(b.x);
解: 此例可以分解为
var a = {n: 1}; var b = a;
var temp = a.x;
a = {n: 2};
temp = a;
b.x = temp;
(1) JS 中取值操作(. [])优先级最高, 赋值操作优先级接近最低, 因此 a.x = a = {n: 2}; 部分应当看做 (a.x) = a = {n: 2} 而不是 a.x = (a = {n: 2})
(2) JS的连等赋值是从右往左执行的
(3) 在 a = {n: 2}; 阶段,a 已经失去了之前的引用,因此对 旧a 的 x 属性赋值不影响 新a,而 b 仍然持有对 旧a 值的引用,因此 a.x = undefined; b.x = {n: 2}
答: undefined {n: 2}
题: ['1','2','3'].map(parseInt)
解: 此例可分解为 ['1','2','3'].map((val, index) => parseInt(val, index))
(1) map 的参数为 (val, index, arr)
(2) parseInt 的第二个参数为基准进制, 取值2-36
(3) 基准进制为0或缺省时取10, 返回1, 进制为1非法, 进制为2时, 值比进制还大, 同样非法
答: [1, NaN, NaN]
题: for(let i=0;i<10;i++) {
let i = 10;
console.log(i)
}
解: for 循环的循环语句在执行体的块级作用域外又套了一层作用域, 因此执行体内部(内部作用域)可以访问循环语句(外部作用域)中定义的变量,并且执行体中定义的变量不与循环体冲突
答: 10个10
题: 实现 add(1)(2)(3)(4) = 10
解: 函数内部得有一个变量维护 当前和, 函数的基本执行逻辑是对 当前和 与 入参 求和, 函数应当返回一个新函数供下一次调用
前两个逻辑并不难实现,但 “函数应当返回一个新函数供下一次调用”,关键在于如何实现函数同时返回 求和的结果 和 下一次调用的函数
实现此功能的核心在于,函数在 return 时,会调用返回值的 toString 方法后再输出, 因此可以覆盖返回值的 toString 达到我们的目的
(1) 首先实现一个分解版本
function add(initVal) { let total = initVal || 0 function sum(p) { total = total + p return total } return sum } var a = add(1) a(2) // 3 a(3) // 6 a(4) // 10(2) 上述版利用闭包维护了 当前和 ,实现了持续相加的功能,但sum的返回值是数值,无法连续调用,因此稍加改造,让其可以连续调用即可
function add(initVal) { let total = initVal || 0 function sum(p) { // 严谨一点的话可以在这里加个入参类型判断,因为每次连续调用,实际上都在调用这个函数 total = total+p return sum // 返回值改为sum,使得可以连续调用 } sum.toString = function() { return total } // 通过 return 返回时会自动调用 toString 的特性,改为在 toString 中输出结果 return sum } add(1) // 1 add(1)(2) // 3 add(1)(2)(3) // 6 add(1)(2)(3)(4) // 10