JavaScript基础:作用域、作用域链和闭包

2018-11-28  本文已影响4人  三年级一班亚索

作用域的理解

JavaScript的作用域有两种:全局变量和局部变量。不过有一点需要注意,在类C编程语言中,花括号内的每一段代码都各有自的作用域,而且变量在声明外是不可见的,称之为块级作用域。而JS没有块级作用域。下面代码块内的a对于外部是可见的

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

output: 1

代码没有在函数内声明便是全局变量,否则为局部变量,还有一种情况是imply global,后面会说。不过,有一点要注意,在JS中会有预处理,它会把声明提前。比如:

console.log(a);

output:报错

console.log(a);
var a = 1;

output: a is not defined

按理说,因为第一行a没有声明就使用,所以会出现问题。但是,JS解释器会把变量a的声明提前,所以,出现 " a is not defined "。

test();
function test(){
  console.log("hello world");
}

output: hello world

因为他会把test的函数声明提前

作用域链前置知识

imply globe
没有声明的变量就使用为全局变量

function test(){
  var a = b = 123;
}
test();
console.log(a);

output: 错误
这一点不用置疑,因为a是局部变量,但是console.log(b),将输出123。

问题

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

output: [Function: a] 123 123
步骤:

一、创建AO(Activation Object)对象
AO{ }和实参
二、 找出所有的声明
AO{
a: undefined
b: undefined
}
三、 把形参和实参相统一
AO{
a: 1
b: undefined
}
四、最后添加所有函数
AO{
a: 1
b: undefined
}
五、按顺序执行

我们一般都可能觉得第一个输出应该是1,产生这个错误的原因是因为我们忽略了第四步。

练习

function test(a, b) {
  console.log(a);
  c = 0;
  var c;
  a = 3;
  b = 2;
  console.log(b);
  function b(){}
  function d(){}
  console.log(b);
}
test(1);

output: 1 2 2

练习

function test(a, b) {
  console.log(a);
  console.log(b);
  var b = 234;
  console.log(b);
  a = 123;
  console.log(a);
  function a(){}
  var a;
  b = 234;
  var b = function(){}
  console.log(a);
  console.log(b);
}
test(1)

output: [Function: a] undefine 234 123 123 [Function: b]

上一篇 下一篇

猜你喜欢

热点阅读