闭包与函数作用域、函数的原型链

113 阅读1分钟

闭包与call

首先需要明确的几个知识点

1.函数的scope在函数定义时已经确定

2.作用域链在函数定义时已经确定

3.函数this指向的改变,不会影响作用域(不知道理解对不对)

function fn(){
    var a = 1;
    return function foo() {
        console.log(a)//函数的作用域在函数定义的时候确定,作用域链是不会改变的,去上层找到a=1
        console.log(this)//this的指向会改变,改变为obj
    }
}
var obj = {
    a:3000
}
fn().call(obj)
// 1
// { a: 3000 }

自执行函数的this

2.IIFE的this指向window

var b = 10;
function foo(){
    console.log(b)//10
}

(function (){
    var b = 20;
    console.log(this.b)//10
    foo()
})()

变量赋值加var和不加var

函数体内加var是局部变量,不加var是全局变量

var b = 10;
function foo(){
    console.log(b)//20
}

(function (){
    b = 20;
    console.log(this.b)//20
    foo()
})()

本题中,因为b=20在函数体内,且没有加var,所以是全局变量,将原来的a=10重新赋值为20;导致结果变为20

之前在哪里看到说IIFE没有变量提升,我觉得说法有错

console.log(b)//报错
(function (){
    console.log(b)//undefined
    var b = 20;
})()

说IIFE没有变量提升不如说是IIFE具有自己隔绝的作用域,在IIFE内仍然会变量提升(见undefined),只是在外部是无法访问内部的变量的,当然,也可以通过传入window,再将b赋值给window,通过这样的方式将内部变量暴露到全局,这也是早期模块化的一种思想。