zoukankan      html  css  js  c++  java
  • 函数的作用域链在定义时已经确定!!

    最近看到一个面试题如下:

    var x=10;
    function fn() {
        console.log(x);
    }
    
    function show(f) {
        var x=20;
    
        (function() {
            f();
        })();
    }
    show(fn); //10

    最后的输出结果是10而不是20,是不是很差异,不是有作用域链吗,不是内部函数有权访问外部函数的变量吗,世界怎么了,之前的理论都崩塌了吗??囧。。。

    其实不是的,之前的理论没错,只是自己的理解有问题。函数执行时确实是沿着作用域链查找变量的,问题是什么是作用域链?红宝书上的解释:其实作用域链在函数定义时已经确定了,作用域链是和函数定义时的位置相关的。在函数创建的时候创建一个包含外部对象(包括全局对象和所有包含自己的对象)的作用域链,储存在内部[[scope]]属性中。函数执行的时候会创建一个执行环境,通过复制[[scope]]属性中的对象,构建执行环境的作用域链,并把自己的活动对象推向当前作用域链的前端以此形成完整的作用域链。[[scope]]属性中保存的是对可访问变量对象的引用,而不是值的复制。

    所以作用域链是和函数创建时的位置相关的:

    var x=10;
    function fn(){
        console.log(x);
    }
    function show() {
        var x=20;
        fn();
    }
    show();  //输出10
    -----------------------
    var x=10;
    function show() {
        var x=20;
        function fn(){// 这里定义的fn函数,定义时的作用域链已经确定保存在[[Scope]]属性中,包括show函数中的变量对象和全局变量对象
            console.log(x);
        }
        fn();
    }
    show();  //输出20
  • 相关阅读:
    jquery 获取 input type radio checked的元素
    各种js验证规则
    centos7 vsftp xftp 解决无法显示远程文件夹,可登陆
    js浮点运算精度丢失的解决办法
    ThinkPHP 改装后的分页类
    亚马逊AWS开启之路
    上慕课从这里开始 (www-mooc.com)
    iptables httpd.conf详解
    微信带链接的文本消息推送
    IE8不支持响应式设计解决方法
  • 原文地址:https://www.cnblogs.com/changzz/p/10153161.html
Copyright © 2011-2022 走看看