执行环境

当执行流执行到函数时会创建一个执行环境,这个执行环境包含了函数内部 语句可以访问的所有变量和函数,当代码执行完时,销毁执行环境。所以一般情 况下,局部变量在函数执行完时会被销毁。

作用域、调用对象

很多人认为作用域是在函数执行时创建的,这是有偏差的理解!

作用域分词法作用域和动态作用域:

  • 词法作用域是在函数定义的时候创建的,作用域的本质是创建它的外层函数的调用对象组成的对象链,函数内部属性[[scope]]指向此作用域。
  • 当调用函数时,会创建一个调用对象(有些地方称活动对象),这个调用对象保存了函数参数和局部变量。将此调用对象推入词法作用域的前端,因此执行时作用域发生了变化,称为动态作用域。

实质上作用域只有一个,都是内部属性[[scope]],词法作用域和动态作用域是时间上的不同造成的划分。作用域链是一条对象链,函数自己的活动对象,接着是父函数的活动对象,接着是祖父函数的活动对象。。。。 函数执行时,是沿着作用域链去寻找标识符的值的,先从自己的活动对象开始。 with、catch 会改变动态作用域,将with的对象和catch的对象压入作用域链前端。

下面出个例子看你是否对作用域链理解到位了:

var obj = {a:1,b:2};
var fn = function(){
var c=3;
var a = 5;
console.log(a); //a等于多少?
with(obj){
a=6;
return function(){return a+c;};
}
}();
fn(); //结果是多少?

闭包  

啥是闭包?

官方:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

民间:内部函数拥有外部函数的环境。

通俗的就是内部函数可以访问外部函数的变量。

形成机理:作用域链。

内存及变量查找效率

当有闭包,且内部函数赋给了外部变量引用时,要特别注意内存 。没有赋给外部变量时,代码执行完后执行环境销毁,不会有变量贮存内存。但赋给了外部变量时,闭包的词法作用域链会持有外层函数的活动对象,使得外部的变量不会回收。为了有效回收应该将变量设为null,断开引用。

var fn = function(){
var div = document.getElementById("div");
return function(){};
}; //div不会销毁

根据作用域链的原理,处于作用链前端的变量会更快找到,所以尽量用局部变量。

 var a,b,c;
var fn = function(){
var d,e,f;
return function(){
var h,j,k;
return typeof nothing; //nothing这个变量查找了整条作用域链,直到查询到window中这个变量,才返回"undefined".
};
};

this

this跟arguments一样是函数执行时,活动对象的一部分。this是动态的,函数执行时候绑定。

大概有这几种情况:

(1) 函数,this==window

var fn = function(){console.log(this==window);}; //true

fn(); //不管函数fn在任何地方定义,是顶层函数,还是嵌套 ,this都等于window

(2) 方法,this==obj

var obj = {};

obj.fn = function(){console.log(this==obj);}; //true

obj.fn();

(3)setTimeout setInterval,this==window

var obj = {};

var fn = function(){console.log(this==obj);};

setTimeout(fn,1000); //?

obj.fn = fn;

setTimeout(obj.fn,1000); //?

(4)call,apply将函数or方法绑定给了对象,this==obj

var obj = {};

var fn = function(){console.log(this==obj);}; //true

fn();

fn.call(obj);

(5)事件处理程序

DOM0

btn.onclick = function(){console.log(this==btn);}; //true

DOM2

btn.addEventListener("click",function(){
console.log(this==btn); //true
},false);

IE

btn.attachEvent("onclick",function(){
console.log(window==btn); //true
});

