执行环境

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

作用域、调用对象

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

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

  • 词法作用域是在函数定义的时候创建的,作用域的本质是创建它的外层函数的调用对象组成的对象链,函数内部属性[[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. Flex表格中添加图片

      Flex4.5中datagrid加入图片显示image <s:DataGrid id="maingrid" x="0" y="36" ...

  2. ubuntu14.04下chrome浏览器的安装

    ubuntu 64位 1.下载chrome安装包: sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_ ...

  3. iOS开发之单例模式

    1.概述 单例模式是一种常用的软件设计模式,通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源. 如果希望系统中某个类的对象只能存在一个,单例模 ...

  4. Project下载提示检索 COM 类工厂中 CLSID 为 {36D27C48-A1E8-11D3-BA55-00C04F72F325} 的组件失败

    做后台系统导出Project时,部署到服务器提示:检索 COM 类工厂中 CLSID 为 {36D27C48-A1E8-11D3-BA55-00C04F72F325} 的组件失败,原因是出现以下错误: ...

  5. Activity的Task详解

    1.Task Task是一个具有栈结构(后进先出)的容器,可以放置多个Activity实例.启动一个应用,系统就会为之创建一个Task,来放置根Activity.默认情况下,一个Activity启动另 ...

  6. chrome插件推荐

    分享自己一直在用的chrome插件 1. Adblock Plus 广告屏蔽插件,能够屏蔽YouTube视频广告.Facebook广告.弹出窗口和其他显眼的广告,个人认为非常强大. 2.AutoPag ...

  7. C++中的类继承(1) 三种继承方式

    继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一.简单的说,继承是指一个对象直接使用另一对象的属性和方法.继承呈现了 面向对象程序设 计的层次结构, 体现了 由简单到复杂的认知过程. ...

  8. axure 动态面板制作图片轮播 (01图片轮播)

    利用Axure的动态面板组件制作图片轮播: 首先现在操作区添加一个动态面板组件: 鼠标放在动态面板上,右键单击选择面板状态管理,给动态面板设置名称并添加两条状态然后点击确定. 双击动态面板,然后双击s ...

  9. 从零开始用 Flask 搭建一个网站(一)

    前言 笔者之前未接触过 Python,只是略懂一点前端,所以说从零开始也相差无几吧.Flask 是一个轻量级的基于 Python 的框架,但是扩展性非常良好(Github 上 22000 多个 sta ...

  10. 跟着刚哥梳理java知识点——异常(十一)

    异常:将程序执行中发生的不正常情况(当执行一个程序时,如果出现异常,那么异常之后的代码就不在执行.) java.lang.Throwable:异常的超类 1.Error:java虚拟机无法解决的严重问 ...