ES6+前端面试题整合

谈一谈let与var和const的区别

let为ES6新添加申明变量的命令,它类似于var,但是有以下不同:  

  • let命令不存在变量提升,如果在let前使用,会导致报错
  • let暂时性死区的本质,其实还是块级作用域必须“先声明后使用”的性质,let 暂时性死区的原因:var 会变量提升,let 不会。
  • let,const和class声明的全局变量不是全局对象的属性
  • const可以在多个模块间共享
  • const声明的变量与let声明的变量类似,它们的不同之处在于,const声明的变量只可以在声明时赋值,不可随意修改,否则会导致SyntaxError(语法错误)
  • const只是保证变量名指向的地址不变,并不保证该地址的数据不变

说说箭头函数的特点

  • 箭头函数不属于普通的 function,所以没有独立的上下文。
  • 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  • 由于箭头函数没有自己的this,函数对象中的call、apply、bind三个方法,无法"覆盖"箭头函数中的this值。
  • 箭头函数没有原本(传统)的函数有的隐藏arguments对象。
  • 箭头函数不能当作generators使用,使用yield会产生错误。

在以下场景中不要使用箭头函数去定义:

1. 定义对象方法、定义原型方法、定义构造函数、定义事件回调函数。

2. 箭头函数里不但没有 this,也没有 arguments,super

对Symbol,Map和Set的理解

Symbol 是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用,即使使用同样的参数实例化symbol,得到的symbol实例也不会相等

let _symbol1 = Symbol('test');
let _symbol2 = Symbol('test');
console.log(_symbol1 == _symbol2);//false

Map对象保存键值对,有点类似于Object,但是Object的键只能是字符串或者Symbols,而Map可以是任何值

        let myMap = new Map()
        let str1 = 'dog'
        let str2 = 'cat'
        myMap.set(str1,'汪')
        myMap.set(str2,'喵')
        console.log(myMap) // {0: {"dog" => "汪"}1: {"cat" => "喵"}}
        console.log(myMap.get(str1)) // 汪

Set 对象允许你存储任何类型的唯一值(数组去重),有点类似于Array,Set中的元素只会出现一次

        let mySet = new Set()
        mySet.add('hello')
        mySet.add('1')
        mySet.add('2')
        mySet.add('2')
        console.log(mySet) // {0: "hello",1: "1",2: "2"}

使用ES6如何监测数组变化(proxy监测读写)

        let list = [1,2,3]
        // 代理
        let _proxy = new Proxy(list,{
            set: function (target,prop,val,rec) {
                console.log('写入')
                target[prop] = val
                return true
            },get: function (target,prop) {
                console.log('读取')
                return target[prop]
            }
        })
        _proxy[0] = 4 // 写入
        console.log(_proxy[1]) // 读取

JS有哪些处理异步的方法

回调函数:回调是一个函数被作为一个参数传递到另一个函数里,在那个函数执行完后再执行

优点:简单,方便,实用,易懂
缺点:当逻辑复杂时,会产生回调函数地狱,耦合度高,流程会很混乱

        // 回调
        let cb = (props) => {
            console.log(props) // 2
        }
        let init = (props) => {
            // 异步操作
            setTimeout(() => {
                cb(props) // 异步传参
            },1000)
        }
        init(2)
        console.log(1) // 1

事件发布/订阅:采用事件驱动模式,任务的执行取决于某一个事件是否发生

优点:事件监听方式相对回调实现了代码的解耦,对模块化开发很友好
缺点:每次执行任务都需要发布/订阅事件

        // 事件发布/订阅
        let cb = (event) => {
            console.log(event.props) // 2
        }
        let init = (props) => {
            // 异步操作
            setTimeout(() => {
                let event = new Event('myEvent')
                event.props = props // 异步传参
                document.dispatchEvent(event)
            },1000)
        }
        init(2)
        console.log(1) // 1
        document.addEventListener('myEvent',cb)

Promise:Promise是异步编程,它将异步操作以同步的方式表现出来,避免回调地狱的产生

优点:避免回调地狱,链式调用,函数思路清晰,逻辑相对前两者更强
缺点:理解性差,异步操作在promise构造函数内部

        // ES6  Promise
        let init = (props) => {
            return new Promise((resolve,reject) => {
                // 异步操作
                setTimeout(() => {
                    resolve(props)
                },1000)
            })
        }
        init(2).then((res) => {
            console.log(res) // 2
        })
        console.log(1) // 1

Generator:generator(生成器)是ES6标准引入Python的新的数据类型

