美文网首页
关于作用域

关于作用域

作者: 卤蛋皮皮 | 来源:发表于2018-11-20 16:02 被阅读0次

一、作用域链的定义

作用域(scope)指的是变量存在的范围,在ES5的规范中,Javascript只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。

函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。

var v = 1;

function f() {
    console.log(v);
}

f()    // 1

上面的代码表明,函数 f 内部可以读取全局变量 v

在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。

function f() {
    var v = 1;
}

v   //  ReferenceError: v is not defined

上面代码中,变量 v 在函数内部定义,所以是一个局部变量,函数之外就无法读取。

函数内部定义的变量,会在该作用域内覆盖同名全局变量。

var v = 1;

function f() {
    var v = 2;
    console.log(v);
}

f()   //   2
v     //   1

上面代码中,变量 v 同时在函数的外部和内部有定义,结果,在函数内部定义,局部变量 v 覆盖了全局变量 v 。

注意,对于 var 命令来说,局部变量只能在函数内部声明,在其他区块中 声明,一律都是全局变量。

if (true) {
    var x = 5;
}

console.log(x);   //   5

上面代码中,变量 x 在条件判断区块之中声明,结果就是一个全局变量,可以在区块之外读取。

二、函数内部的变量提升

与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var 命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部。

function foo(x) {
    if (x > 100) {
        var tmp = x - 100;
    }
}

// 等同于
function foo(x) {
    var tmp;
    if (x > 100) {
        tmp = x - 100;
    };
}

三、函数本身的作用域

函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,变是其声明时所在的作用域,与其运行时所在的作用域无关。

var a = 1;
var x = function () {
    console.log(a);
};

function f() {
    var a = 2;
    x();
}

f()  //   1

上面代码中,函数 x 是在函数 f 的外部声明的,所以它的作用域绑定外层,内部变量 a 不会到函数 f 体内取值,所以输出 1 ,而不是 2。

总之,函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。
很容易犯错的一点是,如果函数 A 调用函数 B ,去没有考虑到函数 B 不会引用函数 A 的内部变量。

var x = function () {
    console.log(a);
};

function y(f) {
    var a = 2;
    f();
}

y(x)

//   ReferenceError: v is not defined

以上代码将函数 x 作为参数,传入函数 y。但是,函数 x 是在函数 y 体外声明的,作用域绑定外层,因此找不到函数 y 的内部变量 a ,导致报错。

同样的,函数体内部声明的函数,作用域绑定函数体内部。

function foo() {
    var x = 1;
    function bar() {
        console.log(x);
    }
    return bar;
}

var x = 2;
var f = foo();
f()  //   1

上面的代码中,函数 foo 内部声明了一个函数 bar,bar 的作用域绑定 foo。当我们在 foo 外部取出 bar 执行时,变量 x 指向的是 foo 内部的 x ,而不是 foo 外部的 x 。正是这种机制,构成了“闭包”现象。

相关文章

  • 2018-01-07 关于javascript闭包和作用域的理解

    关于 javascript 闭包的一些思考 作用域 词法作用域 函数作用域 块作用域 闭包 什么是作用域? 作用域...

  • 「JS」变量作用域

    作用域介绍静态作用域动态作用域 JavaScript 变量作用域词法环境组成创建结构关于词法环境的问题with 语...

  • js笔记

    1. 关于循环 for( A ) { B };for循环的A和B是两个不同的作用域,B作用域是A作用域的子域,如下...

  • 作用域链

    作用域链 作用域:就近原则在写下声明就能确定的,叫做词法作用域 词法作用域可以确定是哪个a,但不能确定a的值 关于...

  • 理解JavaScript的核心知识点:作用域

    Understanding JavaScript Core: Scope 关于作用域:About Scope 作用...

  • 关于作用域

    一、作用域链的定义 作用域(scope)指的是变量存在的范围,在ES5的规范中,Javascript只有两种作用域...

  • 关于作用域和作用域链

    作用域 在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子...

  • js作用域

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 作用域,作用域链

    1 - 作用域 1.1 作用域概述 全局作用域 局部作用域(函数作用域) 1.2 全局作用域 1.3 局部作用域 ...

  • 变量作用域

    变量作用域:静态作用域、动态作用域JS变量作用域:JS使用静态作用域JS没有块级作用域(全局作用域、函数作用域等)...

网友评论

      本文标题:关于作用域

      本文链接:https://www.haomeiwen.com/subject/ctjxqqtx.html