JS作用域、链学习笔记

来源:互联网 发布:淘宝手机评价管理登录 编辑:程序博客网 时间:2024/06/07 22:03

JS作用域


作用域就是变量与函数的可访问范围,控制着变量与函数的可见性和生命周期。分为全局和局部作用域链。

  1. 全局作用域(Global Scope)
    (1)最外层函数和在最外层函数外面定义的变量拥有全局作用域链。
    (2)所有未定义直接赋值的变量自动声明为拥有全局变量。
    (3)所有window对象的属性 拥有全局作用域。
    一般,window对象的内置属性都拥有,例window.name、window.location、window.top等等。

2.局部作用域(Local Scope)
局部作用域一般只在固定的代码片段内可访问到,例如函数内部。

var name = 'zjh'; //全局function  echo() {    blogname = 'MyBlog'; //全局    var authorname = 'zzzz'; //局部}

JS作用域链


JS权威指南中描述:“javascript中的函数运行在他们被定义的作用域里,而不是它们执行的作用域里。” “一切皆对象,函数也是。
函数对象和其他对象一样,拥有可以通过代码访问的属性和仅供Javascript引擎访问的内部属性,其中一个内部属性是[[Scope]],该内部属性包含了函数被创建的作用域中对象的集合,这个集合称为函数的作用域链。
当一个函数被创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。
(函数所有的局部变量、命名参数、参数集合以及this)
例:

var name = "zjh";function echo() {    alert(name);    var name = "eve";    alert(name);    alert(age);}echo();

运行结果

underfiendeve[脚本出错]

当echo函数被调用的时候,echo的活动对象已经被预编译过程创建

[[scope chain]] = [{    this : window,    arguments : [],    name : underfined}]

作用域链和代码优化

从作用域链的结构可以看出,标识符所在的位置越深,读写速度越慢。因为全局变量总是存在于作用域链的最末端。所以,在编写代码时应尽量少使用全局变量,尽可能使用局部变量。经验法则:如果一个跨作用域的对象被引用了一次以上,则先把它存储在dc局部变量里再使用。
例:

function changeColor(){    document.getElementById("btnChange").onclick=function(){        document.getElementById("targetCanvas").style.backgroundColor="red";    };}

引用两次document,重写如下:

function changeColor(){    var doc=document;    doc.getElementById("btnChange").onclick=function(){        doc.getElementById("targetCanvas").style.backgroundColor="red";    };}

Javascript的预编译

<script>alert(typeof eve); //function    function eve() {         alert('I am Zach');}</script>

JS在执行每一段JS代码之前,都会先处理var关键字和function定义时(函数定义式和函数表达式).
在跳用函数之前,首先会创建一个活动对象,然后搜寻这个函数中的局部变量定义和函数定义,将变量名和函数名都做为这个活动对象的同名属性,变量的值会在真正执行的时候才计算,此时只是简单地赋为underfiend.
而对于函数定义式,是一个要注意的地方.

<script>    alert(typeof eve); //function    alert(typeof walle); //underfiend    function eve() { //函数定义式或函数申明        alert('I am Zach');}    var walle = function() {} //函数表达式 </script>

参考blog:
梦想天空
鸟哥

0 0