最近看了一些解释js词法作用域的文章,于是有一个问题
//静态作用域测试 1
var finn = function() {
var x = {
a: "a",
b: "b"
};
queen(function() {
x.a = "c";
console.log(x.a);
})
};
var queen = function(callback) {
callback()
};
finn();
//静态作用域测试 2
var finn = function() {
var x = {
a: "a",
b: "b"
};
queen()
};
var queen = function() {
x.a = "c";
console.log(x.a);
};
finn();
这里测试一的结果是打出“c”,测试二的结果是x undefined,用静态作用域来解释是可以行的通的,函数的作用域在被定义时已经确定,所以1有值,2无值。 这里想要问的是对于测试1中,
queen(function(){
x.a="c";
console.log(x.a);
})
是否等价于
var qop = function(){
x.a="c";
console.log(x.a);
};
queen(qop);
下面这种方式可以比较直观的看出,该匿名函数的声明位置在finn内部,所以它的作用域链上有finn的变量作用域
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
对于函数表达式的情况,你完全可以把这个函数当成一个值,所以
和
基本等价,同理
和
也就是基本等价。
为什么说是基本等价……因为有一个变量定义的区别。
对于作用域的理解,以 C 语系的语言中,基本上都可以用
{}的范围来理解,只不过 C/C++ 中存在局部变量即时销毁的问题,而 JavaScript 的var变量作用域不是按块范围,而是按function() {}范围的。ES6 的let变量就是块范围了。所以,要看一个函数有没有权限访问一个
var变量,只需要看访问这个var变量的语句是不是在定义var变量的那个 function 的大括号内部即可。我们只需要说
x这个对象的作用域就可以了,函数A内变量的作用域是可以延伸到函数的子函数内的,但是子函数需要在函数A里面定义,这是不是解释了测试2为什么访问不到x了?对于一,你用x只是作为queen的参数,有什么理由访问不到呢?依照题主结尾的疑问
片段1
片段2
这两个片段是等价的。内部函数所能访问的外部作用域,确实取决与它在定义时的位置(或者说,函数体的位置),而该内部函数的内部定义的变量,也只能在该内部函数及该内部函数的内部函数可访问。
哇,说到作用域居然没提到this,感觉有点幸福。。。
首先作用域,就是js搞事的地方,一般来说那些概念性的东西我记不来,我主要记住是下面这种形式:
就像正则匹配一样,见到形如
function开头存在{}的语句,大括号里面就是一个作用域。(有关于json对象的内部是否属于作用域,这个我也是有点疑惑的,望有大神解答正如上面的代码,子作用域可以访问父作用域的变量和函数,但是父作用域不能访问子作用域的变量和函数。然后是作用域B和作用域C不能相互访问。。。你可以这样理解:作用域是函数的老婆,儿子可以亲妈妈对吧,但是父亲不能亲儿媳妇,弟弟也不能亲嫂子,这样家庭就会出问题(我他妈都在说什么。。。)
那好,回到你的代码,首先是测试1,我们看看作用域的结构是怎么样的:
然后是测试2的: