zoukankan      html  css  js  c++  java
  • JS作用域和作用域链

    作用域和作用域链

    作用域:

    函数执行会形成一个私有作用域(栈内存),为代码执行提供一个环境

    闭包

    • 形成一个私有作用域,使里面的私有变量不受外部影响
    • 函数执行,有一个地方可以把变量存储起来,以后想要使用的时候可以拿出来

    全局变量

    全局对象是最顶层的对象,在浏览器环境指的是window对象。在ES5中,全局对象的属性与全局变量是等价的。

    私有变量

    在私有作用域中,只有一下两种情况是私有变量

    • 声明过的变量(带VAR/FUNCTION)
    • 形参也是私有变量
      剩下的都不是自己私有变量,都需要基于作用域链的机制向上查找
    var a = 12, b = 13, c = 14;
    function fn(a){
        console.log(a, b, c);
        var b = c = a = 20;
        console.log(a, b, c);
    }
    fn(a);
    console.log(a, b, c);
    

    -> 12,undefined,14
    -> 20,20,20
    ->12,13,20

    fn(a)中: a(形参),b(VAR定义)为私有变量,a,b的改变不影响外部的a,b。c为外部变量,c改变会影响到全局下的c也改变

    暂时性死区

    基于LET创建变量,会把大部分{}当做一个私有作用域(类似函数的私有作用域),在这里也是重新检查语法规范,看一下是否是基于新语法创建的变量,如果是按照新语法规范来解析

    var a = 12;
    if(true){
        console.log(a);
        let a = 13;
    }
    

    -> Uncaught ReferenceError: a is not defined

    使用LET创建变量,未执行到创建语句时,使用变量会报错。

    在原有浏览器渲染机制下,基于typeof等逻辑运算符检测一个未被声明过的变量,不会报错,返回undefined

    console.log(typeof a);
    

    -> undefined

    如果当前变量是基于ES6语法处理,在没有声明这个变量的时候,使用typeof检测会直接报错,不会是undefined,解决了原有的JS的死区问题

    console.log(typeof a);
    let a = 12;
    

    -> ReferenceError: Cannot access 'a' before initialization,无法在初始化之前访问’a‘

    作用域链查找

    当前函数执行,形成一个私有作用域A,A的上级作用域是谁,和他在哪创建(定义)的有关系,在哪创建,他的上级作用域就是谁。

    var num = 12;
    function fn(){
        var num = 120;
        return function(){
            console.log(num);
        }
    }
    var f = fn();
    f();
    
    function(){
        var num = 1200;
        f():
    }()
    

    -> 120
    -> 120

    ARGUMENTS

    arguments:参数集合
    arguments.callee:函数本身
    arguments.callee.caller:当前函数在哪执行,caller就是谁(记录的是他执行的宿主环境),在全局下执行CALLER的结果是null

  • 相关阅读:
    Ural 1741 Communication Fiend(隐式图+虚拟节点最短路)
    OpenCV学习笔记——多种Smooth平滑处理
    HDU 1025 Constructing Roads In JGShining's Kingdom(二维LIS)
    POJ 2533 Longest Ordered Subsequence(LIS模版题)
    NBUT 1186 Get the Width(DFS求树的宽度,水题)
    Codeforeces 617E XOR and Favorite Number(莫队+小技巧)
    CodeBlocks的汉化、主题美化及其调试功能的实现
    PAT天梯赛练习题 L3-010. 是否完全二叉搜索树(完全二叉树的判断)
    POJ 2892 Tunnel Warfare(线段树单点更新区间合并)
    HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13637553.html
Copyright © 2011-2022 走看看