javascript执行原理的更多相关文章

  1. 浏览器中JavaScript执行原理

    本章我们讨论javascript在浏览器中是如果工作的,包括:下载.解析.执行的全过程.javascript的这些讨人嫌的地方我们是知道的: i.需要串行下载 ii.需要解析 iii.需要串行执行 而 ...

  2. Javascript之数据执行原理探究

    Javascript在Web服务器端执行原理: 1.客户端请求数据,即我们在上网时在地址栏中输入某个网址,浏览器接收到数据之后,向远程web服务器发送请求报文. 2.web服务器响应请求,web服务器 ...

  3. 《浏览器工作原理与实践》<11>this:从JavaScript执行上下文的视角讲清楚this

    在上篇文章中,我们讲了词法作用域.作用域链以及闭包,接下来我们分析一下这段代码: var bar = { myName:"time.geekbang.com", printName ...

  4. Javascript引擎的单线程机制和setTimeout执行原理阐述

    工作中使用setTimeout解决了一个问题,于是对setTimeout的相关资料整理了下,以及对js引擎执行的原理一并整理了下,希望能给码农们一些帮助.若发现有错的地方大家及时指出,共同学习进步. ...

  5. JavaScript作用域原理(三)——作用域根据函数划分

    一.一个for实例 <p id="scope3" style="color:red"></p> var pscope3 = docume ...

  6. JavaScript作用域原理(二)——预编译

    JavaScript是一种脚本语言, 它的执行过程, 是一种翻译执行的过程.并且JavaScript是有预编译过程的,在执行每一段脚本代码之前, 都会首先处理var关键字和function定义式(函数 ...

  7. JavaScript作用域原理(一)——作用域链

    一.作用域的描述 JavaScript权威指南中对作用域有一句很精辟的描述:“JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.” 在JavaScript中,作用域的 ...

  8. JavaScript执行顺序分析

    之前从JavaScript引擎的解析机制来探索JavaScript的工作原理,下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序.如果说,JavaScript引擎的工作机制比较深奥 ...

  9. 深入理解JavaScript Hijacking原理

    最近在整理关于JavaScript代码安全方面的资料,在查关于JavaScript Hijacking的资料时,发现关于它的中文资料很少,故特意整理一下. 一.JavaScript Hijacking ...

随机推荐

  1. LKNotification控件-通知控件

    通知控件 项目介绍: 一个通知控件,长得很像iOS系统的通知栏弹出时候的样式.可以多个通知覆盖.引入项目之后,只需调用一行代码即可 [Java] 查看源文件 复制代码 ? 1 LKNotificati ...

  2. eclipse和myeclipse设置默认编码格式为UTF-8

    1:jsp页面设置默认为utf-8 以eclipse为例 2:java界面设置: Window->Preferences->General->Workspace 面板Text fil ...

  3. java根据HashMap中的值将其元素排序

    思路:HashMap或Map本身没有排序功能,若要进行较轻松的排序,可利用ArrayList中的sort方法 例子: import java.util.ArrayList; import java.u ...

  4. Dark的项链(树链剖分)

    P2272 - Dark的锁链 Description 无向图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边.Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由 ...

  5. SQL AlawaysOn 之三:SQL服务器加入域

    声明:由于第一篇,配置域服务器,用的是别人的图,所以那个IP并不是我的. 至此为止,我的域控制器IP为192.168.8.230 域名为:dataserver.com 约定的SQL1  IP为192. ...

  6. [译]Selenium Python文档:二、初步开始

    2.1.简单使用 如果已经安装好了Selenium Python,你就可以像下面这样编写Python代码来使用它了: from selenium import webdriver from selen ...

  7. cuda编程学习6——点积dot

    __shared__ float cache[threadPerBlock];//声明共享内存缓冲区,__shared__ __syncthreads();//对线程块中的线程进行同步,只有都完成前面 ...

  8. pg_config executable not found

    Error: pg_config executable not found. Please add the directory containing pg_config to the PATH or ...

  9. C#封装MongoDB工具类库

    什么是MongoDB MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保证服务器性能. MongoDB 旨在为WEB应用提供可扩 ...

  10. 【C++】智能指针详解(二):auto_ptr

    首先,我要声明auto_ptr是一个坑!auto_ptr是一个坑!auto_ptr是一个坑!重要的事情说三遍!!! 通过上文,我们知道智能指针通过对象去管理指针,在构造对象时完成资源的分配及初始化,在 ...