第一个例子中 :之所以每个函数都返回不同的值的原因 有2点 (简写如下文)

就是[SCOPE]内部属性,函数可能拥有相同的父作用域时,多个函数引用同一个[SCOPE]属性,所以return i的值还是10(第一点),但是return num的值就不是了。因为每个内部函数的父执行环境都是新的(因为每次I++之后函数都会被调用执行每次进入的环境是新的)。所以多个函数不引用同一个[scope]属性,创建函数时[scope]中的作用域链中的所有父执行环境的A0/VO都是一个新的。当然全局父执行环境不是。因为它只被进入一次。(第二点)

function createFunctions(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(num){//创建函数时创建包含所有父执行环境的V0/AO对象指针作用域链,此链被保存在创建的函数的内部属性[[Scope]]中,第一次进入函数的执行环境,活动对象里的num属性值为0;第二次进入函数的执行环境,每次进入的函数的执行环境都是一个新的执行环境。很明显两次的执行环境是不同的。所以,此时活动里的num属性值为1; return function(){//创建函数时创建包含所有父执行环境的V0/AO对象指针作用域链,此链被保存在创建的函数的内部属性[[Scope]]中,此时的num为0;当进入 result[0]()函数的执行环境时他的作用域链的第二个活动对象指针是父函数执行环境的活动对象 值为0;当进入 result[1]()第二次进入函数的新执行环境时,作用域链的第二个活动对象指针是父函数执行环境的活动对象,注意:此时的父函数的执行环境是一个新的执行环境,所以它的作用域链的第二个活动对象指针指向新的父函数执行环境的活动对象;还有一点当return函数退出时,父执行环境被销毁,但是活动对象依然保存在内存中(因为内部闭包匿名被引用中。);每个被保存到result数组里面的函数的执行环境的作用域链的第二个活动对象指针引用的都是一个新的父执行环境的活动对象;所以num值为1;这里之所以每个函数都返回不同的值的原因 有2点。一点是我之前说的一大堆,第二点就是[SCOPE]内部属性,函数可能拥有相同的父作用域时,多个函数引用同一个[SCOPE]属性,所以return i的值还是10,但是return num的值就不是了。因为每个内部函数的父执行环境都是新的。所以多个函数不引用同一个[scope]属性 ,创建函数时[scope]中的作用域链中的所有父执行环境的A0/VO都是一个新的。当然全局父执行环境不是。因为它只被进入一次。 return num;
};
}(i);//当循环体执行完毕后。result[i]里面的每个函数对象都是不相等的。
}
return result;
} 此例子的原因还是因为父执行环境相同不相同的问题。
function createFunctions(){ //
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){// 创建函数时创建包含所有父执行环境的V0/AO对象指针作用域链,此链被保存在创建的函数的内部属性[[Scope]]中,
return i;
};
}
return result;//result[i]里面的每个函数对象都是不相等的。当循环体结束后createFunctions函数的执行环境的活动对象的属性i=10;父函数执行环境只被进入一次。 result[i]()每次进入函数执行环境都是一个新的执行环境。所有函数的执行环境的作用域链中的所有父执行环境的VO/AO对象指针是复制创建函数时的[Scope]属性中作用域链.循环语句中的多个函数可能拥有相同的父作用域时,多个函数引用同一个[SCOPE]属性,并且此属性中的作用域链的A0/VO是唯一的。因为父执行环境createFunctions只被进入一次,所以它的活动对象是唯一的.这就是为什么每个函数都返回10的原因; } function Person(name){
this.getName = function(){
return name;
};
this.setName = function (value) {
name = value;
};
}
var person = new Person("Nicholas");
alert(person.getName()); //"Nicholas"
person.setName("Greg");
alert(person.getName()); //"Greg"
var persoe = new Person("icholas");
alert(persoe.getName());//这里弹出icholas是因为new的时候进入了新的函数的执行环境。而不是之前保存的执行环境 也就是说persoe.getName和person.getName的父执行环境不同。2个对象是不同的内存空间所以函数有2份。
alert(person.getName()); //"Greg" / /这里之所以会弹出greg是因为进行执行环境时,他的scope属性保存的作用域中的父执行环境中的VO对象指针是之前创建函数时的scope中的作用域链中的VO对象指针指向父执行环境中的VO对象。
说简单点就是2个对象的方法的执行环境的作用域链中的第二个活动对象指针指向的是不同的父执行环境的活动对象。 总结:如果想要让所有子执行环境引用同一个scpeo属性,只需要让父执行环境进入一次即可,这样子执行环境就拥有相同的父执行环境了。此环境的的vo/AO是唯一的。既然是唯一的,那么对此变VO/AO的属性做的想修改会反应到所有子执行环境。 如果想要让所有子执行环境引用不同的scpeo属性,只需要让父执行环境进入多次即可,这样子执行环境就不拥有相同的父执行环境了。不同的父执行环境的的vo/AO是不一样的。;既然是不一样的的,那么对此VO/AO的属性做的修改自然就反应到 和不同的执行环境相对应的子执行环境了。 还有一点就是:当父执行环境退出时,如果内部函数执行环境一直被引用状态,那么当再次进入此函数的执行环境时它的作用域链引用的是同一个SCOPE的地址,父执行环境的活动对象不会被销毁。还在内存中。 此链一直包含父执行环境的活动对象。