优点:取消链式调用的then,和发布/订阅模式非常相似,对于理解同步操作很直观
缺点:多个异步函数时不够直观,原函数需要通过next去维护外部函数的yield

        // ES6  Generator
        const fn = init(2)
        let cb = (props) => {
            console.log(props) // 2
        }
        function* init(props) {
            // 异步操作
            yield setTimeout(() => {
                fn.next()
            },500)
            yield setTimeout(() => {
                fn.next()
            },500)
            cb(props)
        }
        fn.next()
        console.log(1) // 1

async/await:async函数是generator函数的语法糖,函数(function关键字)前添加async关键字,函数中通过await等待异步执行

优点:同步流程清晰,简洁,异步操作可以返回promise对象,后续操作更方便
缺点:JS的执行器功能较其他co模块较弱

        // ES6+  async/await
        let cb = (props) => {
            console.log(props) // 2
        }
        let cb2 = (props) => {
            return new Promise((resolve,reject) => {
                setTimeout(() => {
                    resolve(props)
                },1000)
            })
        }
        async function init(props) {
            // 异步操作
            let num2 = await cb2(props)
            cb(num2)
        }
        init(2)
        console.log(1) // 1

ES6中的class关键字跟function什么区别

  • 在function定义的构造函数中,其prototype.constructor属性指向构造器自身,在class定义的类中,constructor其实也相当于定义在prototype属性上
  • function如果重复定义,会覆盖之前定义的方法,而class重复定义则会报错
  • class中定义的方法不可用Object.keys(Point.prototype)枚举到,function构造器原型方法可被Object.keys(Point.prototype)枚举到
  • class没有变量提升,也就是说,必须先定义class,再使用,而function定义后,会被提升至当前作用域顶端
  • class定义的类没有私有方法和私有属性,function可以通过闭包实现私有方法和属性

ES6新增哪些数组方法

find():返回数组中第一个满足条件的元素(如果有的话), 如果没有,则返回 undefined
findIndex():返回数组中第一个满足条件的元素的索引(如果有的话), 如果没有,则返回 -1
keys():返回一个数组索引的迭代器
values():返回一个数组迭代器对象,该对象包含数组中每个索引的值
entries():返回一个数组迭代器对象,该对象包含数组中每个索引的键值对

for in 和 for of 的区别

for in 适合用于遍历对象,for of可以用来遍历数组,类数组对象,argument,字符串,Map和Set

for in 遍历数组时会有以下问题:

  • index索引为字符串型数字,不能直接进行几何运算
  • 遍历顺序有可能不是按照实际数组的内部顺序
  • 使用for in会遍历数组所有的可枚举属性,包括原型,原型上的方法和属性

所以for in 不适合遍历数组,而适合用于遍历对象

而for of遍历数组时

只会遍历数组内的元素,而不包括数组的原型属性method和索引name

CommonJS 中的 require/exports 和 ES6 中的 import/export 区别

  • CommonJS模块输出的是一个值的拷贝,ES6模块输出的是值的引用
  • CommonJS模块是运行时加载,ES6模块是编译时输出接口,ES6可以在编译时就完成模块加载,效率要比CommonJS模块的加载方式高
  • CommonJS模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。而Es6模块的运行机制与CommonJS不一样。JS引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,在根据引用到被加载的那个模块里面去取值。ES6模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。
  • require/exportsCommonJSNode中实现的,import/exportES6的模块
  • require/exports是同步导入,因为用于服务端,文件都在本地,同步导入即使卡住主线程影响也不大。而ES6模块是异步导入,因为用于浏览器,需要下载文件,如果也采用导入会对渲染有很大影响
  • ES6模块的设计思想,是尽量静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量,ES6模块会编译成 require/exports 来执行的
  • export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能

尝试实现Promise

https://blog.csdn.net/time_____/article/details/109721703

Object.is()与“==”,“===”的区别

“==”会在比较时进行类型转换

“===”比较时不进行隐式类型转换

Object.is()在三等号判等的基础上特别处理了NaN、-0和+0,保证-0和+0不再相同,但Object.is(NaN,NaN)会返回true

ES6中为何出现Class

Class的功能实际上在ES5都能实现,可以算是ES6的语法糖,其作用是使JS语法清晰,更像面向对象语法

基础写法

        class MyEvent extends EventTarget { // 继承EventTarget
            constructor(e) {
                super(e) // 父类的构造函数
                this.consoleThis() // 执行函数
            }
            consoleThis() {
                console.log(this)
            }
        }
        let myEvent = new MyEvent(document) // EventTarget 

