函数表达式

理解函数提升的关键,就是理解函数声明与函数表达式之间的区别。

arguments.callee是一个指向正在执行的函数的指针

函数对象属性:caller;这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,它的值为null。

function outer(){
    inner()
}
function inner(){
    console.log(arguments.callee.caller)
}
outer()

示例闭包函数

function createCompareFunction(propertyName){
    return function(obj1,obj2){
        let val1 = obj1[propertyName],val2 = obj2[propertyName];
        if(val1 < val2){
            return -1
        }else if(val1 > val2){
            return 1
        }else{
            return 0
        }
    }
}  

解析:在一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的作用域链中。因此,在createCompareFunction函数内部定义的匿名函数的作用域链中,实际上将会包含外部函数createCompareFunction的活动对象。在匿名函数从createCompareFunction中被返回后,它的作用域链被初始化为包含createCompareFunction函数的活动对象和全局变量对象。这样匿名函数就可以访问在createCompareFunction中定义的所有变量。createCompareFunction函数执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。换句话说,当createCompareFunction函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中,直到匿名函数被销毁后,createCompareFunction的活动对象才会被销毁。

注:所以使用闭包不及时释放内存,会造成内存泄漏。像V8等优化后的JavaScript引擎会尝试回收被闭包占用的内存。

MST

var obj = {
    name:'zjy',
    getName(){
        return ()=>{
            return this.name
        }
    }
}

var name = 'lyn'
var obj = {
    name:'zjy',
    getName(){
        return function(){
            return this.name
        }
    }
}

var name = 'lyn'
var obj = {
    name:'zjy',
    getName(){
        var that = this
        return function(){
            return that.name
        }
    }
}

  

原文地址:https://www.cnblogs.com/zhenjianyu/p/13477450.html