大神求解答JavaScript函数实例的问题
天蓬老师
天蓬老师 2017-04-10 16:24:35
[JavaScript讨论组]

为什么第一个图里的函数实例f1===f2就是假的。。第二个图里的函数实例f3===f4就是真的呢?还有什么是JS的函数实例呢?请大神指导一下小白

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(6)
迷茫

1)每次aFunc()执行后返回一个函数对象都是不同的,所以f1和f2不相同
2)第二个片段aFunc_3指向一个立即执行函数执行后返回的函数,这个函数处在一个闭包环境中,每次执行总是返回闭包中的MyFunc函数,所以f3和f4是相同的
3)JS中定义的任何一个函数-无论通过声明语法声明的还是通过函数表达式声明的-都是函数对象的实例,函数也是有原型的-Function

天蓬老师

你仔细观察一下,第一个例子返回的是函数声明。也就是说,声明了2个同名函数,他们在堆内存中是不一样的。

第二个例子

因为aFunc_3有个函数自执行的括号,因此最后的结果是

var myFunc = function() {}
aFunc_3 = function() {
    return myFunc;
}

于是f3 === f4就很好理解了。他们指向了同一个函数。

巴扎黑

看了一楼的答案之后百度了下,涨姿势了。。。
现在我的理解,大概是这样的:

图1和图2的区别,主要就是关于JS的函数闭包和内存回收的问题。
图1类似于:

var f1 = function(){
    var f2 = function(){

    };
    return f2;
};

或者考虑的更极端一点,这样:

f1 = function(){
    f2 = function(){

    };
    return f2;
};

无论如何,每次执行f1函数,f2必然都会被重新赋值为一个新的函数,于是函数的返回值不相等。

图2是这样的:

var f1 = function(){
    var f2 = function(){

    };
    return function(){
        return f2;
    }
}();

更直观的理解就是:

var f1 = function(){
    return f2;
}

注意,每次执行f1函数,只执行这一句return f2;所以f2不是每次都变成新的函数。
另外,因为f1的返回值持有了f2的引用,所以f2一直在内存里,不会被销毁。
于是,函数的返回值都是f2。

ringa_lee

你的第一个不相等是因为,你每执行一次函数,就返回了一个新的函数(也就是说内存上位置不同),所以肯定是不相等的,第二个相等是因为,这是一个自执行的函数,你的aFun3,也就是下面的这个函数

return function () {
    return MyFunc;
}

所以你在执行aFun3返回的是同一个函数,也就是MyFun
简单的可以将上面的两种情况等价为以下的两种情况:
第一个:

    var f1 = function () {},
        f2 = function () {},
        a = f1,
        b = f2;
    console.log(a === b);  // 必然是false啊

第二个:

    var f1 = function () {},
        a = f1,
        b = f1;
    console.log(a === b);  // true,a和b是指向同一函数
黄舟

何必解释得那样图文并茂,反而让人看不懂

“js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量一起保存起来,构建一个闭包,这些变量将不会被内存回收器所回收。”

阿神

要搞清楚这个问题,涉及到几个概念
作用域
对象的比较方式
闭包

第一张图
每次调用,都会在外层函数的作用域中,重新定义内层函数并命名为MyFunc,然后return出来。所以,考虑到function也是个对象,代码简化为

function aFunc {
  var MyFunc = {}
  return MyFunc
}

又因为对象的===实际是比的内存地址

{} === {} // false,因为两边并不是同一个{}

第二张图
同理简化为下面的形式

var a = (function {
  var my = function (){}
  return function () {
    return my
  }
})()

立即执行函数表达式(Immediately Invoke Function Expression)返回一个获取闭包内变量的函数
此时,不妨再简化一下,所有作用域往上提一层,把my放在global,整个global可以看作一个大的“闭包”,a具有访问这个global“闭包”(作用域)内变量的能力

var my = function () {}
var a = function () {return my}

显然,无论调用多少次a,返回的都是同一个my

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号