ES6语法糖的对象的属性简写和属性名表达式是什么

属性简写:对象的字面量可以直接写入与之名称相同的变量和函数

        let name = '小明'
        function showName() {
            console.log(this.name)
        }
        let person = {
            name,showName
        }
        console.log(person.name)// 小明
        person.showName()// 小明

属性名表达式简写:ES6允许把表达式放在方括号内,作为对象的属性名

        let num = 0
        let obj = {
            "1": 'a',"2": 'b',"3": 'c'
        }
        console.log(obj[++num]) // a
        console.log(obj[++num]) // b
        console.log(obj[++num]) // c

谈谈解构赋值的理解

解构赋值是对赋值运算符的扩展,是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值

        // 数组
        let [a,b,c] = [1,3];
        console.log(a,c) // 1,3
        // 对象
        let {
            d,e,f
        } = {
            d: 4,e: 5
        };
        console.log(d,f) // 4,5,undefined

使用ES6如何合并多个对象,复制对象

ES6中的对象新增(...)拓展运算符,用于取出参数对象所有可遍历属性然后拷贝到当前对象

ES6新增对象拷贝方法:Object.assign(target,source1,source2,source3, ···),将源对象的所有可枚举属性复制到目标对象中,即,将source1,source2,source3......复制到target中

合并:

        let name = {
            name: '小明'
        }
        let age = {
            age: 20
        }
        let hobby = {
            hobby: 'music'
        }
        let person = {// 拓展运算符
            ...name,...age,...hobby
        }
        console.log(person)// age: 20,hobby: "music",name: "小明"

        Object.assign(person,name,age,hobby)// 对象拷贝
        console.log(person) // age: 20,name: "小明"

复制:

        let list = [1,3,4,5]
        let list2 = [...list]// 拓展运算符
        Object.assign(list2,list)// 对象拷贝
        let index = 0
        do {
            list[index] += 10
        } while (index++ < list.length - 1)
        console.log(list,list2) // [11,12,13,14,15]  [1,5]

如何控制类中属性的读写性

setter...getter...

        class Animal {
            constructor() {
                this._dog = '小黑'
                this._cat = '小黄'
            }
            set cat(val) { // 只写
                this._cat = val
            }
            get dog() { // 只读
                return this._dog
            }
        }
        let animal = new Animal()
        animal.dog = '小白'
        animal.cat = '小灰'
        console.log(animal.dog,animal.cat) // 小黑 undefined
        console.log(animal._dog,animal._cat) // 小黑 小灰

Object.defineProperty()修改对象只读

        class Animal {
            constructor() {
                this.dog = '小白'
            }
        }
        let animal = new Animal()
        Object.defineProperty(animal,'dog',{
            writable: false,// 可写,false为只读
        });
        animal.dog = '小黑'
        console.log(animal.dog) // 小白

 

