2018web前端面试题总结 (3)

二、什么是闭包和原型链
内部函数可以访问定义他们外部函数的参数和变量。(作用域链的向上查找,把外围的作用域中的变量值存储在内存中而不是在函数调用完毕后销毁)设计私有的方法和变量,避免全局变量的污染
函数嵌套函数
本质是将函数内部和外部连接起来。优点是可以读取函数内部的变量,让这些变量的值始终保存在内存中,不会在函数被调用之后自动清除
闭包的缺陷:
1.闭包的缺点就是常驻内存会增大内存使用量,并且使用不当容易造成内存泄漏
2.如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。


内存溢出和内存泄漏(给的不够用| 用了不归还)
内存溢出:在程序中申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出
内存泄漏:在程序申请内存后,无法释放已申请的内存空间,一次内存泄漏危害可以忽略,但内存泄漏堆积后果很严重,无论多少内存,迟到会被占光

举列子:闭包中的this,对象函数。匿名函数返回函数return function

作用域:(由当前环境与上层环境一系列的变量对象组成!!!保证 当先执行环境里,有权访问的变量和函数是有序的,作用域链变量只能被向上访问)
定义:由当前环境与上层环境的一系列变量对象组成(函数嵌套函数,内部一级级往上有序访问变量或对象)
作用是:保证当前执行环境里,有权访问的变量和函数时有序的,作用域链的变量只能被向上访问
变量访问到window对象及被终止,作用域链向下访问是不允许的
1.改变作用域有 with try..中的catch,
2.所有为定义的直接赋值的变量自动声明为全局作用域

作用域:一套规则,管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称
查找变量(标识符就是变量或者函数名)(只用全局作用域和局部作用域)(作用域在它创建的时候就存在了)

代码执行分为两个阶段:
1.代码编译阶段:有编译器完成,将代码翻译可执行的代码,这个阶段会被确定
2.代码执行阶段:有js引擎完成,主要执行可执行的大妈,这个阶段执行上下文被创建(对象被创建)

执行上下文:一个看不见得对象,存在若干个属性和变量,它被调用的时候创建的。函数被调用查看的this指向的object,object就是上下文(只有被调用的时候创建)

作用域链: https://blog.csdn.net/yooungt13/article/details/20581635
· 当代码在一个环境中执行时,会创建变量对象的一个作用域链,
举例子:var name ="Tom"
function sayHi () {
alert('Hi,'+name)
}
sayHi() //Hi, Tom
函数sayHi()的执行环境为全局环境,所以它的变量对象为window。当函数执行到name时,先查找局部环境,找到则换回,否则顺着作用域查找,在全局环境中,
找到name返回,这一查找变量的有序过程的依据就是作用域。

· 作用域链是保证执行环境有权访问的所有变量和函数的有序访问

原型链:函数的原型链对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针_proto_,
该指针是指向上一层的原型对象,而上一层的原型对象的结构依然类似。因此可以利用_proto_一直指向Object的原型对象上,而Object
原型对象用Object.prototype._proto_ = null表示原型链顶端。如此形成了js的原型链继承。同时所有的js对象都有Object的基本防范

三、类的创建和继承
(es5)new 一个function,在这个function的prototype里增加属性和方法, 类里面有方法和属性
(es6)中class, extends
继承:
原型链继承: function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; 无法实现多继承
构造继承: 使用父类的构造函数来增强子类实例。function Cat(name){Animal.call(this);this.name = name || 'Tom';} 无法继承父类原型链上的属性跟方法 installof去检验
实例继承: 为父类实例添加新特性,作为子类实例的返回
拷贝继承: 拷贝父类元素上的属性跟方法
组合继承:构造继承 + 原型继承的组合体
寄生组合继承:通过寄生方式,在构造继承上加一个Super函数(没有实例和方法) 让他的原型链指向父类的原型链
砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性
如何判断是那种类型

四、异步回调(如何解决回调地狱)
promise、generator、async/await

promise: 1.是一个对象,用来传递异步操作的信息。代表着某个未来才会知道结果的时间,并未这个事件提供统一的api,供进异步处理
2.有了这个对象,就可以让异步操作以同步的操作的流程来表达出来,避免层层嵌套的回调地狱
3.promise代表一个异步状态,有三个状态pending(进行中),Resolve(以完成),Reject(失败)
4.一旦状态改变,就不会在变。任何时候都可以得到结果。从进行中变为以完成或者失败
promise.all() 里面状态都改变,那就会输出,得到一个数组
promise.race() 里面只有一个状态变为rejected或者fulfilled即输出
promis.finally()不管指定不管Promise对象最后状态如何,都会执行的操作(本质上还是then方法的特例)

五、前端事件流
事件流描述的是从页面中接受事件的顺序,事件 捕获阶段 处于目标阶段 事件冒泡阶段 addeventListener 最后这个布尔值参数如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
1、事件捕获阶段:实际目标div在捕获阶段不会接受事件,也就是在捕获阶段,事件从document到<html>再到<body>就停止了。
2、处于目标阶段:事件在div发生并处理,但是事件处理会被看成是冒泡阶段的一部分。
3、冒泡阶段:事件又传播回文档
阻止冒泡事件event.stopPropagation()
function stopBubble(e) {
if (e && e.stopPropagation) { // 如果提供了事件对象event 这说明不是IE浏览器
e.stopPropagation()
} else {
window.event.cancelBubble = true //IE方式阻止冒泡
}
}
阻止默认行为event.preventDefault()
function stopDefault(e) {
if (e && e.preventDefault) {
e.preventDefault()
} else {
// IE浏览器阻止函数器默认动作的行为

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjfsg.html