JavaScript深切系列的第二篇,JavaScript采纳词法作用域,什么言语采纳了动态作用域?二者的区分又是什么?另有一个略难的思索题,快来看看吧。
作用域
作用域是指顺序源代码中定义变量的地区。
作用域划定了怎样查找变量,也就是肯定当前实行代码对变量的接见权限。
JavaScript 采纳词法作用域(lexical scoping),也就是静态作用域。
静态作用域与动态作用域
由于 JavaScript 采纳的是词法作用域,函数的作用域在函数定义的时刻就决议了。
而与词法作用域相对的是动态作用域,函数的作用域是在函数挪用的时刻才决议的。
让我们仔细看个例子就能够邃晓之间的区分:
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
// 效果是 ???
假定JavaScript采纳静态作用域,让我们剖析下实行历程:
实行 foo 函数,先从 foo 函数内部查找是不是有局部变量 value,假如没有,就依据誊写的位置,查找上面一层的代码,也就是 value 即是 1,所以效果会打印 1。
假定JavaScript采纳动态作用域,让我们剖析下实行历程:
实行 foo 函数,依旧是从 foo 函数内部查找是不是有局部变量 value。假如没有,就从挪用函数的作用域,也就是 bar 函数内部查找 value 变量,所以效果会打印 2。
前面我们已说了,JavaScript采纳的是静态作用域,所以这个例子的效果是 1。
动态作用域
或许你会猎奇什么言语是动态作用域?
bash 就是动态作用域,不信的话,把下面的剧本存成比方 scope.bash,然后进入响应的目次,用命令行实行 bash ./scope.bash
,看看打印的值是多少。
value=1
function foo () {
echo $value;
}
function bar () {
local value=2;
foo;
}
bar
这个文件也能够在github博客堆栈中找到。
思索题
末了,让我们看一个《JavaScript威望指南》中的例子:
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
猜猜两段代码各自的实行效果是多少?
这里直接通知人人效果,两段代码都邑打印:local scope
。
缘由也很简单,由于JavaScript采纳的是词法作用域,函数的作用域基于函数建立的位置。
而援用《JavaScript威望指南》的回复就是:
JavaScript 函数的实行用到了作用域链,这个作用域链是在函数定义的时刻建立的。嵌套的函数 f() 定义在这个作用域链里,个中的变量 scope 一定是局部变量,不论何时何地实行函数 f(),这类绑定在实行 f() 时依旧有用。
然则在这里真正想让人人思索的是:
虽然两段代码实行的效果一样,然则两段代码终究有哪些差别呢?
假如要回复这个题目,就要牵涉到许多的内容,词法作用域只是个中的一小部分,让我们期待下一篇文章————《JavaScript深切之实行上下文栈》。
下一篇文章
深切系列
JavaScript深切系列目次地点:https://github.com/mqyqingfeng/Blog。
JavaScript深切系列估计写十五篇摆布,旨在帮人人捋顺JavaScript底层学问,重点解说如原型、作用域、实行上下文、变量对象、this、闭包、按值通报、call、apply、bind、new、继续等难点观点。
假如有毛病或许不严谨的处所,请务必赋予斧正,非常谢谢。假如喜好或许有所启示,迎接star,对作者也是一种勉励。