JavaScript作用域链(面试题)
Published on Jan 08, 2023, with 22 view(s) and 0 comment(s)
Ai 摘要:本文通过多个JavaScript代码示例解析了作用域链的核心概念。关键点包括:函数作用域由定义位置决定而非调用位置(如p1打印全局变量);变量提升导致未赋值前输出undefined(p3、p5);全局变量可被函数修改(p2);链式作用域访问规则(p4显示外层变量);以及隐式全局变量声明(p6中未var的b成为全局变量)。这些案例揭示了JavaScript静态作用域特性及编译/执行阶段的处理机制。

问:打印?

p1

var message = "hello global";

function foo() {
  console.log(message);
}

function bar() {
  var message = "hello bar";
  foo();
}

bar();

// "hello global"

因为在编译的时候foo函数对象的父级作用域已经确定。

p2

var n = 100;

function foo() {
  n = 200;
}
foo();

console.log(n);
// 200

p3

function foo() {
  console.log(n);
  var n = 200;
  console.log(n);
}
var n = 100;
foo();
// undefined 200

执行函数上下文foo之前先编译该函数对象 ,因为还没有进行执行,所以AO对象里的n是undefined。 接着开始执行foo函数,在该函数作用域里先打印n,再赋值n,所以第一个n是undefined

p4

var n = 100;

function foo1() {
  console.log(n); // 2, 100
}

function foo2() {
  var n = 200;
  console.log(n); // 1, 200
  foo1();
}

foo2();
console.log(n); // 3, 100

p5

var a = 100;

function foo() {
  console.log(a);
  return;
  var a = 100;
}

foo();
//undefined

和p3类似

p6

function foo() {
  var a = b = 100;
}
foo();
// console.log(a);  // error: a is not defined
console.log(b); //100

var a = (b = 100);(从右向左) 会转化为  var a = 10;  b = 10;因为js中直接对一个没有定义的值赋值,会提到全局对象里,但是在其他语言中是错误的语法