有个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。

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

  1. iframe里面的页面调用父窗口,左右窗口js函数的方法

      iframe里面的页面调用父窗口,左右窗口js函数的方法 实现iframe内部页面直接调用该iframe所属父窗口自定义函数的方法. 比如有A窗口,A内有个IFRAME B,B里面的装载的是C页面 ...

  2. C语言学习_C如何在一个文件里调用另一个源文件中的函数

    问题 C如何在一个文件里调用另一个源文件中的函数,如题. 解决办法 当程序大了代码多了之后,想模块化开发,不同文件中存一点,是很好的解决办法,那我们如何做才能让各个文件中的代码协同工作呢?我们知道,m ...

  3. 外层页面与iframe相互调用的方法

    iframe调用外层页面的方法: parent.func(); 外层页面调用里面的iframe中的内容方法:  $("iframe").contents().find(" ...

  4. 解决同一页面中两个iframe互相调用jquery,js函数

    这一个月又没更新博客,唉,懒癌又犯了,今天解决了一个问题,关于两个iframe互相调用jquery函数方法 a.html中有两个iframe,如下: <iframe width="10 ...

  5. 父窗口与iFrame之间调用方法和元素

    父窗口与iFrame之间调用方法和元素 父窗口调用子窗口: 调用元素 js格式: var obj=document.getElementById("iframe的name").co ...

  6. Entity Framework 6 Recipes 2nd Edition(11-4)译 -> 在”模型定义”函数里调用另一个”模型定义”函数

    11-4.在”模型定义”函数里调用另一个”模型定义”函数 问题 想要用一个”模型定义”函数去实现另一个”模型定义”函数 解决方案 假设我们已有一个公司合伙人关系连同它们的结构模型,如Figure 11 ...

  7. 在ORACLE触发器里调用JAVA程序

    因为项目需要,有一个已经写好的Java程序,想要在Oracle某个表的触发器中调用,以使得每次数据更新时,调用这个JAVA程序,来修改后台某个数据. 现将过程记录如下: 1.编写JAVA程序 publ ...

  8. 在 C++Builder 工程里调用 DLL 函数

    调用 Visual C++ DLL 给 C++Builder 程序员提出了一些独特的挑战.在我们试图解决 Visual C++ 生成的 DLL 之前,回顾一下如何调用一个 C++Builder 创建的 ...

  9. Ruby操作VBA的注意事项和技巧(2):宏里调用和控制窗体以及窗体上的控件、不同workbook之间的宏互相调用

    4.宏里调用并控制窗体以及窗体上的各种控件 1 Sub Criterion_Check() 2 If Workbooks.count = 0 Then '如果当前没有打开的工作薄的话需要发出警告 3 ...

随机推荐

  1. 线段树(区间修改、区间查询) HDU 1754 I Hate It

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  2. 【单调栈】Vijos P1926 紫色的手链

    题目链接: https://vijos.org/p/1926 题目大意: 给n个数(n<=100 000),求任意区间的最大值异或次大值的最大值. 题目思路: [模拟][单调栈] 我们维护一个严 ...

  3. Evaluate Reverse Polish Notation——LeetCode

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  4. ArrayList 、Vector、 LinkList

    public class TestList {     public static void init(List list)     {         if(list!=null)          ...

  5. 在javaweb中通过servlet类和普通类读取资源文件

    javaweb有两种方式读取资源文件 在Servlet中读取,可以使用servletContext,servletContext可以拿到web所有的资源文件,然后随便读,但是这种方法不常用,尽量少在S ...

  6. Oracle Locks之DML锁

    Oracle通过锁来实现数据库的并发控制 Oracle Database automatically locks a resource on behalf of a transaction to pr ...

  7. Ken Norton和软件工程师打交道的10个秘诀

    How to work with software engineers - by Ken Norton Deflect praise Absorb blame Sweat the details In ...

  8. ubuntu下安装svn

    Ubuntu下使用SVN SVN作为日常开发中不可缺少的工具,今天终于开始在Ubuntu下使用了. 1.首先需要安装SVN.Ubuntu下的SVN安装十分简单,sudo apt-get install ...

  9. android编程中setLayoutParams方法设置

    第一篇 private LinearLayout generateHeadOfControl() { LinearLayout LayoutHead = createLayout(LinearLayo ...

  10. 常用颜色大全---RGB值及中英文名称

    ■■■■■ #DC143C Crimson 深红/猩红 ■■■■■ #FFF0F5 LavenderBlush 淡紫红 ■■■■■ #DB7093 PaleVioletRed 弱紫罗兰红 ■■■■■ ...