理解 JavaScript 里的函数( 上 )

216 阅读2分钟

函数与闭包

函数的返回值由什么确定?

  • 影响因素
  1. 调用时输入的参数 params
  2. 定义时的环境 env
    • 下面是两个例子:
let x = 'x'
let a = '1'
function f1(x){
    console.log( x + a )
};
a = '3' 
{
	let
	a = '2'
	f1('x') // "x3"
}
a = '4'

// 第二个例子
let x = 'x'
let a = '1'
function f1(fn){
  fn()
};
a = '3'
{
	let a = '2'
	function f2(){
      console.log(x + a) //此时 a 为 2 , x 是顶部的”x“
    }
    f1(f2) //"x2"
}

闭包

如果在函数里面可以访问外面的变量,那么「这个函数」 +「这些变量 」 = 闭包

常见考题

  • 请问下面打印出什么?
for(var i = 0;i < 6; i++){
    setTimeout(()=>{
        console.log(i)
    })
}
// 666666
  • 如何解决
  1. 把 var 换成 let
for( let i = 0; i<6; i++){
    setTimeout(
        ()=>console.log(i) // i
    )
}
// 0 1 2 3 4 5
  1. 使用立即执行函数
for( var i = 0; i < 6; i++){
    !function(j){
        setTimeout(
            ()=>console.log(j)
        )
    }(i)
}
// 0 1 2 3 4 5

闭包结论

  • 特点
  1. 能让一个函数维持住一个变量
  2. 但不能维持这个变量的值
  3. 尤其变量的值会变化的时候

函数与 this

this 是参数还是环境?

  • 答: this 是参数,是在函数调用的时候传入的参数

this 的确定

确定方法

  • 显示 this
  1. fn.call(asThis, 1, 2)
  2. fn.bind(asThis, 1, 2)()
  3. fn.apply(asThis, [1,2])
  • 隐式 this
    1. fn(1,2) // fn.call(undefined,1,2)
    2. obj.method("ddd") // obj.method.call(obj, "hi")
    3. array[0]("hi") // array[0].call(array,"hi")

测试题

button.onclick = function(){	
	console.log(this) 
	// 一般是button 但是具体要看调用时的传递的参数
	//button.onclick.call("this")
}

const vm = new Vue({
	data:{
		message: "hi"
	},
	methods:{
		sayHi(){
			console.log(this.message)
			// 一般在vue 中是 "hi"
			//如果直接调用 vm.sayHi.call("this")
		}
	}
})

面试题

let length = 10;  

function fn(){	 
	console.log(this.length)
}

let  obj = {
	lenght:5,
	method(fn){
		fn()
		arguments[0]()		
    }
}
obj.method( fn, 1) // 不确定的值  2 (实参的个数)

解析:进行改写后即为 obj.method.call(obj, fn , 1)

fn() 是定义在全局中的,所以调用时 this 指向 window 。

let 定义的变量不挂载到 window 上, 那么 window.lenght 返回在当前窗口中frames的数量(包括IFRAMES)。所以第一个打印出的是不确定的。

第二个 arguments[0]() 改写后即为 arguments[0].call(arguments)

所以 this 即为 arguments (实际参数)

this.length === arguments.length //2

this 规则

    1. this 是 call 的第一个参数
    1. new 重新设计了 this
    1. 箭头函数不接受 this

函数总结

  • 函数的返回值由参数和环境确定
  • this 是参数,arguments 也是参数
  • 全局变量和自由变量是环境