面试题
1.谈谈你对作用域的理解
- 概念:标识符能够被访问的范围
- 分类
- es5:
- 全局
- 局部(函数)
- es6:
- 全局
- 局部(函数)
- 块级
- es5:
- 作用域链:
- 标识符有序的查找规则
- 自身找=>外层作用域找=>…=>直到window,找不到报错未定义
2.什么是闭包?闭包的作用是什么?
- 跨作用域访问就能形成闭包,函数和被访问的变量就是闭包。
- 标准的闭包写法:
- 父函数嵌套子函数,把子函数返回
- 父函数嵌套子函数,把子函数挂载到window
- 特点:
- 变量会常驻内存,不会被销毁。
- 作用:
- 让变量私有化,避免全局污染
- 场景:
- 结合IIFE, 实现模块化
- 防抖和节流
- 单例模式等
3.使用new关键字创建对象,中间发生了什么?
- 1.创建一个空对象
- 2.this指向这个空对象
- 3.执行构造函数(为对象添加属性)
- 4.返回this(这个对象)
4.请谈谈你对原型和原型链的理解
- 原型
- 每个函数(主要指构造函数)都有一个属性prototype,这个属性指向一个对象,这个对象就是原型。
- 原型上的属性和方法被所有实例共享
- 原型有一个constructor属性,指向构造函数
- 每个实例对象都有一个__proto__属性,指向构造函数的原型
- 原型链
- 原型也是一个对象,也有__proto__属性,指向其构造函数的原型;一层层指下去,就形成了原型链。
- 对象访问属性的规则:先从自身找=>找不到往原型上找=>找不到继续沿着原型链向上找=>直到Object.prototype。
5.es5如何继承
- 1.借用父类构造函数; 父.call(this,参数…)
- 2.让子类构造函数原型的__proto__指向父类原型;子.prototype = Object.create(父.prototype)
- 3.还原子类构造器。子.prototype.constructor = 子
6.ES6有哪些新特性?
- 变量声明let const
- 解构赋值
- 箭头函数&参数默认值
- 对象的简洁写法
- 展开运算符
- 模板字符串
- map和set
- class
- 模块化
- Promise
- async和await等
7.什么是Promise?为什么要使用Promise?
- Promise是用来管理异步操作的,用同步的方式来编写异步代码。Promise有三种状态pending(进行中)、fulfilled(已成功)和rejected(已失败);状态只能从pending变成fulfilled或者rejected且不可逆。
- 使用Promise可以解决地狱回调。让代码看起来像同步。
8.async与await是用来做什么的?如何使用它们?
- 用来做什么
- async与await在ES7中推出,配合Promise,使得编码异步操作更加方便!
- 如何使用
- async关键字写在函数前面,表示该函数中有异步操作
- await只能使用在async修饰的函数中,用于等待异步操作结果(一般等待的是一个Promise的状态改变)
- 步骤:
- 1)await一个异步操作
- 2)拿到结果赋值给变量
- 3)再继续下一个异步操作
9.说说this的7种指向
- 全局 window
- 函数 谁调用指向谁
- 对象属性方法 谁调用指向谁
- 构造函数 实例对象
- 事件绑定 事件源
- 定时器 window
- 箭头函数 上一层作用域
10.使用for循环、forEach()、map()方法都可以遍历一个数组,他们之间有什么区别?
- for循环和forEach一般用来遍历数组,for循环可以被break,forEach不能。
- map方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。不会改变原数组。