js执行环境的深入理解的更多相关文章

  1. js执行环境、作用域

    js执行环境.作用域 执行环境:是javascript中的一个重要的概念,<javascript高级程序设计第三版>的定义是:执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行 ...

  2. 【repost】 原生JS执行环境与作用域深入理解

    首先,我们要知道执行环境和作用域是两个完全不同的概念. 函数的每次调用都有与之紧密相关的作用域和执行环境.从根本上来说,作用域是基于函数的,而执行环境是基于对象的(例如:全局执行环境即window对象 ...

  3. JS 执行环境与作用域链

    1.执行环境 JavaScript 代码都是在执行环境中被执行的.执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域.生命周期等方面的处理,它定义了变量或函数是否有权访问其他数据 ...

  4. js执行环境相关

    Js执行过程 如果一个文档中存在多个代码段 步骤一:读入第一个代码段(js引擎并非一行一行执行,而是一段一段分析执行) 步骤二:做词法分析和语法分析,有错则报语法错误(比如括号不匹配等),并跳转到步骤 ...

  5. JS执行环境,作用域链及非块状作用域

    JS中的执行环境,顾名思义就是变量或函数所执行时的环境.在我的理解中,执行环境和作用域相差不大. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而在函数执行之后 ...

  6. 浅谈JS执行环境及作用域

     今天刚刚开通博客,也是第一次写博文,略感紧张.作为一个表达能力弱弱的人来说,自己花三分钟理解一个知识点,当别人问起时,也许需要30分钟才只是让别人知道自己在说什么,一点也不夸张,希望在博客上可以练习 ...

  7. js执行环境深入研究

    js 声明函数是创建函数对象的过程,当创建函数对象时,函数对象的[[scope]] =连当前执行环境对象的作用域(栈顶执行环境--当执行函数时,js会将该函数的执行环境对象入栈) 当为全局函数时,如: ...

  8. js执行环境的周边概念

    一.熟悉几个名词: 1.执行环境(execution context),也叫执行上下文,每个函数都会有自己的执行环境:当浏览器首次加载脚本时,他将默认进入全局执行环境:如果接下来要调用一个内部函数,则 ...

  9. JS执行环境栈及事件循环机制—简洁明了的讲解

    JavaScript解释器在浏览器中是单线程的,这意味着浏览器在同一时间内只执行一个事件,对于其他的事件我们把它们排队在一个称为 执行栈(调用栈) 的地方.下表是一个单线程栈的抽象视图: 我们已经知道 ...

随机推荐

  1. MongoDB使用小结:一些常用操作分享

    本文整理了一年多以来我常用的MongoDB操作,涉及mongo-shell.pymongo,既有运维层面也有应用层面,内容有浅有深,这也就是我从零到熟练的历程. MongoDB的使用之前也分享过一篇, ...

  2. *HDU1455 DFS剪枝

    Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  3. jQueryMobile 网页在UC等游览器上无法正常显示或者是无法自适应设备大小,但在QQ游览器上能正常显示的解决方法

    造成jQueryMobile网页在QQ游览器上能正常显示,在UC等游览器上无法正常显示或者是无法自适应设备大小的解决方法: 在<head>标签间添加<meta name=" ...

  4. Android课程---如何用网格视图做出手机桌面APP

    activity_test.xml <?xml version="1.0" encoding="utf-8"?> <GridView xmln ...

  5. 安卓中級教程(4):ScrollView與ListView之間的高度問題

    在scrollView中加插ListView是一個大難題.其中一個難題是Listview的高度難以計算,輸出效果往往強差人意,就讓我們看看當中的問題 . <LinearLayout xmlns: ...

  6. PHP 接入芝麻信用 注意 事项

    芝麻官方下载的SDK,跑不起来,百度搜索一番也没有发现太多的文章 ,只有一个CSDN博客写的一篇文章,比较有参考价值 详细查阅文档+几天测试整理以下几点注意事项: 接入芝麻API接口,应该分2步: 第 ...

  7. 掌握Thinkphp3.2.0----标签库

    1.什么是内置标签?什么是标签扩展库? Cx.class.php 和 Html.class.php 2.怎么加载非内置标签,怎么使用? 两种方式加载 3.怎么扩展自定义的标签? 仿照Html.clas ...

  8. angular前端开发环境

    1.代码编辑工具 webstorm 2.断点调试工具 chrome插件Batarang 3.版本管理工具 git(仅仅是命令行工具) git小乌龟--tortoisegit(图形化工具) 首先在git ...

  9. python2.7安装PIL.Image模块

    这是大家常用的两种安装方法 sudo pip install PIL pip install PIL --allow-external PIL --allow-unverified PIL 如果安装成 ...

  10. 1.Maven的安装以及本地仓库的配置

    安装: maven下载地址:http://maven.apache.org/release-notes-all.html 然后解压,配置环境变量   MAVEN_HOME,并添加到path中.验证是否 ...