阅读 242

JavaScript学习系列之词法作用域和动态作用域

第一次看到「词法作用域」和「动态作用域」这两个名词我是有点懵的,之前只知道:全局作用域、函数作用域、块级作用域,一度以为是新出来的概念。

词法作用域等同于静态作用域,被创建时就确定好了,也就是说我们写好代码时 TA 的作用域就确定了,JavaScript 遵循的就是词法作用域。

而动态作用域是在被调用时才会确定的。二者关注的点不一样,一个关注何时创建,一个关注何时运行。

词法作用域

function m(){
    console.log(a)
}
function n(){
    var a = 97;
    m();
}
var a = 1997;
n()
// 1997
复制代码

运行上面的代码输出的是 1997。

上篇文章说过作用域链,一起来分析上面的代码:函数 m 想输出变量 a 的值,首先会在函数 m 的作用域内找,函数 m 内没有,便向他的上一级作用域查找。

如果是动态作用域,输出的结果应该是 97,而 JavaScript 遵循的是词法作用域,所以我们得到的结果是 1997。

this 实现「动态作用域」

this 是 JavaScript 中的关键字,TA 能实现类似于动态作用域的效果。 函数运行时其内部自动生成 this 对象,TA 只能在函数内部使用。 this 的指向不是固定不变的,TA 会随着执行环境的改变而改变。

开始我一度以为 this 是指向 window,应该有很多和我一样想法的读者,运行下面的代码就能发现并不是我们想的那样:

var obj = {
    m: function m(){
           console.log(this.msunh)
       },
    msunh : 97
}
var msunh = 1997;
var n = obj.m;
obj.m()    // 97
n() //1997
复制代码

如果都指向 window,输出的结果应该都是 1997,然而实际结果却不一样。 这是因为 this 是指向的是函数运行时所在的环境,并不是全局对象 window,只是很多使用场景都会指向 window。 拿 obj.m() 来说,m() 运行在 obj 环境,所以 this 指向 obj;对于 n(),TA 运行在全局环境中,所以 this 指向全局环境 window,这就是造成 TA 们结果不一样的原因。

严格模式下"use strict"

this 在不同的使用场合,指向的对象不一样。

1、严格模式下,this 将保持进入执行环境时的值,下面的 this 会默认为 undefined。
function m(){
    "use strict";
    return this;
}
m()    //  undefined
2、无论是否在严格模式下,全局执行环境中 this 都指向全局对象 window。
3、函数作为对象里的方法被调用时,this 指向调用该方法的对象。
4、call() 和 apply() 方法可以将 this 指向特定的对象。
复制代码
文章分类
阅读
文章标签