函数与闭包
函数的返回值由什么确定?
- 影响因素
- 调用时输入的参数 params
- 定义时的环境 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
- 如何解决
- 把 var 换成 let
for( let i = 0; i<6; i++){
setTimeout(
()=>console.log(i) // i
)
}
// 0 1 2 3 4 5
- 使用立即执行函数
for( var i = 0; i < 6; i++){
!function(j){
setTimeout(
()=>console.log(j)
)
}(i)
}
// 0 1 2 3 4 5
闭包结论
- 特点
- 能让一个函数维持住一个变量
- 但不能维持这个变量的值
- 尤其变量的值会变化的时候
函数与 this
this 是参数还是环境?
- 答: this 是参数,是在函数调用的时候传入的参数
this 的确定
确定方法
- 显示 this
- fn.call(asThis, 1, 2)
- fn.bind(asThis, 1, 2)()
- fn.apply(asThis, [1,2])
- 隐式 this
fn(1,2)// fn.call(undefined,1,2)obj.method("ddd")// obj.method.call(obj, "hi")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 规则
-
- this 是 call 的第一个参数
-
- new 重新设计了 this
-
- 箭头函数不接受 this
函数总结
- 函数的返回值由参数和环境确定
- this 是参数,arguments 也是参数
- 全局变量和自由变量是环境