作用域面试题
01_作用域面试题一
var n = 100;
function foo() {
// 本级作用域中找不到定义的n 去父级作用域中寻找
n = 200;
}
foo();
// 200
console.log(n);
02_作用域面试二
function foo() {
// 在编译阶段会编译整个函数作用域 会发现作用域里面定义n 则给n赋值为undefined 然后按代码顺序执行
console.log(n); //undefined
var n = 200;
console.log(n); //200
}
var n = 100;
foo();
03_作用域面试三
var n = 100;
function foo1() {
//函数的作用域是由作用域链的,本级别找不到向父级寻找,一层层寻找,找不到最终报错
//函数的父级 作用域是和函数本身定义的位置有关,和函数调用的位置无关
// 这里函数的父级作用域是全局
console.log(n); //100
}
function foo2() {
var n = 200;
console.log(n); //200
//函数的作用域是由作用域链的,本级别找不到向父级寻找,一层层寻找,找不到最终报错
//函数的父级 作用域是和函数本身定义的位置有关,和函数调用的位置无关
foo1();
}
foo2();
console.log(n); //100
04_作用域面试四
var a = 100;
function foo() {
// 函数在编译期间 会编译整个作用域 但并不执行 所以return后面的也会编译 不会执行 ,编译完成在执行函数
// 所以这函数作用域里面是有定义变量n的 在编译期间为undefined
console.log(a);
return;
var a = 200;
}
foo();
05_作用域补充
function foo() {
// 函数作用域里面 没有定义类型直接写会被定义成全局 依然存在可以被打印出来,虽然实现了,但其实算是一个语法错误
var n = 100;
m = 100;
}
foo();
console.log(m);
// m = 100
console.log(n); //GO访问不到AO里面的值 说人话就是全局作用域访问不到局部作用域的值
06_作用域面试五
function foo() {
var a = (b = 10);
// =》转成下面的两行代码
// var a = 10 //AO的作用域==foo的作用域
// b = 10 //GO作用域 全局
}
foo();
console.log(a); //报错
console.log(b); //10
07_作用域面试六
var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a.x);
console.log(b);
// 结果
// undefined
// { n: 1, x: { n: 2 } }
// 原理
// 第一行 a = { n: 1 }; 给变量a 赋值一个引用对象{ n: 1 };
// 第二行 b = a; 将a的引用地址赋值给 b b={ n: 1 };
// 第三行 a.x = a = { n: 2 }; 拆解 之后 a = { n: 2 } a重写了引用地址 而 a.x = { n: 2 };相当于在a变量中添加一个属性x 并给x属性赋值为{ n: 2 };
// 第四行 a.x因为 a重写了引用地址 里面a没有属性x所以为undefined
// 第五行 由于第二行b = a;a和b同一个地址然后又在a中添加一个属性x 并给x属性赋值为{ n: 2 } 所以b的值为// { n: 1, x: { n: 2 } }
// 注意点 对a.x=a={n:1},赋值语句一般都是从右向左赋值,但是这里涉及到了赋值运算符优先级的问题,我们再看一下js中的运算符的优先级
// 我们可以看到“.”的优先级是要大于“=”的,因此先执行a.x,这是属性赋值(不了解的小伙伴可以先去看一下js的属性),在内存中是这样的,因为x声明未定义,所以是undefined。