zoukankan      html  css  js  c++  java
  • JS基础——作用域与闭包

    前言

    JS 作用域

    整理到了作用域上和闭包

    Javascript 变量的作用域无非就是两种:全局变量和局部变量。Javascript 语言的特殊之处,就在于函数内部可以直接读取全局变量

    全局作用域(Global Scope)

    在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域

    1.最外层函数和在最外层函数外面定义的变量拥有全局作用域

    var name = 'Jack' // 全局定义
    function foo() {
      var age = 23 // 局部定义
      function inner() {
        // 局部函数
        console.log(age) //age 23
      }
      inner()
    }
    
    console.log(name) // jack
    console.log(age) // Uncaught ReferenceError: age is not defined,在外部没有这个变量
    foo() // 内嵌函数的打印23
    inner() // Uncaught ReferenceError: inner is not defined 因为内嵌函数,找不到这个函数

    2.所有末定义直接赋值的变量自动声明为拥有全局作用域

    var name = 'yuan'
    function foo() {
      age = 23 // 全局定义
      var sex = 'male' // 局部定义
    }
    foo()
    console.log(age) //  23
    console.log(sex) // sex is not defined

    3.所有 window 对象的属性拥有全局作用域 一般情况下,

    window 对象的内置属性都都拥有全局作用域,例如 window.alert()、window.location、window.top 等等。

    内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数。

    闭包是js开发惯用的技巧,什么是闭包?

    闭包指的是:能够访问另一个函数作用域的变量的函数。清晰的讲:闭包就是一个函数,这个函数能够访问其他函数的作用域中的变量。

    函数没有被释放,整条作用域链上的局部变量都将得到保留。

    由于在 javascript 语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”

    闭包的应用

    1. 设计私有的方法和变量。 任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。私有变量包括函数的参数、局部变量和函数内定义的其他函数。把有权访问私有变量的公有方法称为特权方法(privileged method)
    function fn() {
      var a = 1,
        b = 2
    
      function f1() {
        return a + b
      }
      return f1
    }

    上面例子中的 f1 就是一个闭包

    闭包的应用

    1.匿名函数最大的用途是创建闭包。减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染。

    var objEvent = objEvent || {}
    (function() {
      var addEvent = function() {
        // some code
      }
      function removeEvent() {
        // some code
      }
    
      objEvent.addEvent = addEvent
      objEvent.removeEvent = removeEvent
    })()

    addEvent 和 removeEvent 都是局部变量,但我们可以通过全局变量 objEvent 使用它,

    这就大大减少了全局变量的使用,增强了网页的安全性。

    2.用闭包模仿块级作用域
    es6没出来之前,用var定义变量存在变量提升问题,

    for(var i=0; i<10; i++){
        console.info(i)
    }
    alert(i)  // 变量提升,弹出10
    
    //为了避免i的提升可以这样做
    (function () {
        for(var i=0; i<10; i++){
             console.info(i)
        }
    })()
    alert(i)   // underfined   因为i随着闭包函数的退出,执行环境销毁,变量回收

    使用闭包的注意点

      由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,

       在 IE 中可能导致内存泄露。解决方法时,在退出函数之前,将不使用的局部变量全部删除。

    function makeAdder(x) {
      return function(y) {
        return x + y
      }
    }
    
    var add5 = makeAdder(5)
    var add10 = makeAdder(10)
    
    console.log(add5(2)) // 7
    console.log(add10(2)) // 12
    
    // 释放对闭包的引用
    add5 = null
    add10 = null

    add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的环境。

    在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。最后通过 null 释放了 add5 和 add10 对闭包的引用。

    闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,

    把闭包当作它的公用方法,把内部变量当作它的私有属性,这时一定要小心,不要随便改变父函数内部变量的值。

  • 相关阅读:
    composer 版本号前置~与^符号的区别
    阿里巴巴离线数据同步工具/平台datax安装、使用笔记
    LAMP集成环境搭建
    MySQL在Windows中设置环境变量
    jQuery 事件
    jQuery 属性,元素
    jQuery 选择器
    JavaScript 动画
    JavaScript BOM-三剑客
    JavaScript BOM-对象
  • 原文地址:https://www.cnblogs.com/yf-html/p/12366116.html
Copyright © 2011-2022 走看看