当前位置: 首页 > Web前端 > CSS

掌握前端面试基础系列一:ES6

时间:2023-03-31 11:12:17 CSS

背景又到了年末,跳槽的季节。还记得准备面试,收集各种资料,整理,面试,再整理的场景。这是非常困难的。其实不管是哪家公司面试,基础都是不可避免的。之前有过整理这些资料的想法,但是懒惰,没有做。最近一直在研究公众号,就想着干脆就干吧,把这些基础知识整理一下,以后可以自己看。国庆刚好在家看了ES6相关的东西,所以这篇文章就从ES6说起。经常问到字面的var、let、const这三个东西。总结起来,基本上就是:var、let、const有什么区别?let,const有变量宿主(hosting)吗?什么是TDZ?首先,让我们从整体上看一下差异:对于这几点,我们一一来看。首先,让我们看一下变量提升。我们来看一个例子:console.log(a)//undefinedvara=1这里我们可以看到,虽然第一行的a还没有声明,但是我们不会使用它报错。在这种情况下,它是语句的提升。其实就是:varaconsole.log(a)//undefineda=1但是,如果改成let,情况就不一样了:要理解这个现象,首先要理解promotion的本质,理解三者javascript变量的创建方法步骤:创建初始化赋值为了便于理解,我们先看一下var的创建、初始化和赋值过程:functionfoo(){varx=1vary=2}foo()当foo被执行时,会有一些进程(partialprocesses):输入foo,为foo创建一个环境。查找在foo中用var声明的所有变量,并在此环境中“创建”这些变量(即x和y)。将这些变量“初始化”为未定义。执行代码x=1将x变量“赋值”给1y=2将y变量“赋值”给2,也就是说,va声明会在代码执行前创建该变量,并将其初始化为undefined。这解释了为什么console.log(x)在varx=1之前未定义。接下来我们看一下let声明的“创建、初始化和赋值”过程//...{letx=1;x=2}看一下过程:找到所有用let声明的变量,在环境中创建这些变量并执行代码(注意还没有初始化)执行x=1,“初始化”x到1(这不是赋值,如果代码是letx,则将x初始化为undefined)executex=2,"assign"x这解释了为什么在letx之前使用x会报错:letx='global'{console.log(x)//UncaughtReferenceError:xisnotdefinedletx=1}有两个原因console.log(xin)指的是后面的x,不是全局的x。x在执行日志的时候还没有被“初始化”,所以不能使用(也就是所谓的TDZ,temporarydeadzone,临时死区)。说到这里,就很清楚了:let的“创建”挂了,初始化没有挂。var的“创建”和“初始化”都得到了提升。功能类似,提升了功能的“创建”、“初始化”和“赋值”。至此,有兴趣的朋友可以自行试验。算了,直接举个例子:JS引擎会有一个过程:找到所有用function声明的变量,在环境"创建”这些变量。这些变量被“初始化”和“赋值”为function(){console.log(2)}。开始执行代码fn2()`也就是说,函数声明会在代码执行之前被“创建、初始化和赋值”。这里有一个简短的总结:函数提升优先于变量提升。函数提升会将整个函数移动到作用域的顶部,而变量提升只会将声明移动到作用域的顶部。var被提升了,我们可以在声明它之前使用它。let,const由于临时死区不能在声明前使用。var在全局范围内声明变量,会导致变量被挂载到window上,而另外两个则不会。let和const的作用基本相同,只是后者声明的变量不能再次赋值。箭头函数也是ES6中一个很有用的特性,我们每天都在使用它。箭头函数是ES6中一种新的函数定义形式:functionname(arg1,arg2){}//可以使用(arg1,arg2)=>{}//来定义。箭头函数,一方面看起来更简洁,另一方面解决了ES5时代的这个问题。看一个例子:functionfn(){console.log(this)//{a:100},在这个作用域下this的实际值vararr=[1,2,3]//ES5arr.map(function(item){console.log(this)//window})//箭头函数arr.map(item=>{console.log(this)//{a:100}这里打印的是父级的thisscope})}fn.call({a:100})模块化的好处非常明显:解决命名冲突,提供可重用性,提高代码可维护性。在ES6之前,也有模块化的解决方案:AMD、CMD,只是简单提一下,不是本文的主要内容。AMD,CMD//AMDdefine(['./a','./b'],function(a,b){a.do()b.do()})//CMDdefine(function(require,exports,module){vara=require('./a')a.doSomething()})IIFE还有一种IIFE形式:(function(globalVariable){//形成一个独立的作用域,不会污染全局//。..})(globalVariable)CommonJSCommonJS最先被Node.js使用,至今仍在广泛使用。看一个例子://a.jsmodule.exports={a:1}//b.jsvarmodule=require('./a.js')module.a//1ES6ModuleESModule是原生实现的模块化解决方案,提供一种将文件开发为模块的新方法。使用方式是我们常用的://a.jsexportfunctiona(){}exportdefaultfunction(){}//b.jsimportXXXfrom'./a.js'import{XXX}from'./a.js'如果你只是输出一个唯一的对象,使用exportdefault//util1.jsexportdefault{a:100}//index.js文件importobjfrom'./util1.js'console.log(obj)//{a:100}如果要导出很多对象,不能使用default,需要在导入时加上{...},代码如下://foo.jsexportfunctionfn1(){alert('fn1')}exportfunctionfn2(){alert('fn2')}//index.jsimport{fn1,fn2}from'./foo.js'fn1()fn2()Class类一直是js的保留字,直到使用ES6才正式实现。(js中没有class,class只是语法糖,本质上还是一个函数,其实就是模拟面向对象的语法,你懂的)ES6class就是替代了之前构造函数初始化对象的形式,这在语法面向对象的写作中更接近。例如://ES5functionMathHandle(x,y){this.x=x;this.y=y;}MathHandle.prototype.add=function(){returnthis.x+this.y;};varmethod=newMathHandle(1,2);console.log(method.add())ES6类写法:classMathHandle{constructor(x,y){this.x=x;这个.y=y;}add(){返回this.x+this.y;}}const方法=newMathHandle(1,2);console.log(method.add())注意以下几点:class是一种新的语法形式,className{...}这种形式和函数的写法完全不一样。两者相比,构造函数体的内容应该放在类中的构造函数中。构造器就是构造器。初始化实例时,默认执行.class中的函数。写法是add(){...}的形式,没有function关键字。Prototype继承和Class继承都是使用Class来实现继承。它甚至更简单,至少比构造函数继承简单得多://AnimalfunctionAnimal(){this.eat=function(){console.log('animaleat')}}//dogfunctionDog(){this.bark=function(){console.log('dogbark')}}狗。prototype=newAnimal()varhusky=newDog()husky.bark()//dogbarkES6写作:classAnimal{constructor(name){this.name=name}eat(){console.log(`${this.name}eat`)}}classDogextendsAnimal{constructor(name){super(name)this.name=name}bark(){console.log(`${this.name}say`)}}consthusky=newDog('Husky')husky.bark()注意以下两点:使用extends实现继承,更符合经典面向对象语言的语法。子类的构造函数必须执行super()来调用父类的构造函数。以上几个方面在面试中经常被问到。ES6的内容远非未知。还有很多有用的功能,比如:“...”运算符解构SetMap等,这里就不一一介绍了。关于“...”操作符,可以参考我的文章:深入理解强大的ES6“...”操作符ES6面试题大都是以上几点,可能有错误,我再补充后来吧。我希望能有所帮助。最后,今天是楼主节后第一天上班,状态不佳。告诉大家一件最尴尬的事,今天我要填写2019年的业绩自我评估,其中一项是:公司在哪些方面可以帮助你成长?本来是一个很正常的问题:我是这样写的:写完后笑着和同事开玩笑,我可以要求加薪吗?说完我就点了提交。提交后感觉哪里不对?刚提交的???撒谎,害怕,撒谎,我所做的事情无论如何都无法改变,就这样吧。如果文章中有任何错误,请指正。最后,如果觉得内容有帮助,可以关注我的公众号《前端e进阶》,一起学习成长,可以通过公众号菜单栏联系我,加入我们的微信群,一起玩得开心。