25 谈一谈你了解 ECMAScript6 的新特性?
-
块级作用区域 let a = 1;
-
可定义常量 const PI = 3.141592654;
-
变量解构赋值 var [a, b, c] = [1, 2, 3];
-
字符串的扩展(模板字符串) var sum =
${a + b};
-
数组的扩展(转换数组类型) Array.from($('li'));
-
函数的扩展(扩展运算符) [1, 2].push(...[3, 4, 5]);
-
对象的扩展(同值相等算法) Object.is(NaN, NaN);
-
新增数据类型(Symbol) let uid = Symbol('uid');
-
新增数据结构(Map) let set = new Set([1, 2, 2, 3]);
-
for…of 循环 for(let val of arr){};
-
Promise 对象 var promise = new Promise(func);
-
Generator 函数 function* foo(x){yield x; return x*x;}
-
引入 Class(类) class Foo {}
-
引入模块体系 export default func;
-
引入 async 函数[ES7]
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value)
}
与原来的比较操作符 ===、== 的区别?
-
==
相等运算符,比较时会自动进行数据类型转换 -
===
严格相等运算符,比较时不进行隐式类型转换 -
Object.is
同值相等算法,在===
基础上对0
和NaN
特别处理
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
27 什么是 Babel
-
Babel
是一个 JS 编译器,自带一组 ES6 语法转化器,用于转化 JS 代码。 这些转化器让开发者提前使用最新的 JS 语法(ES6/ES7),而不用等浏览器全部兼容。 -
Babel
默认只转换新的 JS 句法(syntax),而不转换新的 API。
28 symbol 有什么用处
可以用来表示一个独一无二的变量防止命名冲突。但是面试官问还有吗?我没想出其他的用处就直接答我不知道了,还可以利用 symbol 不会被常规的方法(除了 Object.getOwnPropertySymbols 外)遍历到,所以可以用来模拟私有变量。
主要用来提供遍历接口,布置了 symbol.iterator 的对象才可以使用 for···of 循环,可以统一处理数据结构。调用之后回返回一个遍历器对象,包含有一个 next 方法,使用 next 方法后有两个返回值 value 和 done 分别表示函数当前执行位置的值和是否遍历完毕。
Symbol.for()` 可以在全局访问 `symbol
29 模块化
在有
Babel
的情况下,我们可以直接使用ES6
的模块化
// file a.js
export function a() {}
export function b() {}
// file b.js
export default function() {}
import {a, b} from './a.js'
import XXX from './b.js'
CommonJS
CommonJs
是Node
独有的规范,浏览器中使用就需要用到Browserify
解析了。
// a.js
module.exports = {
a: 1
}
// or
exports.a = 1
// b.js
var module = require('./a.js')
module.a // -> log 1
在上述代码中,
module.exports
和exports
很容易混淆,让我们来看看大致内部实现
var module = require('./a.js')
module.a
// 这里其实就是包装了一层立即执行函数,这样就不会污染全局变量了,
// 重要的是 module 这里,module 是 Node 独有的一个变量
module.exports = {
a: 1
}
// 基本实现
var module = {
exports: {} // exports 就是个空对象
}
// 这个是为什么 exports 和 module.exports 用法相似的原因
var exports = module.exports
var load = function (module) {
// 导出的东西
var a = 1
module.exports = a
return module.exports
};
再来说说
module.exports
和exports
,用法其实是相似的,但是不能对exports
直接赋值,不会有任何效果。
对于
CommonJS
和ES6
中的模块化的两者区别是:
-
前者支持动态导入,也就是 require(${path}/xx.js)
,后者目前不支持,但是已有提案,前者是同步导入,因为用于服务端,文件都在本地,同步导入即使卡住主线程影响也不大。 -
而后者是异步导入,因为用于浏览器,需要下载文件,如果也采用同步导入会对渲染有很大影响 -
前者在导出时都是值拷贝,就算导出的值变了,导入的值也不会改变,所以如果想更新值,必须重新导入一次。 -
但是后者采用实时绑定的方式,导入导出的值都指向同一个内存地址,所以导入值会跟随导出值变化 -
后者会编译成 require/exports
来执行的
AMD
AMD
是由RequireJS
提出的
// AMD
define(['./a', './b'], function(a, b) {
a.do()
b.do()
})
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
var b = require('./b')
b.doSomething()
})
30 箭头函数的特点
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
箭头函数其实是没有
this
的,这个函数中的this
只取决于他外面的第一个不是箭头函数的函数的this
。在这个例子中,因为调用a
符合前面代码中的第一个情况,所以this
是window
。并且this
一旦绑定了上下文,就不会被任何代码改变
31 ES5 / ES6 的继承除了写法以外还有什么区别
-
ES5 的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到 this 上(Parent.apply(this)) -
ES6 的继承机制完全不同,实质上是先创建父类的实例对象 this(所以必须先调用父类的 super()方法),然后再用子类的构造函数修改 this。 -
ES5 的继承时通过原型或构造函数机制来实现。 -
ES6 通过 class 关键字定义类,里面有构造方法,类之间通过 extends 关键字实现继承。 -
子类必须在 constructor 方法中调用 super 方法,否则新建实例报错。因为子类没有自己的 this 对象,而是继承了父类的 this 对象,然后对其进行加工。如果不调用 super 方法,子类得不到 this 对象。 -
注意 super 关键字指代父类的实例,即父类的 this 对象。 -
注意:在子类构造函数中,调用 super 后,才可使用 this 关键字,否则报错。function 声明会提升,但不会初始化赋值。Foo 进入暂时性死区,类似于 let、const 声明变量
32 全局作用域中,用 const 和 let 声明的变量不在 window 上,那到底在哪里?如何去获取?
// 在 ES5 中,顶层对象的属性和全局变量是等价的,var 命令和 function 命令声明的全局变量,自然也是顶层对象。
var a = 12;
function f(){};
console.log(window.a);
// 12console.log(window.f);
// f(){}
// 但 ES6 规定,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性,但 let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。
let aa = 1;
const bb = 2;
console.log(window.aa);
// undefinedconsole.log(window.bb);
// undefined
// 在哪里?怎么获取?通过在设置断点,看看浏览器是怎么处理的:
//通过上图也可以看到,在全局作用域中,用 let 和 const 声明的全局变量并没
//有在全局对象中,只是一个块级作用域(Script)中怎么获取?在定义变量的块级作用域中就能获取啊,既然不属于顶层对象,那就不加 window(global)呗。
let aa = 1;
const bb = 2;
console.log(aa);
// 1console.log(bb);
// 2
33 介绍下 Set、Map、WeakSet 和 WeakMap 的区别
Set
-
成员不能重复 -
只有健值,没有健名,有点类似数组 -
可以遍历,方法有 add
,delete
,has
weakSet
-
成员都是对象 -
成员都是弱引用,随时可以消失。 可以用来保存 DOM 节点,不容易造成内存泄漏 -
不能遍历,方法有 add
,delete
,has
Map
-
本质上是健值对的集合,类似集合 -
可以遍历,方法很多,可以干跟各种数据格式转换
weakMap
-
直接受对象作为健名( null
除外),不接受其他类型的值作为健名 -
健名所指向的对象,不计入垃圾回收机制 -
不能遍历,方法同 get
,set
,has
,delete
原文始发于微信公众号(消失的程序员):ES6 面试题精选4
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/250716.html