翻译”:[{“文本”:”
通过 20 道棘手的 ES6 笔试题提高您的 JS 技能n
n
为什么在大多数情况下使用箭头函数?
n
问题4:将Symbol带到ES6的目的是什么?
n
主题:JavaScript
n
困难:
n
符号是一个新的特殊对象,可用作对象中的唯一属性名称。将字符串替换为 Symbol 可避免不同模块属性之间的冲突。您还可以将符号设为私有,以便尚未直接访问符号的人无法访问其属性。
n
符号是 JS 的新基本数据类型。与数字、字符串和布尔基元类型一样,Symbol 具有创建它们的函数。与其他基元类型不同ecmascript6 箭头函数,符号没有文字度量句模式。创建它们的唯一方法是按以下方式使用 Symbol 构造函数
n
let symbol = Symbol();
n
问题 5:ES6 中扩展语法有什么用?它与其余(其余)语法有何不同?
n
主题:JavaScript
n
困难:
n
ES6 的扩展句型在以函数方式编码时特别有用,因为它们可以轻松创建链表或对象的副本,而无需求助于 Object.create、切片或库函数。此功能通常用于.js Redux 和 RX 项目。
n
n
ES6 的 rest 语法提供了一个快捷方式,其中包含要传递给函数的任意数量的参数。
n
与扩展句子的反转一样,它将数据加载并填充到链表中,而不是扩展字段,并且通常用于函数变量以及链表和对象重构。
n
n
Q6:ES6 类和 ES5 函数构造函数有什么区别?
n
主题:JavaScript
n
困难:
n
n
对于简单的构造函数,它们看起来非常相似。
n
构造函数之间的主要区别在于继承的使用。如果我们创建一个继承 Person 类的学生子类并添加一个 studentId 数组,以下是使用的两种形式:
n
n
在 ES5 中使用继承要复杂得多,而 ES6 版本更容易理解和记忆。
n
问题 7: “.call”和“.apply”有什么区别?
n
主题:JavaScript
n
困难:
n调用和 。
apply用于调用函数,第一个参数将用作函数中的this值。但是,.call 将冒号分隔的参数作为下一个参数,而 .apply 将参数链表作为下一个参数。简单助记符:C 用于分隔调用和冒号,A 用于应用和参数字段。
n
n
问题8:为什么要使用ES6类?
n
主题:JavaScript
n
困难:
n
选择使用类的一些原因:
n
请考虑以下代码:
n
n
使用 ES6 执行上述操作:
n
n
问题 9:在 JS 中定义枚举的首选句子模式是什么
n
主题:JavaScript
n
困难:
n
您可以在 Object.freeze 中实现枚举
n
n
或
n
n
但是,这会阻止它们为变量赋值:
n
let day = DaysEnum.tuesday
day = 298832342 // 不会报错
n
问题10:解释“Object.freeze()”和“const”之间的区别
n
主题:JavaScript
n
困难:
n
const 和 Object.freeze 是两个完全不同的概念。
n
const 声明一个只读变量,一旦声明,就无法更改常量的值:
n
n
Object.freeze适用于值,更具体地说,适用于对象值ecmascript6 箭头函数,这使得对象不可变,即其属性无法修改。
n
n
Q11:JS有哪些改进
?n
主题:JavaScript
n
困难:
n促销是指
JS解释器将所有变量和函数声明连接到当前范围的底部,并且有两种类型的提升
n
一旦 var(或函数声明)出现在作用域中,该声明就会被视为属于整个作用域,并且可以在任何地方访问。
n
n
问题 12:解释原型模式
n
主题:JavaScript
n
困难:
n原型
模式不是创建未初始化的对象,而是返回使用从原型或示例对象复制的值初始化的对象。原型模式也称为属性模式。
n
原型模式有用的一种有用情况是使用与数据库中的默认值匹配的值初始化业务对象。原型对象保留默认值,这些默认值将复制到新创建的业务对象。
n传统语言很少使用原型模式,
但 JavaScript 作为一种原型语言,在构建新对象及其原型时使用这些模式。
n
问题13:ES6中的临时死区是什么
n
主题:JavaScript
n
困难:
n
在 ES6 中,let 和 const,就像 var、class 和函数一样,将被提出,只是在进入范围和声明之间的一段时间内无法访问它们,这是一个临时死区 (TDZ)。
n
n
问题 14:何时不使用箭头函数?列举三个或更多示例
n
主题:JavaScript
n
困难:
n
在某些情况下,不应使用箭头函数:
n
Q15: WeakMa p 在 ES6 中的实际用途是什么?
n
主题:JavaScript
n
困难:
n
弱图提供了一种在不影响垃圾回收的情况下从外部丰富对象的方法。当您想要增强对象但无法增强对象时,可以应用 WeakMap,因为它是封闭的或来自外部源。
n
弱图仅适用于 ES6 或更高版本。弱映射是键和值对的集合,其中键必须是对象。
n
n
关于WeakMaps的有趣之处在于它包含对地图内部键的弱引用。弱引用意味着如果一个对象被销毁,垃圾回收器将从 WeakMap 中删除整个条目,从而释放视频内存。
n
Q16: 解释为什么以下方法不能用作IIFE,需要哪些修改才能使其成为IIFE?
n
主题:JavaScript
n
困难:
n
function foo(){ }();
n
IIFE 代表立即调用的函数表达式。JS解析器读取函数foo(){}();作为函数 foo(){} 和 ();,前者是函数声明,后者(一对括号)是在不指定名称的情况下调用函数的尝试,因此它会引发未捕获的语法错误:意外的令牌异常。
n
我们可以使用 void 运算符:void function foo(){ }();。不幸的是,这种方法存在问题。给定表达式的计算始终是未定义的,因此如果 IIFE 函数具有返回值,则无法使用它,如下所示:
n
n
问题 17:我可以将模块模式的使用与构造函数/原型模式进行比较吗?
n
主题:JavaScript
n
困难:
n
模块模式通常用于命名空间,其中单个实例用作存储以对相关函数和对象进行分组。这是一个与原型设计不同的用例,它们彼此没有敌意,我们可以同时使用它们(例如,将构造函数放入模块并使用新的MyNamespace.MyModule.MyClass(参数))。
n
构造函数和原型是实现类和实例的逻辑方法之一。它们与模型不完全对应,因此通常需要选择特定的方案或辅助方式来实现原型中的类。
n
Q18: ES6 Map 和 WeakMap 有什么区别?
n
主题:JavaScript
n
困难:
n
删除其键/值引用的对象时,它们的行为都不同,如以下代码所示:
n
n
执行前面的 IIFE 使得引用 {x:12} 和 {y:12} 变得困难。垃圾回收器继续运行,从 WeakMa 中移除键 b 引脚,从视频内存中移除 {y:12}。
n
但是,在使用 Map 的情况下,垃圾回收器不会从 Map 中删除针头,也不会从视频内存中删除 {x:12}。
n
WeakMap 允许垃圾回收器执行其收集任务,但 Map 不允许。对于自动编译的映射,数组保留对键对象的引用以避免垃圾回收。但在 WeakMap 中,对关键对象的引用被“弱”保留,这意味着当没有其他对象引用时,它们不会停止垃圾回收。
n
问题19:举一个咖喱函数的例子,说明咖喱化的好处?
n
主题:JavaScript
n
困难:
n
Corryization是一种模式,其中具有多个参数的函数分解为多个函数,当调用连接时,将一次一个将所有必需的参数相加。此技术使使用函数创作的代码更易于阅读和编译。应该注意的是,要实现一个函数,它需要从一个函数开始,然后将其分解为一系列函数,每个函数接受一个参数。
n
n
问题 20:如何在 JS 中“深度冻结”对象
n
主题:JavaScript
n
困难:
n
如果要确保对象被深度冻结,则必须创建一个递归函数来冻结对象类型的每个属性:
n
无深度冻结
n
n
深度冷冻
n
n该
代码部署后可能出现的bug无法实时知道,为了解决这类bug,在日志调试上花费了大量的时间,这里顺便给大家推荐一个好的BUG监控工具Fundebug。
n
源语言:“,”
to“:”en“,”sentLen“:{”srcSentLen“:[37,1,1,23,35,22,12,35,31,47,5,21,49,24,33,14,60,22,12,78,22,5,14,43,5,62,5,14,37,22,12,14,23,5,19,60,14,38,5,38,22,12,43,44,33,5,14,27,22,12,19,15,14,22,14,32,22,12,28,14,10,14,24,15,51,22,12,33,5,38,15,51,5,15,24,22,12,50,55,5,15,44,22,12,55,12,5,38,30,5,55,5,28,22,12,88,5,15,38,22,12,22,39,22,12,35,47,5,25,25,5,15,35,43,5,54,22,12,15,20,117,5,43,15,54,15,37,22,12,46,102,5,25,45,5,39,22,12,43,15,34,41,5,48,5,33,33,54,5,37,22,12,61,26,48,5,15,30,22,12,47,13,15,11,15,81,5,10],“transSentLen”:[73,0,1,53,66,27,20,98,84,129,5,43,92,87,86,14,108,27,20,218,57,5,14,105,5,215,5,14,83,27,20,14,51,5,71,137,14,105,5,72,27,20,130,138,102,5,14,40,27,20,46,36,14,32,14,85,27,20,58,14,10,14,71,15,81,27,20,66,5,108,15,149,5,15,45,27,20,187,158,5,15,50,27,20,149,48,5,150,104,5,165,5,61,27,20,216,5,15,81,27,20,70,58,27,20,94,136,5,47,83,5,15,104,147,5,124,27,20,15,67,278,5,60,54,140,15,96,27,20,139,208,5,95,162,5,64,27,20,115,15,83,109,5,142,5,90,101,152,5,104,27,20,199,79,161,5,15,52,27,20,148,24,15,19,15,222,4,16]}}]}]
让我们从 ES6 之前存在的问题开始,即 VAR 问题
定义可以重复
变化没有极限ecmascript 6箭头函数,有些事情不会改变,没有常数
没有块级作用域,只有一个函数作用域
可变提示引起的混淆
ES6 添加了两个声明式变量关键字 let 和 const,以解决 ES5 中的问题
让
(1) 让我们只在其块级范围内声明一个变量
1 {
2 let a = 10;
3 var b = 1;
4 }
5 console.log(a); //出错 not defined
6 console.log(b); //1
在 ES5 中,如果要实现块级范围,通常使用 Execute Moment 匿名函数来完成。
1 (function(){
2 var a = 1;
3 }());
4 console.log(a); //出错,not defined
但是有了let,你可以解决这样的问题
(2) 无变量改进
正是这样,变量必须在声明之后使用,否则它会报告错误,与var经典的变量相比,这里有所改进
//let
console.log(a); //出错, not defined
let a = 1;
//var
console.log(a); //undefined
var a =1;
(3) 同一变量不能在同一范围内重复声明,包括 var 和 const 变量的名称
let a = 1;
let a = 1; //出错 let不可重复声明
var b = 1;
let b = 1; //出错 let不可重复声明
const c = 1;
let c = 1; //出错 let不可重复声明
(4)在块级范围内,如果有一个用let命令声明的变量,则变量所在的块对该变量有一个封闭的作用域,即该变量忽略同名的外部变量。由于没有变量改进,因此在声明之前不能在此块中使用变量。
var a = 1;
if(true){
a = 2; //出错 not defined
let a;
}
var a = 1;
if(true){
a = 2; //var允许重复声明,而且变量提升,故a=2正常赋值
var a;
}
常量
const 和 let 之间的区别在于,由
常量不能改变,let 声明的变量可以改变
const name = "";
//name = '2' //报错
//但是也不是都不能变
const person = {
name:""
}
person.name="";
console.log(person)//const实际上保证的,并不是变量的值不得改动,
而是变量指向的那个内存地址所保存的数据不得改动。
//对于简单类型的数据(数值、字符串、布尔值),
值就保存在变量指向的那个内存地址,因此等同于常量。
//但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,
保存的只是一个指向实际数据的指针,
//const只能保证这个指针是固定的(即总是指向另一个固定的地址),//至于它指向的数据结构是不是可变的,就完全不能控制了。因此,
将一个对象声明为常量必须非常小心。
学会使用let在以后推荐声明变量时,可以避免很多不必要的麻烦,常量看个人需求
◆2、符号
ES6 增加了一个基本数据类型:Symbol,因此 ECMAScript 有 6 种基本数据类型:字符串、数字、布尔值、null、undefined、symbol。
//Symbol 的定义不能使用new 他使用Symbol()函数生成
let a = Symbol();
typeof a // "symbol"
//Symbol创建时可以传一个参数,表示对Symbol的描述
let s1 = Symbol('a');
let s2 = Symbol('b');
s1 // Symbol(a)
s2 // Symbol(b)
符号表示唯一值
1 let s1 = Symbol('a');
2 let s2 = Symbol('a');
3
4 //s1===s2 false;5 //既然Symbol的值都不相等
那么可以利用他的特性解决对象里同名覆盖的问题
6
7 let obj = {
8 [Symbol()]: 1
9 };
10 //或者
11 let s = Symbol();
12 let obj = {
13 [s]: 1
14 };
Symbol.for()
有时我们想重用相同的 Symbol 值,而 Symbol.for() 方法就是这样做的。它接受字符串作为参数,然后使用该参数作为名称搜索符号值。如果有,请返回此符号值,否则创建一个以字符串命名的新符号值并全局注册它。
1 let s1 = Symbol.for('a');
2 let s2 = Symbol.for('a');
3
4 s1 === s2 // true
5
6 //两种写法区别
7 Symbol.for("a") === Symbol.for("a") // true
8
9 Symbol("a") === Symbol("a") //false
◆3.解构参数(常用)。
1 let [a,b,c] = [1,2,3]
2 var [a,,c]=[1,2,3];
3 console.log(a+' | '+c); //1 | 3
4 var [a,...b]=[1,2,3];
5 console.log(a+' | '+b);//1 | 2,3
6 console.log(b);//[2, 3]7 // ...将右侧多余的值以数组的形式赋值给左侧变量
rest
8
9 //设置默认值
10 var [a,b,c='default',d='default']=[1,2,3];11 console.log(a+' | '+b+' | '+c+' | '+d);
//1 | 2 | 3 | default
12
13 //找不到的会被赋值为undefined
14 var [a,b,c]=[1,2];15 console.log(a+' | '+b+' | '+c);
//1 | 2 | undefined
对象的解释参数
1 //对象的解构赋值
2
3 let obj={
4 a:1,
5 b:2
6 }
7 let {a,b}=obj;
8 console.log(a+" | "+b);//1 | 2
9
10 //重命名,把obj.a重命名为A
11 let obj={
12 a:1,
13 b:2
14 }
15 let {a:A,b}=obj;
16 console.log(A+" | "+b);//1 | 217 console.log(a);
//Uncaught ReferenceError: a is not defined
18
19 //设置默认值
20
21 let {a=1,b=2}={a:10};
22 console.log(a+" | "+b);//10 | 2
23
24 //字符串也可以解构
25
26 var [a,b,c,d,e]='nihao';
27 console.log(a);//
◆4.函数默认值
1 //es5写法
2 function sum(a,b){
3 b= b||0;
4 console.log(a+b)
5 }
6
7 sum(1)
8
9 //es6
10 function sum(a,b=0){
11 console.log(a+b)
12 }
13 sum(1)
14 function sum(a=2,b=0){
15 console.log(a+b)
16 }
17
18 sum()
◆5.箭头功能(常用)。
箭头函数是匿名函数
1 function show(num){
2 return num*num
3 }
4 var show = function(num){
5
6 return num*num
7 }
89 //如果箭头函数不需要参数或需要多个参数,
就使用一个圆括号代表参数部分。提个参数可以去掉括号
10 var show =(num)=>{
11 return num*num
12 }13 //如果只有一条return语句,可以省略大括号和return
隐式返回
14
15 var show =num=>num*num;
16
17
18
19 //箭头函数的this继承自他的父作用域20 //而且与我们原来普通函数不同,
原来的函数this是调用时动态指定的,
21 //而箭头函数是词法作用域,他里的this是定义时就指定的
而且不会随着调用方式不同而改变
22
23 //如下例子
24 var log_this = ()=>{
25
26 console.log(this)
27 }
28 var log_this = function(){
29
30 console.log(this)
31 }
32
33 var obj = {
34 hobbies:['code','run','paly game'],
35 logHobbies:log_this
36 }
37
38
39 obj.logHobbies()
40
41
42 log_this()
有几点需要注意
函数体中的 this 对象是定义它的对象,而不是使用它的对象。
它不能用作构造函数,即不能使用 new 命令,否则会抛出错误。无法使用
参数对象,该对象在函数体中不存在。如果要使用它,可以将其替换为 REST 参数。
不能使用 yield 命令,因此箭头函数不能用作生成器函数。
◆6.模板字符串(常用)。
事实证明,编写字符串更令人沮丧,尤其是在连接变量时
1 const name="小";
2 const age = 2;
3
4 console.log('ta的名字是'+name+',它今年'+age+'了');5 console.log
('
'+name+'');//这种更难受
6 console.log(`ta的名字是${name},它今年${age}了`)
7 console.log(`${name}`)
8
模板字符串可以嵌套
1 var arr = [{
2 name:"苹果",
3 price:11
4 },{
5 name:"香蕉",
6 price:12
7 }];
8
9
10 var template = `
11
- ${v.name}
14 ${v.price}
15
12 ${arr.map(v=>`
13
16 `).join('')}
17
18 `
19
20 console.log(template)
21
22 document.body.innerHTML = template;
◆7.数组点
差扩展运算符也是一个三点(...)。它类似于 REST 参数的反转ecmascript 6箭头函数,将字段转换为由冒号分隔的参数序列。
1 const a = [1, 2, 3];
2 const b = [4,5,6];
3 const c = [...a] // [1,2,3]
4 //轻松拼接两个数组
5 const d = [...a,...b] // [1,2,3,4,5,6]
6
7
8 //类数组对象变成数组
9 var list=document.getElementsByTagName('a');
10 var arr=[...list];
实际上,不仅可以扩展参数,还可以扩展对象和字符串
1 const obj1 = { a: 111, b: 222 };
2 const obj2 = { c: 333, d: 444 };
3 const merged = { ...obj1, ...obj2 };4 console.log(merged); // ->
{ a: 111, b: 222, c: 333, d: 444 }
5 //或者这样
6 const others = {third: 3, fourth: 4, fifth: 5}
7 const items = { first:1, second:1, ...others }8 items //{ first: 1, second: 2, third: 3, fourth: 4,
fifth: 5 }
9
10
11 //展开字符串
12
13 const str = 'hello'
14 const array_str_ = [...str] //
1 //Array.from方法用于将两类对象转为真正的数组
2 var args = Array.from(arguments);3 var list = Array.from(document.querySelectAll('li'));
1 //这个方法的主要目的,是弥补数组构造函数Array()的不足。
因为参数个数的不同,会导致Array()的行为有差异。
2 Array() // []
3 Array(3) // [, , ,]
4 Array(3, 11, 8) // [3, 11, 8]
5
6 Array.of(3, 11, 8) // [3,11,8]
7 Array.of(3) // [3]
8 Array.of(3).length // 1
◆8、用于回路
1 看一下咱们会的循环方法
2 for 无法循环对象3 for in 存在问题 他会遍历所有可遍历属性
如果为原型加了一些属性,那也会遍历出来
4 forEach 循环数组 无法终止
56 最终es6为了统一,也借鉴了c++,java,python语言引入了for of
循环 作为遍历所有数据结构的统一的方法。
7 for...of循环可以使用的范围包括数组、Set 和 Map 结构、8 某些类似数组的对象
(比如arguments对象、DOM NodeList 对象)、
9 后文的 Generator 对象,以及字符串。
10 -- 对象不能使用for of
1 for(let v of [1,2,3]) {
2 console.log(v); // 1 2 3
3 }
4 let p = document.querySelectorAll("p");
5 for (let x of p) {
6 console.log(x);
7 }
◆9、套
1 //ES6 提供了新的数据结构 Set。它类似于数组,
但是成员的值都是唯一的,没有重复的值。
2
3 const set = new Set([1, 2, 2, 4, 4]);
4 [...set]
5 //用Set 去重非常方便 ,数组去重面试常考题
6
7 [...new Set(arr)]