在javascript中,可执行的JavaScript代码分三种类型:

1. Global Code,即全局的、不在任何函数里面的代码,例如:一个js文件、嵌入在HTML页面中的js代码等。
2. Eval Code,即使用eval()函数动态执行的JS代码。
3. Function Code,即用户自定义函数中的函数体JS代码。
不同类型的JavaScript代码具有不同的执行环境,这里我们不考虑evel code,对应于global code和function code存在2种执行环境:全局执行环境和函数执行环境。

一、执行环境(执行上下文)

执行环境(Execution Context,有时简称“环境”)是javascript中最为重要的一个概念。它定义了变量和函数有权访问的其他数据,决定了它们各自的行为。(每个函数都有自己的执行环境。)

全局执行环境:最外围的一个执行环境,根据ECMAScript实现所在的宿主环境不同而不同,在Web浏览器中,全局执行环境被认为是window对象。

执行环境的销毁:在某个执行环境的所有代码都执行完毕后,环境将被销毁,意味着其中所有变量和函数定义也都随之销毁(全局执行环境直到应用程序退出—例如关闭网页或浏览器—时才会被销毁)。

执行流:每个函数都有自己的执行环境;当执行流进入一个函数时,函数的环境就被推入到一个环境栈的顶部并获得控制权。在函数执行完成,栈会将其环境弹出,(即从栈的顶部弹出)再把控制权返还给之前的执行环境。

作用域 上下文 的区别:

从根本上来说,作用域是基于函数的而上下文是基于对象的。

作用域适用于函数被调用时函数中变量的访问权限

上下文通常是指“this”关键字的值,“this”是拥有当前执行代码的对象的引用

二、变量对象

变量对象:每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数保存在这个对象中。(我们无法访问,但解析器在处理数据时会在后台使用它。)

三、作用域

作用域链:当代码在环境中执行时,会创建变量对象的一个作用链;作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问。

作用域链的前端:始终都是当前执行代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。

延长作用域链:

虽然执行环境只有两种——全局作用域和函数作用域,但是还是可以通过某种方式来延长作用域链。因为有些语句可以在作用域链的顶部增加一个临时的变量对象。

有两种情况会发生这种现象:
1、try-catch语句的catch块;
2、with语句;
关于作用域:
1. 声明变量
使用var关键字声明变量的时候,变量将被自动添加到距离最近的可用环境中(在函数内部,最近的作用域就是函数的局部变量,在with语句中,最近的环境是函数环境),不使用var声明的情况下,变量会被直接添加到全局环境中。
2. 查询标识符
查询的过程,就是一个向上搜索的过程。当执行js代码的过程中,遇到一个标识符,就会根据标识符的名称,在执行上下文(Execution Context)的作用域链中进行搜索。从作用域链的第一个对象(该函数的Activation Object对象)开始,如果没有找到,就搜索作用域链中的下一个对象,如此往复,直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象,也就是全局对象(Global Object)以后也没有找到,则会抛出一个错误,提示undefined。 

四、块级作用域(通常叫做私有作用域)

五、私有变量和特权方法

【私有变量】 在对象内部使用'var'关键字来声明,而且它只能被私有函数和特权方法访问。 
【私有方法】 在对象的构造函数里声明(或者是通过varfunctionName=function(){...}来定义),
它能被特权方法调用(包括对象的构造方法)和私有方法调用,私有函数只能访问私有的方法和属性。 
【特权方法】通过this.methodName=function(){...}来声明而且可能被对象外部的代码调用。
它可以使用:this.特权函数() 方式来调用特权函数,使用 :私有函数()方式来调用私有函数。

【公共属性】 通过this.variableName来定义而且在对象外部是可以读写的。不能被私有函数所调用。 
【公共方法】 通过ClassName.prototype.methodName=function(){...}来定义可以从对象外部来调用。 
【原型属性】 通过ClassName.prototype.propertyName=someValue 来定义。 
【静态属性】 通过ClassName.propertyName=someValue 来定义。
【静态方法】 通过ClassName.funName=function(){...} 来定义。

参考  js--属性和方法(私有/公有)

《高程三 P184-P192 》

私有变量:任何在函数中定义的变量,都可以认为是私有变量(因为不能在函数外面访问这些变量)。
             私有变量包括函数的参数,局部变量和在函数内部定义的其它函数。
私有函数:在函数内部声明的函数称为私有函数。
特权方法:有权访问私有变量和私有函数的公有方法称为特权方法。
 
参考这两篇博客 博客一  博客二 博客三

公有方法:

  1.公有方法是可以在类的外部被调用的,

  2.但是它不可以访问类的私有属性。

  3.公有方法必须在类的内部或者外部通过类的prototype属性添加。

一般把共用的方法,都放在“原型对象“当中,如果放在构造函数中,会重复创建共同的方法。

特权方法: 

  1.特权方法是可以在类的外部被调用的, 
  2.但是它可以访问类的私有属性,并且也是可以访问类的公有属性,可以勉强的认为它是一种特殊的公有方法。 
  3.但是它与上面的公有方法的声明与定义方式不同。特权方法必须在类的内部声明定义。

在对象上添加特权方法:    (《高程三》P188)

1. 在构造函数中定义特权方法
     function MyObject(){
var privateVariable = 10;
function privateFunction(){
return false;
}
this.publicMethod = function(){ // 特权方法,利用构造函数的缺点是每个实例都会创建同样一组新方法
privateVariable ++;
return privateFunction();
};
}

