前端面经之ES6+JS

目录

  • ES6介绍
  • 问题+回答
    • ES6新特性有哪些
    • 什么是闭包
    • 什么是冒泡(不是冒泡排序的冒泡)
    • call,apply,bind是干什么的,有什么区别
    • new做了哪些事
    • 什么是宏任务和微任务,以及以什么顺序执行
    • localStorsge,sessionStorage,cookies的区别
    • filter和find的区别
    • 深拷贝和浅拷贝
    • 堆区和栈区:
    • Document.write和innerHtml的区别:
    • Generator:
    • 类型判断
    • object.is和 === 和 ==的区别

ES6介绍

ES6,ECMAScript 6.0,就是javascript的新标准,属于是这里面的东西好多都用过,但我不知道这是不是ES6的。

问题+回答

ES6新特性有哪些

  1. let和const
  2. class语法糖
  3. symbol数据类型
  4. 箭头函数
  5. 扩展运算符(…)
  6. 生成器(Generator)和遍历器(Iterator)
  7. import/export
  8. 解构赋值
  9. set和map数据类型

什么是闭包

就是定义在函数内部能够读取其他函数内部变量的函数

优点:
	1.保护函数内的变量安全
	2.在内存中维持一个变量(用的太多就变成了缺点,占内存) ;
	3. 逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑。
	4. 方便调用上下文的局部变量。
	5. 加强封装性,可以达到对变量的保护作用。
缺点:
	1.常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
    2.还有有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生。

什么是冒泡(不是冒泡排序的冒泡)

由里往外,比如下面代码中如果不阻止冒泡点击fn2就会触发fn1

<div onclick="fn1">
	<div onclick="fn2">
		xxxxx
	div>
div>

addEventListener的第三个参数就默认是false,不阻止冒泡
相反的由外往里叫捕获

call,apply,bind是干什么的,有什么区别

共同点:
调用函数并改变this指向
区别
fun.call(this指向,函数调用的参数1,函数调用的参数2)
fun.apply(this指向,[函数调用的参数1,函数调用的参数2])第二个参数必须是数组
fun.bind(this指向)(函数调用的参数1,函数调用的参数2) bind不能立即执行,因为它返回的是一个函数,必须要fun.bind()()才能执行
(Bind可以用来改变click事件绑定的函数(不用立即执行))

new做了哪些事

  1. 创建空对象
  2. 执行constructor创建实例
  3. 判断对象是否存在且是对象或者函数
  4. 依据判断结果返回对象或者实例

什么是宏任务和微任务,以及以什么顺序执行

说到宏任务和微任务首先要了解事件循环机制,

事件循环
js是单线程的,但是总要执行一些异步指令,那就只能靠事件循环,可以理解为:
解析js的时候一直循环解析,当遇到 同步代码放入执行队列依次执行,遇到异步代码分为宏任务队列和微任务队列,同步代码执行完先执行 微任务,等微任务队列全部执行完执行 宏任务

**同步代码:**立刻执行的都是同步代码,比如console.log。要注意promise在then前都属于同步代码
微任务:.then,catch,async/await
宏任务: setTimeout等计时器

localStorsge,sessionStorage,cookies的区别

  1. 当浏览器关闭时local还有,session消失
  2. Cookies可以设置过期时间expires
  3. Cookie不能超过4k,storage不能超过5m(浏览器不同存储大小不同

filter和find的区别

filter和find都是不改变原数组的方法,
区别是find返回第一个查找到的元素,filter返回一个满足条件的数组

深拷贝和浅拷贝

首先要介绍一下什么是深拷贝和浅拷贝,

浅拷贝: 学过c语言的都知道指针,指针指向的是地址,而js中的引用数据类型(object,array)存储的就是地址,就可以把它想象成指针,指针赋值说明什么,说明赋值只是存了个地址,那么地址里的值变了,指针指向的内容也会改变,这就是浅拷贝,也就是不够深,不够彻底的拷贝;

深拷贝: 那深拷贝是什么呢,深拷贝就是赋值之后原数据再怎么改都不会影响赋值的数据。

那么哪些赋值方法是深拷贝那些是浅拷贝呢

浅拷贝:
obj1=obj
Object.assign(obj1,obj)
深拷贝:
obj = {a:1,b:2}
obj2 = JSON.parse(JSON.stringify(obj1))

堆区和栈区:

堆区:动态分配的内存,引用数据类型栈区存放的指针指向堆区
栈区:自动分配的内存

Document.write和innerHtml的区别:

document.write只能重绘整个页面,
innerHTML可以重绘页面的一部分

Generator:

Generator函数使用yield+next() 可以返回多次值

function* gen() {
yield 1
yield 2
return 3
yield 4
}
let g = gen();
console.log(g.next()) // {value: 1, done: false}
console.log(g.next()) // {value: 2, done: false}
console.log(g.next()) // {value: 3, done: true}
console.log(g.next()) // {value: undefined, done: true}
可以循环遍历generator,for foo of gen
但是return不会被遍历到也不会被扩展运算符显示到
注意:next里可以放参数,相当于给上一个yield赋值,yield本身结果并不是值,而是undefined,第一个next是没有形参的,给了也没有用

类型判断

	console.log('------------类型判断------------')
    console.log([1,2,3]==[1,2,3])   //false
    console.log({}=={})             //false,里面有也是false        
    //这两种都是引用类型的比较,比较的是指针
    console.log(typeof Number === typeof Window)    //true 都是function
    console.log(typeof window)      //object
    console.log(typeof Number())    //number

	console.log("------------instanceof-----------")
    console.log(2 instanceof Number)  //false ,因为instance只能用来判断引用数据
    console.log([] instanceof Array)  //true
    console.log(function(){} instanceof Function)  //true ,注意这个function的typeof也是function
    // instance运算符原理:判断构造函数的prototype属性是否在对象原型链上的任何位置

    console.log("------------constructor-----------")
    console.log((2).construtor===Number)   //true,注意这里的2外面有括号,因为原始数据类型不能用xxx.constructor

    console.log("------------Object方法-----------")
    var a = Object.prototype.toString
    console.log(a.call(2))          //[object Number]
    console.log(a.call(null))       //[object Null]
    console.log(a.call({}))         //[oject Object]

object.is和 === 和 ==的区别

object.is()与===的区别:is()中+0和-0不等,NaN和NaN相等
===不仅判断值还判断类型,==如果类型不同会进行类型强转

你可能感兴趣的:(javascript,前端,es6)