函数自调用:函数自己调用自己,具体由例题阐述。//一般都是在else中自调用,if里边写输出结果
arguments.length 实参数量
arguments.callee 运行的函数对象(匿名函数自调用时可以使用)
预编译(隐式操作)
1.时间范围:函数调用了以后 在运行代码之前
2.函数每次调用都会生成一个AO对象:执行期上下文对象
3.给AO对象添加成员:函数内部的局部变量和形参变量 名 作为AO对象的属性名
//全局作用域运行代码时 也有预编译==>全局预编译 (没有实参赋值)
//生成一个对象Global Object (GO) ==> GO:{}
//全局预编译还有一步 ==> 不同的环境中运行js代码不一样
// GO对象的成员全部浅拷贝给环境对象window
// node.js 环境中没有这一步
// 拓展知识:关于访问成员 console.log(a) 访问的是GO对象的成员(作用域链中没有就报错)
// console.log(window.a)不报错 原型链没有返回unfined
例如 AO:{a:undefined}//形参和局部变量一样的时候 不影响
4.把传入的实参赋值给AO对象的属性
例如 AO:{a:100}
5.局部函数声明,赋值 把局部函数的名字让AO对象也有一个一样的成员名,把函数体赋值给这个属性
例如 AO:{a:100,fn:function fn () {}}
预编译完成之后再运行代码: 预编译过的就不在运行
案例1:函数的自调用
var arr=[[1,2,3,4,[2,3,4,5],[2,3,4,5],[4,54,2,6]],[2,3,4,4,5,6]]
//假设你只知道数组内部全是(数字和数组的混套),不知道嵌套了几层
//打印出所有数字
function fn(arr){
// 遍历数组
for(var i=0;i<arr.length;i++){
if(typeof(arr[i])=="number"){
console.log(arr[i])
}else{
// for(var j=0;j< arr[i].length;j++){
// if(typeof(arr[i][j])=="number") console.log(arr[i])
// else{
// //arr[i][j].length 因为不知道嵌套了几层
//也就不知道该写几次for循环
// }
// }
fn(arr[i])
}
}
}
fn(arr)
案例2:
function fn (n) {
if(n<2){
return 0
}
else{
n+fn(n*0.5+1)
}
}
var re=fn(100)
需求: 100+51+(51/2+1)+..a(不能小于2)
案例3:匿名函数的自调用
(function(n){
if(n<=1){console.log(1)}
else{console.log(n);arguments.callee(n-1) }
})(10)
10 9 8 7 ... 1