一、谈谈对js执行上下文的理解
执行上下文就是指在js运行环境中,代码如何访问变量、函数以及确定this指向等情况。执行上下文总的来说分为全局执行上下文、函数执行上下文、块级执行上下文。
- 全局执行上下文由js引擎默认创建。
- 函数执行上下文是每当一个函数被创建的时候,就会生成一个新的函数执行上下文。
- 块级执行上下文当一段代码由{}包住、且有let、const声明变量时,就会生成一个块级执行上下文。
应用场景:作用域、程序执行等
二、作用域与作用域链的理解
作用域的作用是为了隔离变量,作用域决定了变量的可访问性和生命周期,作用域分为全局作用、局部作用域和块级作用域。
- 全局作用域是js最外层的作用域,里面的变量能够在任何地方被访问,所有window对象的属性用于全局作用域。注意全局变量会导致全局命名空间污染,容易引发命名冲突。
- 局部作用域是指在函数内部定义的作用域,一般只在固定代码段内可以访问到,一般应用于函数内部的声明。
- 块级作用域是通过let、const声明,声明的变量只在块级中访问。
作用域链是由多个作用域按照特定的规则连接成的一条链式结构。变量取值在创建这个变量的函数作用域中取值,如果当前作用域没有就上上一级作用域查找,在查找过程中形成的链条,就叫作用域链。
三、谈谈对闭包的理解
闭包就是一个函数访问了它的父级以及父级以上的变量,这种情况就是闭包。它的作用是访问函数内部变量,让变量保存在内存中,注意:闭包中的变量是驻留内存的。
闭包形成的条件
- 函数嵌套
- 内部函数引用了外部函数的变量
闭包的优越点
- 优点:可以减少全局变量的定义,减少全局污染,能够读取函数内部的变量,内存中驻留可以当缓存使用。
- 缺点:可能会造成内存泄漏,闭包涉及到跨作用域可能会造成性能下降,尽量把变量设置为局部变量。
应用场景:数据的访问限制的时候可以使用闭包,防抖节流、数据隐藏和封装、回调函数和异步操作
四、原型与原型链的理解
原型
每个js对象创建,同时就会创建一个原型对象,js对象会继承原型对象的内容。每个函数都一个原型对象,这个原型对象包含了可以被该函数创建的所有实例对象共享的属性和方法,原型分为显示原型和隐式原型。
- 显示原型:prototype,创建对象的时候被创建,proptype指向函数的原型对象,属于一个地址的引用。
- 隐式原型:proto ,指向对于构造函数的原型对象。
原型的作用
实现对象之间的属性和方法的共享,节省资源。
原型链
当我们在一个实例对象上访问一个属性或方法时,如果在该实例对象本身找不到,就会沿着原型链依次向上查找,直到找到目标属性或方法或者到达原型链的顶端(Object.prototype)。实例对象都有_proto_,proto 属性指向构造函数的原型对象,原型对象中有一个_proto_属性,层层往上,直到Object.prototype结束。 原型链是实现继承的一种主要方式。
五、this指向问题
this是一个指针变量,动态指向当前函数的运行环境,指向其所在函数的真实调用者。
- 全局环境下的this指向—— 指向window对象
- 函数内部的this指向—— 指向window对象
- 对象中的this指向—— 一层对象this谁调用,指向谁,二层以上对象this指向调用函数的对象,在多层调用中,那个对象离this近,this就指向谁。
- 箭头函数中的this指向—— 没有this和argument,只能捕捉外层的执行环境,并继承该外层的this
- 构造函数中的this指向—— 指向实例化对象
注意:在js继承机制中,this指向的是构造函数创建的实例,而非原型链