下面这个例子是考虑这种情景下:
- 一个构造函数 内部返回一个相同的构造函数①
- 这个构造函数的参数是一个函数 构造函数内的最后一行会执行这个参数 而这个参数还有一个参数这个参数是函数 类似于fn(fn(fn()))②
- 构造函数内设置一个数组 一个私有变量 再加一个构造函数的属性 这样容易跟踪堆栈调用③
- handle方法的参数是一个函数 而这个函数会将外部构造函数的show作为其参数使用 这时作为参数使用的show的词法作用域就被固定成了初始构造函数的作用域 不管这个handle如何调用 比如在⑤这个位置 通过handle对数组进行push操作 handle的作用域是外部构造函数 所以push的数组也就是外部的callbacks 所以可以看到随后的function(show){show()}函数显示为
show函数的作用域 第 1 个构造函数 [ 1 ]
- 而紧跟后面的show() 却显示为
show函数的作用域 第 2 个构造函数 []
因为在内部返回的构造函数的参数 传入了show函数 而这个show函数的作用域是内部的构造函数作用域
- 再看下面的代码 直接console.log(callbacks) 并没有显示内部构造函数的私有变量(数组) 而是显示了外部构造函数的callbacks 这是作用域的概念 只不过套上了构造函数这么个东西
i = 1; function A(fn){ var callbacks = [], aa = i; A.ii = i++; this.then = function(){ return new A(function(show){ handle(1,function(show){ show();}); show(); // console.log(show); console.log(callbacks); }) } function handle(sth,fn){ callbacks.push(sth); console.log('handle函数的作用域 第',aa,'个构造函数'); fn.call(null, show); } function show(){ console.log('show函数的作用域 第',aa,'个构造函数'); console.log(callbacks); } fn(show); } a = new A(function(){}); a.then();
①②③④⑤⑥⑦⑧⑨⑩