原文地址:https://blog.csdn.net/time_____

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1==&gt;简述一下src与href的区别 src用于替换当前元素; href用于在当前文档和引用资源之间确立联系 2==&gt;、谈谈以前端角度出发做好SEO需要考虑什么? a.&#160;了解搜
什么是window对象?什么是document对象? window对象代表浏览器中打开的一个窗口。 document对象代表整个html文档。实际上, document对象是window对象的一个属性
1 》vue-router有哪几种导航钩子? 第一种:是全局导航钩子:router.beforeEach(to,from,next) 第二种:&#160;组件内的钩子 beforeRouteEnter
1=&gt;为什么data是一个函数 【理解】 组件的data写成一个函数, 这样每复用一次组件,就会返回一分新的data。 也就说:给每个组件实例创建一个私有的数据空间。 各个组件维护各自的数据。
01 vue3的新特征 1.组合式API. setUp作为组合函数的入口函数 2.Teleport 传送门 3.片段 template下可以有多个标签 4.用于创建自定义渲染器。我的理解是 creat
// var&#160;arr=[1,2,23,23,4,5,5]; // var&#160;newarr=new&#160;Set(arr);&#160;//去重 // console.log([.
摆好姿势 摆好姿势 如何使下面的等式成立 if(a==1&amp;&amp;a==3&amp;a==5){ console.log(666) } var a=[1,3,5] a.join=a.shif
1=&gt;为什么data是一个函数 【理解】 ok 每复用一次组件,就会返回一分新的data。 也就说:【每个组件实例创建】一个【私有】的数据空间。各个组件维护各自的数据。 如果单纯的写成对象形式,
以下是收集一些面试中经常会遇到的经典面试题以及自己面试过程中无法解决的问题,通过对知识的整理以及经验的总结,重新巩固自身的前端基础知识,如有错误或更好的答案,欢迎指正。:) 在网页中,一个元素占有空间
1 Action是不是线程安全的?如果不是 有什么方式可以保证Action的线程安全?如果是,说明原因不是声明局部变量,或者扩展RequestProcessor,让每次都创建一个Action,或者在s
解决js兼容性问题使用 event对象 function eventHandler(event) { event = event || window.event} 获取滚动条属性 var scrollTop = document.documentElment.scrollTop || document.body.scrollTop
浏览器的内核 IE: trident内核,Firefox:gecko内核,Safari:webkit内核,Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核,Chrome:Blink(基于webkit,Google与Opera Software共同开发) HTML中的Doctype有什么作用 此标签可告知浏览器文档使用哪种HTML或XHTML规范。(重点:告诉浏览器按照何种规范解析页面) div+css的布局较table布局有什么...
如何创建函数第一种(函数声明): function sum1(num1,num2){ return num1+num2; } 第二种(函数表达式): var sum2 = function(num1,num2){ return num1+num2; } 第三种(函数对象方式): var sum3 = new Function("num1","num2","return num1+num2");三种弹窗的单词以及三种弹窗的功能1.alert //弹出对话框并输出一段提示信...
js的垃圾回收机制是什么原理垃圾回收机制有两种方法第一种是标记清除法:当变量进入执行环境时,就标记这个变量为”进入环境”,当变量离开环境的时候,则将其标记为”离开环境”,垃圾收集器在运行的时候会给储存在内存中的所有变量都加上标记,然后它会去掉环境中的标量以及被环境中的变量引用的标记,而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了,最后,垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间 第二种是引用计数法:当声明了一个变量并将
Ajax 是什么? 如何创建一个Ajax?AJAX全称是Asychronous JavaScript And Xml(异步的 JavaScript 和 XML)它的作用是用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可以使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持其主要通过XMLHttpRequest(标准浏览器)、ActiveXObject(IE浏览器)对象实现异步通信效果实现方式(gitee上的案例):
谈一谈let与var和const的区别let为ES6新添加申明变量的命令,它类似于var,但是有以下不同: let命令不存在变量提升,如果在let前使用,会导致报错let暂时性死区的本质,其实还是块级作用域必须“先声明后使用”的性质,let 暂时性死区的原因:var 会变量提升,let 不会。let,const和class声明的全局变量不是全局对象的属性const可以在多个模块间共享const声明的变量与let声明的变量类似,它们的不同之处在于,const声明的变量只可以在声明时赋值,不可
解释一下为何[ ] == ![ ] // ---&gt; true首先看一张图![ ] 是 false原式:[ ] == false根据第八条,false通过tonumber()转换为0原式:[ ] == 0根据第十条,[ ]通过ToPrimitive()转换为' '原式:' ' == 0根据第六条原式:0 == 0尝试实现new function ObjectClass() {//对象 console.log(arguments[...
谈谈对Node的理解Node.js 在浏览器外运行V8 JavaScript引擎,单线程 非阻塞I/O 事件驱动,适应于数据高并发,适合多请求,但不适合高运算,有权限读取操作系统级别的API,npm 仓库,常用框架:Express,koa,Socket.io,AdonisJs,NestJS什么是gulp?作用?机制是什么?gulp是基于node的自动化构建工具作用:1 自动压缩JS文件2 自动压缩CSS文件3 自动合并文件4 自动编译sass5 自动压缩图片6 自动刷
vue和react的区别React严格上只针对MVC的view层,Vue则是MVVM模式virtual(虚拟) DOM不一样,vue会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。而对于React而言,每当应用的状态被改变时,全部组件都会重新渲染,所以react中会需要shouldComponentUpdate这个生命周期函数方法来进行控制组件写法不一样,React推荐的做法是 JSX + inline style,也就是把HTML和CSS全都写进JavaScript了,即'all in
谈谈对react的理解react是基于v(视图层)层的一款框架,虚拟dom和diff算法react特点:声明式设计高效,其中高效以现在虚拟dom,最大限度减少与dom的交互和diff算法灵活,体现在可以与已知的框架或库很好的配合JSX,是js语法的扩展组件化,构建组件,是代码的更容易得到复用,比较建议在大型项目的开发单项数据,实现单项数流,从而减少代码复用react有哪几个生命周期自己的总结分为三个阶段,初始,运行中,销毁初始化: 执行getDefaultProps钩子