【1期】作用域链干货梳理,配套面试题练习

注:本文仅总结本人觉得相关容易混淆的点,关于作用域链完整的描述网上很容易找到大量资源哈。

        末尾附有相关易错练习题,有兴趣可以一起探讨解题思路

1.编译原理 :

分词/词法分析, 解析/语法分析, 代码生成

2.JS执行:

引擎, 编译器, 作用域

3.词法作用域(静态作用域):

无论函数在哪里被调用,也无论他如何被调用,他的词法作用域只由函数被声明位置决定。

两个欺骗行为:eval(), with()  //可在代码动态执行时修改或新增作用域;降低性能

4.作用域链(Scope Chain):

就是根据名称查找变量(标识符名称)的一套规则。

规则非常简单,在自己的变量对象里找不到变量,就上父级的变量对象查找,当抵达最外层的全局上下文中,无论找到还是没找到,查找过程都会停止。查找会在找到第一个匹配的变量时停止,被称为遮蔽效应

5.执行环境(也称执行环境)堆栈:

执行上下文定义了变量或函数有权访问的其他数据,决定了它们各自的行为。而在javascript中有三种执行上下文: 全局执行上下文, 函数执行上下文, eval执行上下文

一个函数可能会产生无限上下文集合,因为每次函数调用自身都会产生一个新的执行上下文

每个函数运行时都会产生一个执行环境,js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中。 

//全局执行环境是最外围的执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都作为window对象的属性和方法创建的。

js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。

js函数内的变量值不是在编译的时候就确定的,而是等在运行时期再去寻找的。

5.1 执行上下文

每个执行上下文可以抽象成一个对象,都包含了一组属性。

image.png

注意:隐式劫持(let)

delete 不能删除var/let/const声明的变量。其实,用delete window.vb 的方式也不能删除(var 声明的变量configurable为false; 直接声明的变量为true)

练习题:

//---------------- 题目一 --------------------
inner = 'window';
function say() { 
   console.log(inner);
   console.log(this.inner);
}
var obj1 = (function() {
  var inner = '1-1';
  return {// TODO 1
     inner: '1-2',
     say: function() {
       console.log(inner);
       console.log(this.inner);
     }
   }
})();
/var obj2 = (function() {
    var inner = '2-1';
    return {
       inner: '2-2',
       say: function() {
           console.log(inner);
            console.log(this.inner);
        }
    }
})();
say();
obj1.say();
obj2.say();
obj1.say = say;
obj1.say();
obj1.say = obj2.say;
obj1.say();

//---------------- 题目二 --------------------
var scope = 'global';
function t() {
 console.log(scope);
 var scope = 'local';
 console.log(scope)
}
t()

//---------------- 题目三 --------------------
var name = 1; 
sex = 'girl';
delete name;
delete sex;
console.log(name)
console.log(sex)

//---------------- 题目四 --------------------

// with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部.with语句结束后,作用域链恢复正常。

//---------------- 题目五 --------------------
*inner = 'window';
function say() {
console.log(inner);
console.log(this.inner);
}
var obj1 = (function() {
var inner = '1-1';
return {// TODO 1
inner: '1-2',
say: function() {
console.log(inner);
console.log(this.inner);
}
}
})();
var obj2 = (function() {
var inner = '2-1';
return {// TODO 2
inner: '2-2',
say: function() {
console.log(inner);
console.log(this.inner);
}
}
})();
say();
obj1.say();
obj2.say();
obj1.say = say;
obj1.say();
obj1.say = obj2.say;
obj1.say();

//---------------- 题目六 --------------------
var a = 1; 
function f()
a =10;
return;
function a() {
}
}
f();
console.log(a);
var a = [1];
var b = a;
a.push(2);
var c = 1;
var d = c;
c =2;
console.log(b);

//---------------- 题目六 --------------------
function f1(){
   return this;
}
f1() === window;

//---------------- 题目七 --------------------
var foo = 10;
function bar(){};
(function baz(){})
console.log(baz);

猜你喜欢

转载自blog.csdn.net/m0_38073011/article/details/108450273