`
阿尔萨斯
  • 浏览: 4168761 次
社区版块
存档分类
最新评论

Javascript 进阶 作用域 作用域链

 
阅读更多

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/25076713

一直觉得Js很强大,由于长期不写js代码,最近刚好温故温故。

1、Javascript没有代码块作用域的概念,局部作用域是针对函数来说的。

        function fun()
        {
            for( var i = 0 ; i < 10 ; i++)
            {}
            //如果在Java中i此时应当属于未声明的变量,但是Js中i的作用域依然存在
            console.log(i);//10

            if(true)
            {
                var b = "helloworld";
            }
            console.log(b);//helloworld
        }
        fun();


2、如果不使用var声明的变量,默认为全局变量

        function fun02()
        {
            a = "helloworld";
            var b = "welcome";
        }
        fun02();
        console.log(a); //     helloworld
        console.log(b); //   b is not defined

3、Js中的作用域链

先看个简单的例子:只有一个函数对象,函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

  var a = "hello";

        function fun04()
        {
             a = "world";
              var b ="welcome";
        }
作用域链的图:


注:图中省略了,Global Scope中的window,document等,每个函数对象中的arguments,this等均未画出。

  function fun03()
        {
            var a = 10;
            return function(){
                a*= 2 ;
                return a ;
            };
        }

        var f = fun03();
        f();
        var x = f();
       console.log(x);  //40

        var g = fun03();
        var y = g();
        console.log(y); //20

观察上面代码,存在fun03,f,g三个函数对象。

下面是作用域链的图:


注:每个函数对象一个作用域链,这里直接画在了一起;对于变量的查找,先从链的0开始找。

函数对象 f 在代码中执行了2 次,所以a*2*2 = 40 ; 函数对象 g 在代码中执行了1次, 所以 a *2 = 20 ;

4、闭包

上面的例子可以看到,在fun03执行完成后,a的实例并没有被销毁,这就是闭包。个人对闭包的理解是:函数执行完成后,函数中的变量没有被销毁,被它返回的子函数所引用。

下面以一个特别经典的例子,同时使用作用域链解析:

window.onload = function()
        {
            var elements = document.getElementsByTagName("li");
            for(var i = 0; i < elements.length ; i ++)
            {
                elements[i].onclick = function()
                {
                    alert(i);
                }
            }

        }

相信上面的代码肯定大家都写过,本意是点击每个li,打印出它们的索引,可是事实上打印出的都是elements.length。这是为什么呢?


看下上面的简易的作用域链(省略了很多部分,主要是理解),此时每个onclick函数的i,指向的都是 onload 中的i 此时的 i = element.length.

下面看解决方案:

 window.onload = function ()
        {
            var elements = document.getElementsByTagName("li");
            for (var i = 0; i < elements.length; i++)
            {
                (function (n)
                {
                    elements[n].onclick = function ()
                    {
                        alert(n);
                    }
                })(i);
            }

        }

在onclick函数的外层,包了一层立即执行的函数,所以此时的n指向的 n 是立即执行的,所有都是1~elements.length 。




分享到:
评论

相关推荐

    JavaScript进阶(二)词法作用域与作用域链实例分析

    本文实例讲述了JavaScript词法作用域与作用域链。分享给大家供大家参考,具体如下: 一、作用域 域表示的就是范围,即作用域,就是一个名字在什么地方可以使用,什么时候不能使用。想了解更多关于作用域的问题推荐...

    Web-前端教程37 JS进阶:作用域.zip

    Web-前端教程37 JS进阶:作用域.zip

    javascript基础进阶_深入剖析执行环境及作用域链

    当代码在一个环境中执行,会创建变量对象的一个作用域链。 用途:保证对执行环境有权访问的所有变量和函数有序访问。 特点:作用域链的前端始终是当前执行的代码所在的环境的变量对象。如果这个环境是函数,则将其...

    JavaScript进阶(三)闭包原理与用法详解

    为了更好的理解,在阅读此文之前建议先阅读上一篇《JavaScript词法作用域与作用域链》 1.什么是闭包 闭包的含义就是闭合,包起来,简单的来说,就是一个具有封闭功能与包裹功能的结构。所谓的闭包就是一个具有封闭...

    带你学习javascript的函数进阶(二)

    文章目录1 严格模式1.1 什么是严格模式1.2 开启严格模式3.3 严格模式中的变化2 高阶函数3 闭包3.1 变量作用域3.2 什么是闭包3.3 闭包案例3.4 闭包总结4 递归4.1 什么是递归4.2 利用递归求数学题4.3 利用递归求:根据...

    千峰python课件笔记+源码 (凯哥)

    '千锋python基础教程:7、装饰器&偏函数与作用域与异常处理与文件读写' 千锋python基础教程:8、os与窗口控制与内存修改与语言 第二章前端基础 1、html&css;基础 2、html&css;提升 3、JavaScript基础 4、...

    JavaScript核心技术 PDF扫描版

    2.2作用域 2.3简单类型 2.4常量:有名称但不改变 2.5习题 第3章运算符和语句 3.1JavaScript语句的格式 3.2简单语句 3.3条件语句和程序流 3.4条件运算符 3.5逻辑运算符 3.6高级语句:循环语句 3.7习题 第4章...

    JavaScript提高网站性能优化的建议(二)

    1 利用js作用域链 作用域链(scope chain) 当执行一段JavaScript代码(全局代码或函数)时,JavaScript引擎会创建为其创建一个作用域又称为执行上下文(Execution Context),在页面加载后会首先创建一个全

    深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解

    1、JavaScript中定义函数有2钟方法:  1-1.函数声明: 代码如下:function funcName(arg1,arg2,arg3){ //函数体} ①name属性:可读取函数名。非标准,浏览器支持:FF、Chrome、safari、Opera。 ②函数声明提升:指...

    2023年前端面试必备最新八股文(基础+进阶内容+持续更新)

    包括了css,javascript,vue,webpack,vite,html5新特性等等,包括了面试中比较常见的BFC,v8垃圾回收机制,vite和webpack的区别,vue中遇到的问到,防抖节流,深拷贝,浅拷贝,盒子模型,作用域,闭包,浏览器...

    浅谈关于JavaScript的语言特性分析

    前言在JavaScript中,作用域、上下文、闭包、函数等算是精华中的精华了。对于初级JSer来说,是进阶必备。对于前端攻城师来说,只有静下心来,理解了这些精华,才能写出优雅的代码。 本文旨在总结容易忘记的重要知识...

    前端JavaScript笔记整理

    JavaScript基础:变量、常量、数据类型、类型转换、运算符、语句、数组、函数、对象、堆栈 ...JavaScript高级:作用域、函数进阶、解构赋值、构造函数、编程思想、原型、深浅拷贝、异常处理、this、防抖节流

    js-deep:js深入学习

    前端进阶JavaScript基础:JavaScript数据类型JavaScript代码运行机制作用域和作用域链let/const/var的区别JavaScript高阶编程技巧原型和原型链的底层运行机制this指向数据类型检测JavaScript类的继承方案JavaScript...

    2022前端企业高频问答题

    JavaScript: 数据类型、面向对象、继承、闭包、插件、作用域、跨域、原型链、模块化、自定义事件、内存泄漏、事件机制、异步装载回调、模板引擎、Nodejs、JSON、ajax等。 其他: HTTP、安全、正则、优化、重构、...

    leetcode下载-blog:博客

    作用域链和闭包 this解析 原型和原型链 继承 JS进阶 call和apply模拟实现 bind模拟实现 new模拟实现 深浅拷贝 函数柯里化 防抖和节流 函数递归 ES6 let, const Symbol, Iterator和Map Generator, Promise和Async ...

    前端面试必备最新八股文(基础+进阶内容)2024年最新.docx

    包括了css,javascript,vue,webpack,vite,html5新特性等等,包括了面试中比较常见的BFC,v8垃圾回收机制,vite和webpack的区别,vue中遇到的问到,防抖节流,深拷贝,浅拷贝,盒子模型,作用域,闭包,浏览器...

    Front-end-MindMap-Code:前端知识总结(思维导图+代码)

    内容以《JavaScript高级程序设计》为基础,包括基本语法、数据类型、变量和作用域、面向对象、函数表达式、DOM、BOM、事件等 03-JavaScript进阶 内容以《JavaScript高级程序设计》、《ES6入门教程》和各个前端框架...

    my-blog:使用VuePress构建的博客

    作用域、作用域链015.Reflect016.Proxy017.void018.函数柯里化019.bind、apply、call020.cookie、session、token进阶node001....

Global site tag (gtag.js) - Google Analytics