函数在javascript中可以说是一等公民,也是最有意思的事情,javascript函数其实也是一个对象,是Function类型的实例。因此声明一个函数首先可以使用 Function构造函数:

var saySomething = new Function("something","console.log(something)");
saySomething("hello world!"); // 输出hello world!

Function构造函数可以接受多个参数,但最后一个参数被视为函数体,当然这种方法不直观,因此大部分时候我们使用如下声明:

var saySomething = function(something){
console.log(something);
};
saySomething("hello world!"); // 输出hello world!

或者:

function saySomething(something){
console.log(something);
};
saySomething("hello world!"); // 输出hello world!

这样直观也便于理解多了。

由于函数是一个对象,因此函数名就是一个指向函数对象的指针。如下面示例代码:

示例1:

function makeCounter() {
var i = 0;
console.log( ++i );
} var counter2=makeCounter; //无输出
counter2(); //输出:1
counter2(); //输出:1

var counter2=makeCounter; 这句其实就是将函数makeCounter的引用给了counter2, counter2就是一个别名,它们都指向同一个函数。因此这句 无输出

接来下的 counter2(); 两次就是对函数调用两次,每次调用, 局部变量 i 在调用结束后就不能范问了,因此两次返回的结果都是 输出:1

当函数第一次被调用时,会创建一个执行环境,以及相应的作用域链。执行环境中定义变量和函数都保存在一个称为变量对象的结构中。执行环境通常可分为全局执行环境和局部执行环境。全局执行环境是最外围的执行环境,根据js的宿主不同而异,在web中是 window对象,在node中是 globle对象。因此所有的全局变量和函数都属于全局执行环境,也就是 window对象的属性和方法。

每个函数都有自己的执行环境,当代码执行进入一个函数时首先将会创建一个执行环境,这个过程首先是创建活动对象,活动对象在一开始是只包含一个变量,即arguments对象,然后是 this对象 以及其他的内部变量。作用域链保存这函数有权访问的执行环境的先后顺序,作用域链的最前端始终是当前执行的代码所在的环境的活动对象,下一个是包含该函数的外部环境,再下一个是包含该函数的外部的外部环境,这样类推,直至全局环境。

当访问一个变量时,需要搜索该变量标识符。搜索过程从作用域链的最前端开始,向上逐级查找,直至第一个找到时停止,如果直到全局环境的活动对象中都找不到,说明该变量未声明。

var color="blue";
function getColor(){
var color='red';
return color;
}
console.log(getColor()); // 输出:red

getColor函数首先在当前的执行环境中找到了 color定义,于是输出 red,停止。

var color="blue";
function getColor(){
return color;
}
console.log(getColor()); // 输出:blue

getColor函数首先在当前的执行环境中没有找到 color定义,于是向上一层查找,在全局环境中找到了 color定义,于是输出 blue。

另外一个需要注意的是 javascript中是没有块级作用域的,不像 C,Java等,在一对花括号 {  } 包围起来的区域都有自己的作用域。

if(true){
var color="blue";
}
console.log(color); // 输出:blue

由于 javascript没有块级作用域,因此,在 { } 之外,仍然能够访问到 color 为 blue的定义。

Javascript 函数及其执行环境和作用域的更多相关文章

  1. javascript中函数的执行环境、作用域链、变量对象与活动对象

    javascript高级程序设计中:对执行环境.作用域链.变量对象.活动对象的解释: 1.执行环境: 执行环境:有时也叫环境:是JavaScript中最为重要的一个概念:执行环境定义了变量或函数有权访 ...

  2. Javascript高级程序设计——执行环境与作用域

    Javascript中执行环境是定义了变量或函数有权访问的其他数据,决定了各自的行为,每个执行的环境都有一个与之关联的变量对象,环境中定义的所以变量和函数都保存在这个对象中. 全局执行环境是最外围的一 ...

  3. 【JS】JavaScript中的执行环境与作用域

    JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是 ...

  4. javascript基础进阶——执行环境及作用域链

    概念 执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局 ...

  5. JavaScript:理解执行环境、作用域链和活动对象

    作用域的原理,对JS将如何解析标识符做出了解答.而作用域的形成与执行环境和活动对象紧密相关. 我们对于JS标识符解析的判断,存在一个常见误区 首先,看一个关于JS标识符解析的问题 ,源于风雪之隅提出的 ...

  6. JavaScript语言精粹--执行环境及作用域,this

    1.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为. 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 虽然我们无法访问,但是解析器在处理数据时 ...

  7. javascript学习笔记 - 执行环境及作用域

    一 执行环境(环境) 1.每个执行环境都有一个关联的全局变量对象.例如:web浏览器中,window对象为全局变量对象.环境中定义的所有变量和函数都保存在该对象中.全局执行环境是最外围的环境. 2.执 ...

  8. 深入理解javascript中执行环境(作用域)与作用域链

    深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...

  9. JavaScript 执行环境以及作用域链

    执行环境(execution context,为简单起见,有时也称为"环境")是 JavaScript 中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们 ...

随机推荐

  1. PHP 中 var_export、print_r、var_dump 调试中的区别

    1.output basic type 代码 $n = "test"; var_export($n); print_r($n); var_dump($n); echo '----- ...

  2. iPhone X Web 设计

    原文地址:https://webkit.org/blog/7929/designing-websites-for-iphone-x/ 开箱即用(开发者无需进行任何设置),在iPhone X中,Safa ...

  3. Flask-socketio聊天室 (附源码)

    `* A Chat Room Completed with Flask-socketio 功能: 实时消息更新,实时用户上线显示 快捷注册 快捷登陆 表情支持 截图: 使用方法: 安装依赖:pip i ...

  4. Web API 2 对于 Content-Length 要求严格

    最近在做一个工具,里面有一个发起http请求的操作,虽然工具不是用.NET写的,但是测试用服务器软件是.NET写的.在这里选择了ASP.NET MVC和Web API 2. 首先预定义Student与 ...

  5. git中多账号切换问题的解决方案(转)

    作者:知乎用户链接:https://www.zhihu.com/question/23028445/answer/416231632来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  6. 深入理解SpringCloud之Eureka注册过程分析

    eureka是一种去中心化的服务治理应用,其显著特点是既可以作为服务端又可以作为服务向自己配置的地址进行注册.那么这篇文章就来探讨一下eureka的注册流程. 一.Eureka的服务端 eureka的 ...

  7. Android开发之漫漫长途 XV——RecyclerView

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...

  8. tomcat如何正确的开启远程调试功能

    在日常开发中,有时需要对远程服务器上的应用进行远程调试,对于tomcat,要进行远程调试其实很简单,只需要在启动tomcat时开启jpda服务即可. 什么是JPDA呢? JPDA(JavaPlatfo ...

  9. Java1.8 JDK源码中,对两个类进行 按位与 操作是什么意思

    Java容器类库中的Map接口(java\util\Map.java)中有一个Entry接口(java\util\Map.java),其中有几个接口方法用到了类和类的按位与操作,即类和类之间有 &am ...

  10. logback打印mybatis sql日志

    近期在项目中调试sql,发现现有的配置 使用logback 无法打印出sql语句,原配置如下(修改为debug也不好使): <!--jdbc --><logger name=&quo ...