JS 事件循环,闭包,作用域链题

1,296 阅读2分钟
  • JS的事件循环机制

console.log('one')
setTimeout(function () {
    console.log('two')    
}, 0)
console.log('three')

输出是

one
three
two

此题的关键是JS的事件循环机制,对异步的处理操作,JS有句口令:同步优先、异步靠边、回调垫底。

第一个console.log是同步执行,直接输出one

执行完遇到setTimeout回调(垫底执行),把setTimeout丢到回调消息队列等待

然后console.log('three')也是同步执行,直接输出three,同步的消息队列全部执行完后轮到回调队列执行输出two

  • 闭包与作用域相关题目

function test() {
    var n = 4399;
    function add() {
        n++;
        console.log(n);
    }
    return {
        n: n,
        add: add
    }
}
var result = test(); 
var result2 = test(); 
result.add();
result.add(); 
console.log(result.n); 
result2.add(); 

输出

4400
4401
4399
4400

此题的关键在于明白var result = test() 与var result2 = test()此处分别产生了两个闭包,它们之间是独立,互不干扰的

闭包的产生:在A函数中定义了B函数,B函数中引用了A函数中的变量,此时会产生闭包

var result = test()  // 设置result的属性为: { n:4399, add: add() }
var result2 = test()  // 设置result2的属性为: { n:4399, add: add()  }result.add() // 调用了result的add方法,执行n++,所以n = 4399 + 1 输出4400
result.add() // 再次调用了result的add方法,此时n = 4400 所以n = 4400 + 1 输出4401

console.log(result.n)  //这是输出result的属性n值,输出4399,这里是输出对象属性返回值,并无调用闭包

result2.add() // 调用了result2的add方法,此时n = 4399 所以n = 4399 + 1 输出4400

 

  • 作用域链的题目

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);
	console.log(self.foo);
	(function() {
	    console.log(this.foo);
	    console.log(self.foo);
	}());
    }
};
myObject.func();

输出

bar
bar
undefined
bar

此题关键理解: 方法或函数由谁调用,方法函数内部的this就指向谁

1、func由myObject调用,this指向myObject,输出bar

2、self 指向myObject,输出bar

3、立即执行匿名函数表达式由window调用,this指向window

4、立即执行执行函数在本作用域找不到self,沿着作用域链向上寻找self变量,找到了父函数中指向myObject对象的self