闭包综合练习

124 阅读2分钟

1. 以下代码的执行结果是

const obj = "string";
console.log(typeof(obj) === "string")    // true
console.log(typeof obj === "string")    // true
console.log(obj.constructor === String) // true 

2. 106455 => 106,455 (将数字每千分位用逗号隔开,不考虑浮点数)

function toThousandth(num) {
    num = num + ""
    var str = ""
    for (var i = num.length - 1, j = 1; i > -1; i--, j++) {
        if(j%3 == 0 && i != 0){
            str += num[i] + ","
            continue
        }
        str += num[i]
    }
    return str.split('').reverse().join('')
}
console.log(toThousandth(106455));  // 106,455

针对浮点数

function toThousandth(num) {
    return num && num.toString().replace(/(\d)(?=(\d{3})+\.)/g, function ($1, $2) {
        return $2 + ',';
    })

}
console.log(toThousandth(1064.55));  // 1,064.55

3. setTimeout模拟实现setInterval

var timer;
var i = 1;
timer = function () {
    i++;
    console.log(i);
    if (i == 10) {
        timer = function () {
            console.log("终止运行");
        }
    }
    setTimeout(timer, 500);
};
console.log(timer);
setTimeout(timer, 2000);

改写

function fn(i) {
    console.log(i);
}

function intervel1(fn, timer, s) {
    let i = 0;
    function func() {
        fn.call(fn, ...arguments)
        i++;
        i < s && setTimeout(function () {
            func.call(func, ...arguments)
        }, timer, ...arguments)

        // i < s && setTimeout(() => func.call(func, ...arguments), timer)
    }
    return func
}

const f = intervel1(fn, 1000, 10)
f('hello')

4. 根据结果完成代码

已知函数fun如下:
function fun(n,o) {  
  console.log(o)  
  return {    
    fun:function(m){    //fun: 对象   
      return fun(m,n);    
    }  
  }; 
}
已知第一行结果执行代码如下:
var one = fun(0);  
one.fun(1);
one.fun(2);
one.fun(3);
结果:
undefined 0 0 0

完成以下两行结果执行代码
undefined 0 1 2
undefined 0 1 1
var one = fun(0); 
one.fun(1).fun(2).fun(3);

var two = fun(0);
two.fun(1).fun(1).fun(1);

原因:一直产生闭包。one就是 fun:function() 这个对象,key为fun,value就是这个一个入参的函数,传入的参数m经过函数调用赋值给了n。one.fun(1); 就是 fun(1,0) one.fun(1).fun(2).fun(3); 每次调用打印上一次的n

5. 下面的函数 createStack() 用于创建栈结构:

function createStack() {
  return {
    items: [],
    push(item) {
      this.items.push(item);
    },
    pop() {
      return this.items.pop();
    }
  };
}

const stack = createStack();
stack.push(10);
stack.push(5);
stack.pop(); // => 5

stack.items; // => [10]
stack.items = [10, 100, 1000]; // 栈结构的封装被破坏了

它能正常工作,但有一个小问题,因为暴露了 stack.items 属性,所以任何人都可以直接修改 items 数组。这是一个大问题,因为它破坏了栈的封装:应该只有 push()pop() 方法是公开的,而 stack.items 或其他任何细节都不能被访问。

使用所学知识重构上面的栈实现

// 把items: [] 返回结果中提取出来
function createStack() {
  let items = [];
  return {
    ……
  }
}

把items 移至 createStack() 作用域内就可以。现在 items 就相当于是一个私有变量,并且栈被封装,只有 push() 和 pop() 方法是公共的,createStack() 作用域的外部无法访问或修改 items 数组。

6. 编写一个函数 multiply() ,将两个数字相乘:

如果用 2 个参数调用 multiply(num1,numb2),则应返回这 2 个参数的乘积。

但是如果用 1个参数调用,则该函数应返回另一个函数: const anotherFunc = multiply(num1) 。返回的函数在调用 anotherFunc(num2) 时执行乘法 num1 * num2

function multiply(num1, num2) {
    if(num1 && num2) {
        return num1 * num2;
    }

    if(typeof(num2) === 'undefined') {
        return function(num2) {
            return multiply(num1, num2);
        }
    }
}

const f = multiply(3);
console.log(f(4));