zoukankan      html  css  js  c++  java
  • 在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。

  • 相关阅读:
    【树】树的前序遍历(非递归)
    表单提交中的input、button、submit的区别
    利用setTimeout来实现setInterval
    Jquery动画操作的stop()函数
    Javascript实现简单的双向绑定
    Javascript观察者模式
    CSS reset
    【CSS3】background-origin和background-clip的区别
    :before和::before的区别
    JS实现瀑布流
  • 原文地址:https://www.cnblogs.com/yigeqi/p/4689420.html
Copyright © 2011-2022 走看看