撩课-Web大前端天天5道面试题-Day30

1.什么叫优雅降级和渐进加强?

优雅降级:
Web站点在全部新式浏览器中都能正常工做,
若是用户使用的是老式浏览器,
则代码会针对旧版本的IE进行降级处理了,
使之在旧式浏览器上以某种形式降级体验却不至于彻底不能用。
如:border-shadow

渐进加强:
从被全部浏览器支持的基本功能开始,
逐步地添加那些只有新版本浏览器才支持的功能,
向页面增长不影响基础浏览器的额外样式和功能的。
当浏览器支持时,它们会自动地呈现出来并发挥做用。
如:默认使用flash上传,
但若是浏览器支持 HTML5 的文件上传功能,
则使用HTML5实现更好的体验;

 

2.举一些ES6对Object类型作的经常使用升级优化?

优化部分

对象属性变量式声明。
ES6能够直接以变量形式声明对象属性或者方法。
比传统的键值对形式声明更加简洁,
更加方便,语义更加清晰.

let [apple, orange] = ['red appe', 'yellow orange'];

// let myFruits = {apple: 'red appe', orange: 'yellow orange'};
let myFruits = {apple, orange};   
尤为在对象解构赋值(见优化部分b.)或者模块输出变量时,
这种写法的好处体现的最为明显

let {keys, values, entries} = Object;

// let MyOwnMethods = {keys: keys, values: values, entries: entries}
let MyOwnMethods = {keys, values, entries};

能够看到属性变量式声明属性看起来更加简洁明了。
方法也能够采用简洁写法

let es5Fun = {
    method: function(){}
}; 

let es6Fun = {
    method(){}
}
对象的解构赋值。 
ES6对象也能够像数组解构赋值那样,
进行变量的解构赋值

let {apple, orange} = {apple: 'red appe', orange: 'yellow orange'};

对象的扩展运算符(...)。 
ES6对象的扩展运算符和数组扩展运算符用法本质上差异不大,
毕竟数组也就是特殊的对象。
对象的扩展运算符一个最经常使用也最好用的用处就在于能够轻松的取出
一个目标对象内部所有或者部分的可遍历属性,
从而进行对象的合并和分解

let {apple, orange, ...otherFruits} =
{apple: 'red apple', orange: 'yellow orange', grape: 'purple grape', peach: 'sweet peach'}; 
// otherFruits  {grape: 'purple grape', peach: 'sweet peach'}
// 注意: 对象的扩展运算符用在解构赋值时,
// 扩展运算符只能用在最有一个参数(otherFruits后面不能再跟其余参数)
let moreFruits = {watermelon: 'nice watermelon'};
let allFruits = {apple, orange, ...otherFruits, ...moreFruits};

super 关键字。
ES6在Class类里新增了相似this的关键字super。
同this老是指向当前函数所在的对象不一样,
super关键字老是指向当前函数所在对象的原型对象

升级部分

ES6在Object原型上新增了is()方法,
作两个目标对象的相等比较,

//false实际上是不合理的,Object.is修复了这个小bug。
//(Object.is(NaN, NaN) // true)
用来完善'==='方法。
'==='方法中NaN === NaN 

ES6在Object原型上新增了assign()方法,
用于对象新增属性或者多个对象合并

const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}

注意: 
assign合并的对象target只能合并source一、source2中的自身属性,
并不会合并source一、source2中的继承属性,
也不会合并不可枚举的属性,
且没法正确复制get和set属性(会直接执行get/set函数,取return的值)

ES6在Object原型上新增了getOwnPropertyDescriptors()方法,
此方法加强了ES5中getOwnPropertyDescriptor()方法,
能够获取指定对象全部自身属性的描述对象。
结合defineProperties()方法,
能够完美复制对象,
包括复制get和set属性
ES6在Object原型上新增了getPrototypeOf()和setPrototypeOf()方法,
用来获取或设置当前对象的prototype对象。
这个方法存在的意义在于,
ES5中获取设置prototype对像是经过__proto__属性来实现的,
然而__proto__属性并非ES规范中的明文规定的属性,
只是浏览器各大产商“私自”加上去的属性,
只不过由于适用范围广而被默认使用了,
再非浏览器环境中并不必定就能够使用,
因此为了稳妥起见,
获取或设置当前对象的prototype对象时,
都应该采用ES6新增的标准用法
ES6在Object原型上还新增了Object.keys(),
Object.values(),Object.entries()方法,
用来获取对象的全部键、全部值和全部键值对数组

 

3.举一些ES6对Function函数类型作的经常使用升级优化?

优化部分:

箭头函数(核心)。
箭头函数是ES6核心的升级项之一,
箭头函数里没有本身的this,
这改变了以往JS函数中最让人难以理解的this运行机制。

主要优化点:

箭头函数内的this指向的是函数定义时所在的对象,
而不是函数执行时所在的对象。
ES5函数里的this老是指向函数执行时所在的对象,
这使得在不少状况下this的指向变得很难理解,
尤为是非严格模式状况下,
this有时候会指向全局对象,
这甚至也能够归结为语言层面的bug之一。

ES6的箭头函数优化了这一点,
它的内部没有本身的this,这也就致使了this老是指向上一层的this,
若是上一层仍是箭头函数,则继续向上指,
直到指向到有本身this的函数为止,并做为本身的this
箭头函数不能用做构造函数,
由于它没有本身的this,没法实例化
也是由于箭头函数没有本身的this,
因此箭头函数 内也不存在arguments对象。(能够用扩展运算符代替)
函数默认赋值。

ES6以前,
函数的形参是没法给默认值得,
只能在函数内部经过变通方法实现。
ES6以更简洁更明确的方式进行函数默认赋值

function es6Fuc (x, y = 'default') {
    console.log(x, y);
}
es6Fuc(4) // 4, default

升级部分

ES6新增了双冒号运算符,
用来取代以往的bind,call,和apply。(浏览器暂不支持,Babel已经支持转码)

foo::bar;
// 等同于
bar.bind(foo);

foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);

 

4.Generator函数是什么,有什么做用?

若是说JavaScript是ECMAScript标准的一种具体实现、
Iterator遍历器是Iterator的具体实现,
那么Generator函数能够说是Iterator接口的具体实现方式。
执行Generator函数会返回一个遍历器对象,
每一次Generator函数里面的yield都至关一次遍历器对象的next()方法,
而且能够经过next(value)方法传入自定义的value,来改变Generator函数的行为。
Generator函数能够经过配合Thunk 函数更轻松更优雅的实现异步编程和控制流管理。

 

5.什么是 Babel?

Babel 是一个 JS 编译器,
自带一组 ES6 语法转化器,
用于转化 JS 代码。 
这些转化器让开发者提早使用最新的 JS语法(ES6/ES7),
而不用等浏览器所有兼容。
Babel 默认只转换新的 JS 句法(syntax),
而不转换新的API。
 
相关文章
相关标签/搜索