js
let arr = [12, 23, 34, 45];
(function(arr) {
arr.pop()
arr = arr.slice()
arr.shift()
console.log(arr)
})(arr)
console.log(arr)
解析:首先将arr作为参数传给了自执行函数,函数执行。首先使用pop方法进行去尾操作,所以最外层arr变成了[12,23,34]。其次使用了赋值操作,调用了slice方法。slice方法的特性是深拷贝一个数组,所以从这个时候开始arr与之前的arr就没有了联系。接着执行shift方法,对刚刚赋值的arr进行去头操作,但是不会影响最外层的arr,最后打印的时候根据作用域链的关系,会先找到函数内部的arr,所以为[23,34],在最外层则打印了只执行了pop方法的[12,23,34]
let i = 0
let fn = function(n) {
i += 2
return function(m) {
i += (++n) + (m --)
console.log(i)
}
}
let f = fn(2)
f(3)
fn(2)(3)
f(4)
console.log(i)
解析:首先let f = fn(2),执行fn,i在下一次执行的时候就为2,返回了一个函数给f,i变成2;执行f(3)这个函数,就是执行fn的返回值,此时i已经等于2,执行i += (++n) + (m --)操作后,f(3)没有n,向上寻找,在fn找到参数n,n=2,所以计算为i=2+3+3=8。然后执行fn(2)(3) ,分成两步像之前两步一样执行,记住i已经变成了8,所以执行结果为18。最后执行f(4),f(4)为f(3)相同函数,所以执行环境与f(3)相同,记住此时i已经等于16。因为执行f(3)的时候进行了++n操作,所以环境里的n已经变成3,再执行f(4)的时候为i=16+4+4=26
var n= 0
var fn = function(n) {
this.n *= 2
n ++
return function(m) {
n += ++m
console.log(n)
}
}
var f = fn(2)
f(3) //7
fn(3)(4) //9
f(4) //12
console.log(n) //0
流程大部分同第二题,因此不做解答。
网友评论