关于前端面试的几个知识点
程序员文章站
2022-03-07 18:44:31
...
1. 函数作用域
1.1 作用域分为全局作用域和局部作用域
全局作用域,对任何函数内部都可以访问,例如:
var a = 'hello';
function f1(){
console.log(a);
}
f1(); // hello
局部作用域,只有函数内部可以访问到,例如:
var a = 'hello';
function f2(){
var b = 'world';
}
console.log(b);
f2(); //Uncaught ReferenceError: b is not defined
如果在函数作用域里不用var定义变量的话,就会定义出全局变量:
function f3(){
inner = 'inner';
}
f3();
console.log(`in: ${inner}`); //in: inner
与此相关的点还有变量提升等;
1.2 作用域链于执行上下文
在红宝书中对作用域链的描述有这么一段话:当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端始终是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象。作用域链的下一个变量对象来自包含环境,而在下一个变量对象则来自下一个包含环境。这样一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。
1.3 闭包
一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象)。
但闭包不同,他让你可以在函数内部访问到另一个函数内部的局部变量;
引用知乎上一个例子:
(function(){
var hello="hello,world";
function welcome(hi){
alert(hi); //解析到作用域链的第一个对象的属性
alert(hello); //解析到作用域链的第二个对象的属性
}
welcome("It's easy");
})();
作者:大水
链接:https://www.zhihu.com/question/34547104/answer/59515735
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
IIFE中welcome定义的时候产生一个作用域链,是一个对象,该对象是个集合对象。
第一个子对象是引用welcome的参数和局部变量;第二个子对象是外层函数的参数和局部变量;第三个就是全局对象,也就是window。
在变量解析的过程中,在作用域链中一个个往上层找,也就成了我们的闭包。
2. 原型链和原型
引用一张图,看懂能绘出就ok了
注释:
prototype 显式原型
__proto__ 隐藏原型
- __proto__ 是每一个对象都有的一个属性,prototype是每一个函数才会有的属性,但函数也是对象,所以实例化的对象和实例化该对象的构造函数都用__proto__隐式原型,但构造韩式又拥有prototype显式原型;
- 对象的隐式原型属性指向构造该对象的构造函数的显式原型;
3. 异步和单线程
https://www.cnblogs.com/woodyblog/p/6061671.html