js函数知识点

函数知识点

  • callee&caller 在严格模式下都无法被使用
  • callee

arguments.callee 指的是函数自己的引用

 function test(){
	console.log(arguments.callee)
}
test()
/* 打印出自己
ƒ test(){
	console.log(arguments.callee)
}
*/
   function test(){
      console.log(arguments.callee);
      function fun(){
        console.log(arguments.callee);
      }
      fun()
    }
    test()
/*
	f test(){
		f fun(){}
		fun()
	}
------------------------------
	f fun(){}
打印出来的都是自己
*/

在使用匿名函数递归的时候可以用得到

// 求10的阶乘
var num =(function (n){
	if(n===1){
		return 1
	}
	return n * arguments.callee(n-1)
}(10))
  • caller

返回一个对函数的引用,该函数调用了当前函数
就是说在哪个环境里被调用

   function fun(){
      console.log(fun.caller)
    }
    function test(){
    fun()
    }
    test()
    /*
	f test(){....}
	*/
  • 函数的作用域以及预编译

函数在执行之前都有一个预编译过程
预编译环节1 变量声明,2 函数声明 ,最后才开始执行

	fun ()
    function fun(){
      console.log("函数执行")
    }
    // 函数执行

变量声明也会提前

funciton fun(a){
	cosnole.log(a)
}

函数执行都会有作用域的产生
先声明变量形参和变量声明
形参实参统一
函数声明的属性名变成GO属性名值为undefined
将函数声明赋值

 // 最外层的作用域是GO也就是window,当有函数执行,函数会生成AO
  fun (a)
    function fun(a){
      console.log(a)
    }
    var a = "声明提前,赋值在后"  
    var a   // 变量声明优先被执行,函数体执行时这天已经被执行过
    fun(a)
/*
undefined
"声明在前,赋值在后"
*/
  • AO和GO

[[scope]]:每个js函数都是一个对象,对象中有些属性我们可以访问,有些不可以,这些属性仅供js引擎存取,[[scope]]就是一个,[[scope]]就是我们所有的作用域,里面储存了执行期上下文的集合
作用域链:[[scope]]中所储存的执行期上下文对象的集合,这个集合呈链式链接

GO指的是全局作用域 也就是window的作用域
AO 执行期上下文 指的是函数作用域
scope是个类数组,最先指向ao,最后指向go
当一个函数执行的时候会产生自己的scope,0指向AO,1指向系统GO
每有一个函数执行,都会在window的scope上生成一个AO ,以此类推,最后的是GO
当在函数里又有一个函数执行了,那么会在原来的AO的基础上,增加新AO

   function a() {
      function b(){
        var  num=100
      }
      b()
    }
  a()
  /*
  a 执行:a的AO  scope[0] AO ,scope[1] GO
  b 执行: a的AO  scope[0] AO , scope[1] GO
		b的AO scope[0] AO(b) ,scope[1] AO (a) , scope[2] GO
	b的scope[1]==a的scope[0] 指向相同
  */

正是因为作用域的特性,内部函数可以使用并且修改外部函数的值,如果外部函数需要用到内部函数的值,那么需要 闭包

  • 闭包

根据上面所述,通常外部函数拿不到内部函数的数据,因为访问不到内部函数的AO
只有把内部函数的数据返回出去,才可以拿得到,此时也就形成了闭包
换句话说,只要函数内部的值被外部使用,那么一定形成闭包

function a (){
       var b=30
       return b 
    }

    var c = a()
    console.log(c)
    // 30 

闭包可以嵌套

	// 连续闭包
function a() {
      function b(){
        var  num=100
        return num
      }
      return b()
    }
    var num2= a()
    // num2: 100

不仅仅是return 只要变量被外部使用,都能形成闭包

	var b=0
    function a (){
       b = "外部变量接收"
    }
    a()
    console.log(b)  // 外部变量接收

你可能感兴趣的:(爬坑记,js,js,函数)