2.在私有作用域中创建特权方法

    (function(){
// 私有变量 和 私有函数
var privateValue = 10;
function privateFunction(){
return false;
}
// 构造函数
MyObject = function(){}; //初始化未经声明的变量,总是会创建一个全局变量。因此,//MyObject成为全局变量,可以在私有作用域之外被访问到。没有var 属于全局变量,严格模式下会报错
// 公有/特权方法 (既是公有,又是特权方法)
MyObject.prototype.publicMethod = function(){
privateValue ++;
return privateFunction();
};
})();

[参考资料]

总结自《高程三》第四章

理解Javascript_12_执行模型浅析

JS的执行环境与作用域

javascript高级程序第三版学习笔记【执行环境、作用域】

JavaScript 执行环境(执行上下文) 变量对象 作用域链 上下文 块级作用域 私有变量和特权方法的更多相关文章

  1. js私有作用域(function(){})(); 模仿块级作用域

    摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: f ...

  2. Javascript的块级作用域

      一.块级作用域的说明 在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c. ...

  3. javascript模仿块级作用域(第一篇)

    作用域有词法作用域和块级作用域之分,javascript属于词法作用域,而在java.C++中却是块级作用域.在javascript中,只有函数能够创建作用域,作用域是以function作为边界的. ...

  4. JavaScript 作用域 匿名函数 模仿块级作用域(私有作用域)

    作用域 对于有块级作用域的语言来说,for语句中定义并初始化的变量i在循环外是无法访问的. 而javascript没有块级作用域,for语句中定义的变量i在循环结束后,依旧会存在于循环外部的执行环境( ...

  5. javascript块级作用域

    在c/java中,拥有块级作用域的概念,大括号内就是一个块级作用域,在块级作用域内声明的变量,块以外不可见. C语音的块级作用域示例如下: ,two = ; if(one < two){ ; t ...

  6. ES6块级作用域及新变量声明(let)

    很多语言中都有块级作用域,但JS没有,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域.用var声明的变量具有变量提升(declaration hoist ...

  7. Javascript高级编程学习笔记(25)—— 函数表达式(3)模仿块级作用域

    昨天写了闭包 今天就来聊聊块级作用域的事情 在绝大多数编程语言中,都有块级作用域这个概念 什么是块级作用域呢? 前面我们在刚开始讲的时候说过,JS中的大括号(不在赋值运算符的后面)表示代码块 块级作用 ...

  8. ECMAScript概述及浅谈const,let与块级作用域

    ECMAScript可以看作javascript的标准规范,实际上javascript是ECMAScript的一门脚本语言,ECMAScript只提供了最基本的语言JavaScript对ECMAScr ...

  9. ES6之块级作用域

    一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1.  全局作用域: 2.  函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...

  10. ES6的 let const 以及块级作用域

    let声明变量 用法类似于var,但是所声明的变量只在let所在的代码块内有效. 1 . 在ES6环境下,let声明的变量不能在声明之前调用. 例: console.log(i); //会报错,这叫做 ...

随机推荐

  1. 在 Linux 中自动生成 Cordova/Phonegap for Android 的 APK 安装程序

    在 Linux 中自动生成 Cordova/Phonegap for Android 的 APK 安装程序 本贴首发于: http://xuekaiyuan.com/forum.php?mod=vie ...

  2. Android中系统设置中的清除数据究竟会清除哪些数据

    今天中的一个story突然提到了系统设置中的清理数据,后来开始思考究竟系统的应用的这个清理功能,究竟会清理那些数据. 于是开始研究,以com.mx.browser为例,思路大概为首先为/data/da ...

  3. swift 动态获取label宽度或高度

    func getLabHeigh(labelStr:String,font:UIFont,width:CGFloat) -> CGFloat { let statusLabelText: NSS ...

  4. 结构-行为-样式-Bootstrap笔记

    1.自上而下的内容布局,中间内容可变,应该用: <div class=" container-fluid"> <div class=" row" ...

  5. jQuery核心结构简单分析

    以下分析均采取沙箱模式 (function (window) { //为了提高性能把需要的变量统一提前声明 var arr = [], push = arr.push; //为区别jQuery,此文章 ...

  6. 【转】关于JVM CPU资源占用过高的问题排查

    http://my.oschina.net/shipley/blog/520062 一.背景: 先执行一个java程序里面开了两个线程分别都在while循环做打印操作. ? 1 # java -cp  ...

  7. Struts框架的入门使用

    1.struts框架的使用 导入jar包 1.commons-fileupload-1.2.jar 2. freemarker-2.3.15.jar 3.ognl-2.7.3.jar 4.struts ...

  8. ProgrammingContestChallengeBook

    POJ 1852 Ants POJ 2386 Lake Counting POJ 1979 Red and Black AOJ 0118 Property Distribution AOJ 0333 ...

  9. js 判断是否为正数

    function validate(num) { var reg = /^\d+(?=\.{0,1}\d+$|$)/   if(reg.test(num)) return true;   return ...

  10. [转]解决VS2008 开发Windows Mobile 项目生成速度慢的问题

    最近用VS2008开发Windows Mobile程序,使用C#..NET Compact Framework,发现项目生成速度比较慢.用VS2008打开项目后,开始一段时间生成速度还能忍受,时间一长 ...