• 在iframe里调用parent.func()引出的js函数运行在它们被定义的作用域里,而不是它们被执行的作用域里


    有个document里定义了一个函数func(),同时在document里嵌入了一个iframe,在这个iframe里调用父窗口的方法:parent.func(),本来我以为这个函数的运行环境是在这个iframe自己里面,测试发现虽然是在iframe里面调用的这个函数,但是运行环境依然是在父窗口里。

    所以也验证了JS权威指南中的:js函数运行在它们被定义的作用域里,而不是它们被执行的作用域里。

    又比如

    var a=1;
    function f1(){console.log(a);};
    function f2(i){var a=2;f1();}
    f2();//----1

    当代码运行到调用某个函数时,作用域会切换到这个函数自身的作用域里,当这个函数调用完毕会再切换会原来的作用域,这两个作用域链是独立的,一个函数的作用域链由它被定义在哪决定。也正是因为函数运行在它们被定义的作用域里,才导致闭包可用。

    本质解释:

    ECMA-262标准:

    在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性。

    在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参和局部变量,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中。

    比如上例中的f1和f2被定义时,[[scope]]里都只有window对象这一级作用域,

    调用f2()时,创建了一个活动对象,这个活动对象包括i和a两个属性,此时f2的[[scope]]包括活动对象和之前的window对象两级作用域;

    调用f1()时创建的活动对象是空的。

    所以当运行f2()时,能访问到的变量是:{i:undefined,a:2}---->window对象{a:1,f1:...,f2:..., ......},

    在f2()里面运行f1()能访问到的变量是:window对象{a:1,f1:...,f2:..., ......},

    所以此时访问到的a是属于window对象的,而无法访问到f2作用域链里的局部变量a。

  • 相关阅读:
    怎样修改原型对象prototype
    怎样获取构造函数的名字
    怎样把实例对象当构造函数用
    怎样理解prototype对象的constructor属性
    怎样理解构造函数的原型对象prototype
    怎样给回调函数绑定this
    怎样绑定this
    怎样理解数组的空元素empty与undefined的区别
    怎样找出数组中的最大数值
    怎样调用对象的原生方法
  • 原文地址:https://www.cnblogs.com/yigeqi/p/4689420.html
Copyright © 2020-2023  润新知