`
charlesEye
  • 浏览: 6867 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

javascript笔记:通过对作用域链和执行环境的深入理解所得出的提高javascript代码性能的建议 《转载》

 
阅读更多

上篇文章里我结束了对象的创建的内容,最后引出了作用域链和执行环境的问题。当我对这块知识有了更深入的了解后,回头看看jQuery源码才知道大师们写的代码是如何的厉害,jQuery源码里很好的运用了作用域链和执行环境的知识来提升程序性能。

  好了,不废话了,上篇博文里对作用域讲的比较简略。其实对作用域的理解是理解整个javascript语言的关键所在,特别我在写javascript笔记时候曾对很多怪异的javascript用法无法理解的透彻,究其原因还是没有真正理解javascript里作用域的概念。

  Javascript里的作用域到底决定了什么呢?作用域决定了那些变量能被函数所访问(注意:作用域是函数的内部属性,谈到作用域是绕不开的function),作用域也确定了this指针的指向。上篇博文里我说道,程序其实就是不断检索数据的过程,那么检索数据的效率决定了程序的性能,因此作用域既然决定那些变量能被访问,当然也决定了检索这些变量的方式,所以想写出高效的javascript程序灵活运用作用域的原理是关键了。

  上篇博文里面,我写了一个函数,代码如下:

复制代码
<script type="text/javascript">
function add(a,b)
{
var sum = a + b;
return sum;
}
</script>
复制代码

  大家可以看到这个函数属于window而非function,在页面被加载时候,add函数会被初始化,生成属于自己的作用域链,上篇文章里我在firebug里设定断点调试贴出了一个我截图下来的变量图,认为这就是函数add的Scope所包含的变量,现在发现当时理解是错误的,那些变量是window的“全局环境”的变量图而非是add函数的内部属性Scope的变量图。在此我纠正一下。

  下面我要着重讲讲作用域链和执行环境,这块知识我在javascript对象创建的中篇里提到过,这里我将那些知识回顾下:

    什么是执行环境呢?在javascript里面执行环境分为两类,一类是全局环境,一类是局部环境,整个页面里被共享的方法和属性就是在全局环境,相对于全局环境,函数{}号里的执行环境就是局部环境,执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为,每个执行环境都定义了一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象里,虽然我们自己编写的代码无法访问这个对象,但解析器在处理数据时候后台会使用到它。
全局执行环境另一种说法是最外围的一个执行环境,在web浏览器的范围中(actionscript也是施行了ECMAScript标准,它的全局范围就和javascript的全局范围不同),全局执行环境被认为是window对象,因此全局变量和函数都是作为window对象的方法和属性来创建的,全局执行环境知道应用程序退出比如关闭网页或浏览器才会被销毁。而局部环境则是以函数对象作为关联对象。

  大家要注意环境的前缀是:执行,也就说只有函数被执行(局部执行环境)和页面被加载(全局执行环境),下面就是页面被加载时候的全局执行环境变量:

  现在我们要执行add函数了,代码如下:

复制代码
function add(a,b)
{
var sum = a + b;
return sum;
}

console.log(add(10,20));
复制代码

  

  这是add函数的执行环境的变量图是:

  1.firebug:

  2.chrome的代码调试器:

  代码的结构图如下:

  在函数被执行时候,函数会创建一个“运行期上下文(execution context)”的内部对象,这个运行期上下文在我的理解里就是函数的执行环境,每个运行期上下文都有自己的作用域链,用于标识符解析。

  当运行期上下文被创建时候,他的作用域链初始化为当前运行函数【Scope】属性中所含的对象(见firebug和chrome调试器里的内存图,比如add函数除了a,b,sum,this还有arguments,不过这个在firebug和chrome调试器里看不到的)。这些值按照它们出现在函数中的顺序,被复制到执行期上下文的作用域链中。这个过程一旦完成,一个被称为“活动对象(activation object)”的新对象就为执行期上下文创建好了,活动对象作为函数运行期的可变对象,包含了所有局部变量,命名参数,参数集合以及this。然后此对象被推入到作用域链的前端。当运行期上下文被销毁的时候,活动对象也随之被销毁。在函数执行过程中,每遇到一个变量都会进行一次标识符的解析,这种解析决定了我们从啥地方获取变量或者将变量存储到什么地方,这个过程是搜索整个函数运行期上下文的作用域链,查找同名的标识符,搜索过程都是从作用域头部开始,也就是当前运行函数的活动对象。找到了就使用它,没有找到则会继续搜索作用域链中的下一个对象,搜索过程会延续到找到标识符为止或者是没有找到为止,这种情况就是标识符没有被定义了

  在javascript里使用变量就是在做标识符解析,由上面的解释我们知道标识符的解析一定是有计算机性能的消耗的,当标识符位于执行上下文作用域链的位置越深,性能也就越慢了,那么到底什么地方最慢了?比如我们举例的函数add,当我们搜索到global全局变量总会比函数内部的局部变量慢,假如我们定义个更复杂的函数里面有多层嵌套的话,访问全局变量就是性能的梦魇了。因此在函数中我们尽量多使用函数内部的局部变量。(由于浏览器的产品的差异,个别浏览器的访问变量的性能可能会有差异,但是总体而言,访问函数局部变量永远是最快的)。

  尽量使用局部变量,就带来一个十分重要的提高程序性能的用法:我们在函数内部使用全局变量可以说是一种跨作用域操作,如果某个跨作用域的值在函数的内部被使用到一次以上,那么我们就把它存储到局部变量里

  代码书写的格式就是:

function ftn()
{
var doc = document;
.......
}

 

  将全局的变量用var定义到局部变量里。

  这个用法在jQuery源码里一开头就清晰可以到看:

复制代码
var jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},

// Map over jQuery in case of overwrite
_jQuery = window.jQuery,

// Map over the $ in case of overwrite
_$ = window.$,

// Use the correct document accordingly with window argument (sandbox)
document = window.document,
复制代码

  jQuery把经常使用的全局变量都存储在函数的局部变量里。

分享到:
评论

相关推荐

    狂神说系列 JavaScript笔记

    【狂神说系列 JavaScript笔记】是一份全面且深入的JavaScript学习资源,旨在帮助开发者和初学者深入理解这门广泛应用于Web开发的脚本语言。这份笔记涵盖了JavaScript的基础语法、核心概念以及高级特性,旨在构建一个...

    《李炎恢Javascript笔记》+源码

    《李炎恢Javascript笔记》是一本深入浅出的JavaScript学习资料,它涵盖了JavaScript的基础到实践应用的诸多方面。这本书的特点是将复杂的编程概念分解为易于理解的小知识点,并且提供了源码示例,使得读者能够更好地...

    JavaScript_Demo,文章《JavaScript笔记》配套代码

    这篇文章《JavaScript笔记》的配套代码提供了丰富的实例,旨在帮助读者深入理解和掌握JavaScript的基本概念、语法以及应用技巧。 首先,我们来看看“JS笔记”部分。在学习JavaScript时,理解变量的声明、数据类型...

    javascript入门学习笔记

    理解闭包和作用域对于掌握JavaScript的高级特性至关重要。 三、DOM操作 在Web开发中,JavaScript常用于操作文档对象模型(DOM),通过DOM可以改变HTML元素的样式、内容或位置。熟悉DOM API,如getElementById、...

    Javascript入门笔记和一些代码

    在"03_Advanced_JavaScript"中,你将接触到更高级的主题,比如作用域(全局、局部、闭包)、原型链和继承机制、异步编程(回调函数、Promise、async/await)、模块化(CommonJS、ES6模块)、以及错误处理。...

    JavaScript-学习笔记.pdf

    以上是JavaScript学习笔记中提到的一些核心知识点,通过对这些知识点的理解和熟练应用,可以为进一步学习和掌握JavaScript打下坚实的基础。在实际开发过程中,结合具体的项目需求,这些知识会得到更深入的拓展和应用...

    JavaScript基础教程笔记

    ### JavaScript基础教程笔记知识点 #### 一、JavaScript简介 - **定义**:JavaScript是一种轻量级的编程语言,主要用于Web浏览器中的网页交互控制。 - **发展历史**:1995年由Netscape公司的Brendan Eich设计并...

    Javascript学习笔记(传智播客视频学习笔记+代码)

    学习如何使用浏览器的开发者工具进行代码调试,理解执行上下文、作用域链、垃圾回收等概念,对于提升代码性能和解决运行问题十分关键。 通过"JS基础知识学习笔记(传智)"这份资料,你可以系统地学习JavaScript的...

    JavaScript学习笔记

    - 变量声明:JavaScript支持var、let和const关键字声明变量,理解它们的作用域和提升特性至关重要。 - 数据类型:JavaScript有七种数据类型,包括原始类型(如字符串、数字、布尔、null和undefined)和引用类型...

    JavaScript 学习笔记集和代码库

    压缩包中的“JavaScript学习笔记集”可能包含了语言的基本概念、语法特性、面向对象编程、闭包、原型链、作用域、异步编程等内容的详细解释。而“代码库”可能包含了大量的示例代码,涵盖各种常见任务,如表单验证、...

    javascript学习笔记整理知识点整理

    闭包是JavaScript的一个重要特性,它允许函数访问并操作其外部作用域的变量,即使在函数执行完毕后仍然保持对这些变量的访问。JavaScript有全局作用域和局部作用域,函数内部创建的变量仅在函数内部可见。 八、异步...

    JavaScript: The Good Parts 读书笔记(五)

    通过阅读《JavaScript: The Good Parts》,开发者可以更好地理解JavaScript的核心原理,学习到如何编写更安全、更高效的代码,并避免常见的陷阱。在实际工作中,这些知识能够提升代码质量和项目效率。对于想要深入...

    韩顺平javascript笔记(最全整理 dom编程 oop 基础语法)

    此外,JavaScript还有封装(使用函数和作用域来隐藏内部实现)、继承(通过原型或class关键字)和多态(一个接口,多种实现)等OOP特性。理解这些概念能帮助开发者设计出更加灵活和复用性强的代码结构。 再来谈谈...

    JavaScript 入门 新手学习笔记

    8. **闭包**:理解闭包的概念及其在内存管理、模块化和函数作用域中的应用,是进阶学习的重要部分。 9. **面向对象编程**:JS支持基于原型的面向对象,包括构造函数、原型链、继承等概念。 10. **JavaScript框架和...

    JavaScript的笔记

    JavaScript是一种广泛应用于Web开发的脚本语言,它主要在...以上就是JavaScript笔记的主要内容,通过深入学习和实践,你可以掌握这门强大的脚本语言,无论是客户端交互还是服务器端开发,JavaScript都能发挥重要作用。

    李炎恢JavaScript-pdf文档笔记

    笔记可能详细解析了原型链、闭包、作用域等概念。 3. **DOM操作**:文档对象模型(DOM)是JavaScript操作HTML和XML文档的标准接口。学习者将了解到如何通过JavaScript选择、添加、修改和删除DOM元素,以及事件处理...

    JavaScript入门课堂随堂笔记.zip

    JavaScript,也被称为JS,是一种广泛应用于网页和网络应用的脚本语言。它是Web开发的核心技术之一,用于...在阅读"JavaScript入门课堂随堂笔记"的过程中,建议结合实际项目进行练习,以便更好地理解和运用所学知识。

    前端开发必备JavaScript(含源码课件笔记总结)

    课程中的源码分析部分,可能是对一些经典库或框架的源码解读,如jQuery、lodash等,通过阅读源码,可以深入理解JavaScript的高级技巧和优化手段,提升代码质量。 八、笔记总结 笔记部分是对整个学习过程的记录和...

    面向对象javascript笔记

    面向对象的JavaScript编程是JavaScript开发中的重要概念,它允许我们以类和对象的...以上就是对"面向对象javascript笔记"所涵盖知识点的详细解析。理解并掌握这些概念对于深入理解和高效地编写JavaScript代码至关重要。

Global site tag (gtag.js) - Google Analytics