1.让元素上下垂直居中的方法有哪些?水平居中和垂直居中的方式有??哪些?absoluteplusmarginschemefixedplusmarginschemedisplay:tableschemeinlineelementline-heightschemeflexelasticlayoutschemetransformunknownelementwidthandheight解决方案absoluteplusmarginschemediv{position:absolute;宽度:100px;高度:100px;左:50%;顶部:50%:边距顶部:-50px;左边距:-50px;}fixedplusmarginschemediv{position:fixed;宽度:100px;高度:100px;顶部:0;右:0;左:0;底部:0;保证金:自动;}display:tableschemediv{display:table-cell;垂直对齐:中间;文本对齐:居中;宽度:100px;高度:100px;}行内元素行高方案div{text-align:center;行高:100px;}flex弹性布局方案div{display:flex;对齐项目:居中;justify-content:center}变换未知元素宽高解div{position:absolute;顶部:50%;左:50%;转sform:translate(-50%,-50%)}2.varletconst的区别和使用场景?前三个是Varvar声明的变量,用于在js中声明变量,作用域在语句所在的函数内,并且有变量提升console.log(a)//变量提升,vara被提升到作用域的顶部,所以这里的输出值是undefinedvara='JS'for(vari=0;i<10;i++){setTimeout(function(){//将回调函数同步注册到异步宏任务queueconsole.log(i);//当这段代码执行时,for循环的同步代码已经执行完毕},0);}10...10//1010console.log(i)//iscopeglobaloutput10后面声明的会覆盖之前声明的变量vara='JS'vara='JavaScript'Letlet声明的变量,作用域是this语句的代码块中,没有变量提升console.log(a)//变量没有被提升,输出ReferenceError:aisnotdefinedleta='JavaScript'for(leti=0;i<10;i++){setTimeout(function(){//将回调函数同步注册到异步宏任务队列中。控制台日志(一);//这段代码执行时,for循环的同步代码已经执行},0);}1...10//1到10console.log(i)//iscopeforblocklevel里面,输出i未定义不允许重复声明leta='JavaScript'leta='JS'//'a'已经被声明constconst包含了let的所有特性,不同的是const声明的变量是一个read-onlyandunmodifiable这里注意,const保证的不是声明的值不能改变,而是变量指向的内存不能改变代码示例consta={content:'JavaScript'}a.content='JS'//JSa={content:'JS'//这里改了内存,所以报错Assignmenttoconstantvariable}三句话概括了用var声明的变量,它的作用域在语句所在的函数内,以及存在变量提升的现象,后面覆盖了前面使用let声明的变量的范围e在语句所在的代码块内。没有变量提升,不能重复声明。const声明的是常量,在后面出现的代码中不能修改常量的内存。3.如何理解ES6的类型?首先,JS作为一种非面向对象的语言,在es6之前是不提供对类的支持的。我们通常的做法是通过构造函数来模拟类的实现,在原型上与其实例共享属性和方法。简单实现:functionJS(name){this.name=name}JS.prototype.getName=function(){console.log(this.name)}constchild=newJS('test')Classes6inES6Class只是语法糖。class的写法只是让对象原型看起来更清晰好用:classJS{constructor(name){this.name=name}getName(){console.log(this.name)}}constchild=newJS('test')每个类中都有一个构造方法。如果没有显示定义,默认会添加一个空的构造函数,相当于ES5中的构造函数。类的所有方法都定义在类的prototype属性上,两者的主要区别是Class必须用new调用,ES5中的构造函数也可以不使用new调用,静态方法(static)关键字被添加到类中,静态方法不能只通过类继承调用类本身JS{constructor(name){this.name=name}staticgetName(){//静态方法只能被类调用class本身,并且实例不能继承console.log(this.name)}}Extends也可以继承class通过extends关键字实现继承代码示例:classJS{constructor(name){this.name=name}getName(){console.log(this.name)}}classCssextendsJs{constructor(){super();}}constchild=newCss('test')child.getName()//'test'extends注意使用extends继承时,必须在子类构造函数中调用super(),即调用父类构造函数super代码的父类的构造函数,但是当返回的子类的实例super作为函数被调用时,当代表类的构造函数super作为对象被调用时,在普通方法中,它指向的是类的原型对象父类,在静态方法中,它指向父类4.如何理解es6中的Promise?js是单线程的,也就是说一次只能完成一个任务。为了解决这个问题,js将任务的执行方式分为同步和异步两种。在es5中,我们只能通过回调来处理异步。处理,在多层异步中,回调会层层嵌套,也就是所谓的回调地狱,promise是异步编程的一种解决方案Promise特性:对象的状态promise对象不受外界影响,代表一个异步操作。共有三种状态:pending(进行中)、fulfilled(成功)和rejected(失败)。状态一旦改变,就不会再改变。状态变化只有两种可能,pending=>fulfilled和pending=>rejected基本用法:constpromise=newPromise(function(resolve,reject){//...somecodeif(/*异步操作成功*/){resolve(value);//将状态从pending更改为fulfilled}else{reject(error);//将状态从pending更改为rejected}});promise生成后,可以使用then方法接收回调函数promise.then(()=>{console.log('resolved')},()=>{console.log('rejected')})promise在原型上有一个catch方法,catch方法是rejection的别名,用于指定错误发生时的回调函数promise.then(()=>{console.log('resolved')},()=>{console.log('rejected')}).catch((err)=>{console.log('catch')})promise原型有一个finally方法,用于将要执行的操作无论promise对象的最终状态如何,都会被执行。promise.then(()=>{console.log('resolved')},()=>{console.log('rejected')})。最后((错误)=>{console.log('end')})Promise.allPromise.all方法用于将多个Promise实例包装成一个新的Promise实例。简单使用:constp=Promise.all([p1,p2,p3]);特点:参数都是promise实例。如果不是,将调用promise.resolve方法将它们转换为promise实例。p的奖励状态由传入的承诺实例的状态决定。实例状态变为拒绝状态,p状态被拒绝6。如何理解es6中的Proxy?如何理解es6中的Proxy?试题解析:对proxy的理解可能会延伸到Vue的双向绑定Proxy(代理)。定义可以理解为对目标对象设置一层拦截。外部对对象的访问必须经过这一层拦截。简单示例:constobj=newProxy({},{get:(target,key,receiver)=>{return'JS'console.log(`get${key}`)},set:(target,key,value,receiver)=>{console.log(`set${key}`)},})obj.name='JS'//setname//JSobj.name//这里进入get的回调函数,都是直接返回JS从上面的例子可以看出,Proxy有一种机制可以重写外部的读写操作。代理实例方法proxy除了get和set操作外还可以代理其他操作,如下handler.getPrototypeOf()//在读取代理对象的原型时触发该操作,比如执行Object.getPrototypeOf(proxy)handler时.setPrototypeOf()//当设置代理对象的原型时触发该操作,比如在执行Object.setPrototypeOf(proxy,null)时。handler.isExtensible()//在判断代理对象是否可扩展时触发该操作,比如执行Object.isExtensible(proxy)时。handler.preventExtensions()//当代理对象不可扩展时触发此操作,例如当执行Object.preventExtensions(proxy)时。handler.getOwnPropertyDescriptor()//在获取代理对象的某个属性的属性描述时触发该操作,比如执行Object.getOwnPropertyDescriptor(proxy,"foo")时。handler.defineProperty()//当定义代理对象的某个属性的属性描述时触发该操作,比如执行Object.defineProperty(proxy,"foo",{})时。handler.has()//在判断代理对象是否有属性时触发该操作,比如在proxy中执行“foo”时。handler.get()//在读取代理对象的某个属性时触发该操作,比如执行proxy.foo时。handler.set()//当给代理对象的某个属性赋值时触发这个操作,比如执行proxy.foo=1的时候。handler.deleteProperty()//当代理对象的某个属性被删除时触发该操作,比如执行deleteproxy.foo。handler.ownKeys()//当获取到代理对象的所有属性键时触发该操作,比如执行Object.getOwnPropertyNames(proxy)时。handler.apply()//当调用目标对象为函数的代理对象时触发该操作,比如执行proxy()时。handler.construct()//在构造目标对象为构造函数的代理对象实例时触发该操作,比如执行newproxy()时。为什么要使用Proxy来拦截和监控外部对对象的访问降低函数或类的复杂度在复杂操作或管理所需资源之前验证操作7.如何理解es6中的装饰器?Decorator是ES7中的一个提案。这个概念是从python借来的。它作用于目标类以向方法添加属性。我们用一个比喻来理解Decorator。把孙悟空想成一个类,那么棍子就是装饰器装备的武器代码理解:@stickclassMonkey{}functionstick(target){//第一个参数是目标类本身target.ATK=100000}Monkey.ATK//给悟空配备一根棍子,攻击力增加100000//一个参数不够可以再包裹一层functionstick(atk){returnfunction(targt){target.ATK=atk}}@stick(200000)//这会给悟空增加200000攻击力classMonkey{}装饰器不仅可以装饰类,还可以装饰类的方法classMonkey{@setNamename(){this.name='MonkeyKing'}}装饰器只能装饰类和类的方法,不能装饰函数,因为在装饰器的基础上有一个促进Mixin的功能,我们可以实现mixin(混入),也就是混合另一个方法objectinoneobject代码示例:exportfunctionmixins(...list){returnfunction(target){Object.assign(target.prototype,...list)}}constskill={shapeshifting(){console.log('72change')}}@mixins(skill)classMonkey{}Object.assign(Monkey.prototype,skill)constswk=newMonkey()swk.shapeshifting()//使用Decorator扩展功能的72个好处,相比继承增加了更多的灵活性代码可读性更强,装饰器的正确命名等同于Note8.Es6新增了哪些数据类型?使用场景?Es6中有哪些新的数据类型?使用场景?在es6中,增加了一种新的原始数据类型Symbol。最大的特点是独特性。符号值由符号函数生成。在es5中,对象的属性都是字符串。我们使用别人定义的对象,然后加上自己的属性,这样很容易造成冲突,覆盖掉原来的属性。Symbol也可以看作是一个字符串,但是这个字符可以保证是唯一的。基础示例//Objectconstobj={name:'JS'}obj.name='JSeveryDailyquestion'//Symbolconstname=Symbol('name')//这里的参数没有特殊意义,可以看成aSymbol加了标记obj[name]='JSDailyquestion'SymbolusageHowmanySymbolscurrently一种写法//一个consttitle=Symbol()constobj={}obj[title]='JSdailyquestion'//二个constobj={[title]:'JS每日一题'}//三个Object.defineProperty(obj,title,{value:'JS每日一题'})obj[title]//输出结果都是JS每日问题。这里注意,当Symbol作为属性名时,不能使用点来读取obj.title//undefinedSymbol作为属性名,只能通过Object.getOwnPropertySymbols方法返回constattrs=Object.getOwnPropertySymbols(obj)//[Symbol[title]]Symbol.for()如果我们想重复Symbol,我们可以使用Symbol.for,Smybol.for()和Smybol()的区别是Symbol.for()会先检查是否已经在下面声明了全局的,如果有则返回值,如果没有则创建一个新值。每次调用Symbol()都会创建新的代码来理解:consttitle=Symbol.for('JS每日题')....Symbol.for('JS每日题')//使用的第一条语句是第一条语句多次使用Symbol.for('JS每日一题')的值===Symbol.for('JS每日一题')//trueconsttitle=Symbol('JS每日一题')Symbol('JS每日一题')===Symbol('JS每日一题')//false总结Symbol的特点。它是唯一的,不能隐式转换。它不能与其他数据类型一起操作。它不能与点运算符一起操作。9.简单说明一下为什么使用vue?
