ES6--ES11新特性面试题整理,更新中。。。

ES6面试题

  • let
  • const
  • 变量的解构赋值
    • 数组的解构
    • 对象的解构
  • 模板字符串
  • 简化对象写法
  • 箭头函数
  • 函数参数默认值
  • rest参数
  • 扩展运算符
    • 扩展运算符的应用
  • Symbol(一般用不到)
  • Set
  • Map
  • 数值扩展
  • 对象方法扩展
  • 模块化
    • ES6模块化语法
  • ES7新特性
    • includes
    • ** 幂运算
  • ES8新特性
    • async 和 await
      • async函数
      • await表达式
    • 对象的方法扩展
  • ES9
    • 对象展开
    • 正则扩展-命名捕获分组

let

1:变量声明不能重复
2:块级作用域
3:不存在变量提升
4:不影响作用域链

const

1:用于声明常量,一定要赋初始值
2:一般用大写(潜规则)
3:常量的值不能修改
4:块级作用域
5:对于数组或对象的元素的修改,不算对常量的修改,不会报错

变量的解构赋值

数组的解构

const F3 = ['白素贞', '小青', '许仙'];
let [bai, qing, xu] = F3;
console.log(bai) // 白素贞
console.log(qing) // 小青
console.log(xu) // 许仙

对象的解构

const dong = {
    name: "东子",
    wife: "奶茶妹妹",
    age: 40,
    save: function () {
        console.log("捐东西")
    }
}
let {name,wife,age,save} = dong;
console.log(name,wife,age); // 东子 奶茶妹妹 40
console.log(save); // ƒ () { console.log("捐东西") }
save(); // 捐东西

模板字符串

1:内容中可以直接出现换行符
2:变量拼接

let age = 80;
let out = `我今年${age}岁了。`

简化对象写法

ES6里面允许在大括号里面,直接写入变量和函数,作为对象的属性和方法

let name = "兵长";
let kill = function (){
	console.log("我能砍巨人")
}

const liweier= {
	name,
	kill,
	fly () {
		console.log("我能飞")
	}
}
上面写法等价于
const liweier= {
	name: name,
	kill: kill,
	fly: function () {
		console.log("我能飞")
	}
}

箭头函数

let fn = (a,b) => {return a + b}

1:this 是静态的,始终指向函数声明时所在作用域下的 this 的值
2:不能作为构造函数实例化对象

let Fn = (name, age) => {
	this.name = name
	this.age = age
}
let fn = new Fn('小明', 29); // 报错
	// Uncaught TypeError: Fn is not a constructor
    // at :1:10

3:不能使用arguments变量

let fn = () => {console.log(arguments)}
fn(1,2) // 报错,找不到arguments
	// VM845:1 Uncaught ReferenceError: arguments is not defined
    // at fn (:1:29)
    //at :1:1

4:关于箭头函数的简写

1):省略小括号,当形参只有一个的时候
let add = n => {
	return n + n
}
2):省略花括号,当代码体只有一条语句的时候,此时,return 也必须省略,而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(2)) // 4

实践一下吧:

需求:返回数组中的偶数
let arr = [1,2,3,4,5,6,6,7];
let result = arr.filter(item => item%2 === 0) // [2, 4, 6, 6]

函数参数默认值

1:形参初始值,具有默认值的参数一般放在最后

function add (a, b, c=10) {
	return a + b + c
}
let result  = add(1,2) // 13

2:与结构赋值结合

function connect({host="127.0.0.1", username}) {
	console.log(host, username)
}
connect({host: "192.168.1.1", username: "root"})

rest参数

ES6引入rest参数,用于获取函数的实参。用来代替arguments

// ES5的arguments
function data () {
	console.log(arguments)
}
data(1,2,3)
// ES6中的rest参数
function data (...args) {
	console.log(args) // [1,2,34]
}
data(1,2,34)
// rest 参数必须放到最后
function data (a,b,...args) {
	console.log(a) // 1
	console.log(b) // 2
	console.log(args) // [3,4,5]
}
data(1,2,3,4,5)

扩展运算符

扩展运算符能将 数组 转化为逗号分隔的参数序列

const tfboys = ['易烊千玺', '王源', '王俊凯'];
function data () {
	console.log(arguments)
}
data(...tfboys) // 相当于 data('易烊千玺', '王源', '王俊凯')

扩展运算符的应用

1:数组的合并

const arr1 = [1,2]
const arr2 = [3,4]
// ES5 写法
const newArr = arr1.concat(arr2)
// ES6 写法
const newArr = [...arr1, ...arr2]

2:数组的克隆(浅克隆)

var arr = [1,2,3];
var arrCopy = [...arr]; // [1, 2, 3]

3:将伪数组转为真正的数组

const divs = document.querySelectorAll('div');
const divAll = [...divs]
// Es6 数组去重
const arr = [1,1,2,3,3]
const result = [...new Set(arr)]; // [1,2,3]const result = Array.from(new Set(arr)); // [1,2,3]

Symbol(一般用不到)

ES6引入了一种新的数据类型Symbol(JS的第7种数据类型,原来的6种有:undefined,null,number,string,boolean,object),表示独一无二的值,是一种类似于字符串的数据类型。
特点:
1:Symbol的值是唯一的,用来解决命名冲突的问题。
2:Symbol不能与其他数据进行运算。
3:Symbol定义的对象属性不能使用for…in循环遍历

Set

ES6提供的新的数据结构,类似于数组,但是里面的每个值都是唯一的。

let s = new Set([1,2,3])
// 元素个数
s.size // 3
// 新增元素
s.add(4) // Set(4) {1, 2, 3, 4}
// 删除元素
s.delete(3) // true
console.log(s) // Set(3) {1, 2, 4}
//检测
s.has(2) // true
// 清空
s.clear()

Set实践
let arr = [1,1,2,3,4,4,5,3]
let arr2 = [4,5,6,5,6]
1:数组去重
2:求交集
3:求并集
4:求差集

// 1: 去重
let arr = [1,1,2,3,4,4,5,3];
let result = [... new Set(arr)]
// 2:交集
let result = [...new Set(arr)].filter(item => new Set(arr2).has(item)); // [4,5]
// 3:并集
let result = [...new Set([...arr, ...arr2])];
// 4:差集(arr不含arr2的元素)
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item))); // [1, 2, 3]

Map

类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值都可以作为键

// 声明
let m = new Map();
// 添加元素
m.set('name', '孙杨');
m.set('swim', function () {console.log("会游泳")})
let key = {
	des: "这是一个对象"
}
m.set(key, "对象也能作为键")
console.log(m)
// size
m.size // 3
// 删除
m.delete('name') // true
// 获取
m.get(key) // "对象也能作为键"
// 清空
m.clear()
// 遍历
for (let v of m) {console.log(v)}

数值扩展

1:Number.EPSILON 是 js中表示的最小精度

console.log(0.1+0.2 === 0.3) // false
function equl(a, b) {
	if (Math.abs(a-b) < Number.EPSILON) {
		return true;
	} else {
		return false;
	}
}
equl(0.1+0.2, 0.3) // true

2:二进制、八进制

let num = 0b01010; // 二进制
console.log(num) // 10
let num = 0o777; // 八进制
console.log(num) // 511
let num = 100; // 十进制
console.log(num); // 100
let num = 0xff; // 十六进制
console.log(num); // 255

3:Number.isFinite 检测一个数字是否为有限数

Number.isFinite(100); // true
Number.isFinite(100/0); // false

4:Number.isNaN 检测一个值是否为NaN
isNaN()是ES5的方法,Number.isNaN()是ES6的方法
可能有一些童鞋会认为 isNaN直译为“是不是 NaN”,其本意不是,isNaN本意是通过Number方法把参数转换成数字类型,如若转换成功,则返回false,反之返回true,它只是判断参数是否能转成数字,不能用来判断是否严格等于NaN。,如果要判断某个值是否严格等于NaN不能用这个方法

ES6提供了Number.isNaN方法用来判断一个值是否严格等于NaN,它会首先判断传入的值是否为数字类型,如不是,直接返回false。
区别:
isNaN方法首先转换类型,而Number.isNaN方法不用;
isNaN不能用来判断是否严格等于NaN,Number.isNaN方法可用
本知识点引用地址链接

Number.isNaN(123)// false
Number.isNaN("asd") // false
let a= 'as';
Math.floor(a);//NaN
Number.isNaN(Math.floor(a)); // true

5:Number.parseFloat 和 Number.parseInt

Number.parseFloat('2.22asd') // 2.22
Number.parseInt('123asd') // 123

6:Number.isInteger 判断十足是否为整数

Number.isInteger(3.3) // false
Number.isInteger(3) // true

7:Math.trunc 舍去数值小数部分

Math.trunc(3.33) // 3

8:Math.sign 判断数值 大于0,等于0还是小于0

Math.sign(-11) // -1
Math.sign(0) // 0
Math.sign(112) // 1

对象方法扩展

1:Onject.is 判断两个值是否完全相等(类似于 === )

Object.is(12,12)// true
Object.is(NaN,NaN) // true
NaN === NaN // flase

2:Object.assign 对象合并

const obj1 = {
	name: '小明',
	age: 22,
	weight: '66kg'
}
const obj2 = {
	name: '小花',
	age: 18,
	height: '165cm'
}
Object.assign(obj1, obj2) // {name: "小花", age: 18, weight: "66kg", height: "165cm"}
// 参数可以传多个,如有同名,则后面的会把前面的覆盖
const obj3 = {
	name: "小红",
	age: 88
}
Object.assign(obj1, obj2, obj3) // {name: "小红", age: 88, weight: "66kg", height: "165cm"}

模块化

模块化是指将一个较大的程序文件,拆分成一个个小文件,最后又将这些小文件组合起来。
优点:
1):防止命名冲突。每个小文件之间都是独立的,声明相同变量时不会产生冲突。
2):代码复用。
3):利于维护。

ES6模块化语法

export:规定模块的对外接口
import:引用其他模块提供的功能

暴露方式有三种:

// 分别暴露
export let name = "小明";
export function fn () {
	console.log("这是一个方法")
}

// 统一暴露
let name = "xiaoming";
function fn () {
	console.log("这是方法")
}
export {name, fn};

// 默认暴露
export default {
	name: "小明",
	fn: function () {
		console.log("这是一个方法")
	}
}

导入的方式:

//1: 通用导入
import * as test from "../../xxx.js"
//2: 结构赋值形式
import {name, fn} from "../../xxx.js"
// 可以取别名
import {name as xiaoMing, fn} from "../../xx.js"
// 导入default类型的
import {default as test} from "../xxx.js"
//3:简便形式(只针对默认暴露)
import test from "../xx.js"

ES7新特性

includes

const arr = ["小明", "小红", "小华"];
arr.includes("小明"); // true
arr.includes("小白"); // false

** 幂运算

console.log(2 ** 10); // 1024
// 等同于Math.pow
console.log(Math.pow(2, 10));

ES8新特性

async 和 await

async函数

// async函数
async function fn () {
	// 返回一个字符串
	// return "返回的数据"
	// 如果返回的不是一个promise类型的对象,返回的结果就是一个成功的promise对象
	// 抛出错误,则返回一个失败的promise对象
	// throw "错误拉"
	// 如果返回一个promise对象
	return new Promise((resolve, reject) => {
		resolve("这是成功的值");
		reject("这是失败的值")
	})
}
let result = fn();
console.log(result);
// 因为返回的是promise类型的对象,所以可以使用.then
result.then(res => {
	console.log(res)
}).catch(err => {
	console.error(err)
})

await表达式

1:await 必须写在async函数中
2:await右侧一般为promise对象
3:await返回的是promise成功的值
4:await如果返回失败,就是抛出异常,用try…catch捕获处理

创建一个promise对象
const p = new Promise((resolve, reject) => {
	resolve("获取到成功的数据");
	reject("报错了")
})
// await 要放在async函数中
async function test () {
	try {
		let result = await p;
		console.log(result);
	} catch(e){
		console.error(e)
	}
}
// 调用函数
test();

发送 AJAX请求

// 发送ajax请求,返回promise
function sendAjax (url) {
	return new Promise((resolve, reject) => {
		// 1: 创建对象
		const x = new XMLHttpRequest();
		// 2:初始化
		x.open("get", url);
		// 3:发送
		x.send();
		// 4:事件绑定
		x.onreadystatechange = function () {
			if (x.readyState === 4) {
				if (x.status >= 200 && x.status < 300) {
					// 成功
					resolve(x.response);
				} else {
					// 失败
					reject(x.status);
				}
			}
		}
	})
}
// promise then测试
sendAjax("https://img-home.csdnimg.cn/data_json/toolbar/toolbar0812.json").then(res => {
	console.log(res)
}).catch(err => {
	console.error(err)
})
// async await测试
async function test() {
	let res = await sendAjax("https://img-home.csdnimg.cn/data_json/toolbar/toolbar0812.json");
	console.log(res)
}
test()

对象的方法扩展

const obj = {
	name: "小明",
	cars: ["宝马", "奔驰", "奥迪"],
	hobby: ["篮球", "swim"]
}
// 获取对象所有的键
console.log(Object.keys(obj)); //["name", "cars", "hobby"]
// 获取对象所有的值
console.log(Object.values(obj)); 
// 0: "小明"
// 1: (3) ["宝马", "奔驰", "奥迪"]
// 2: (2) ["篮球", "swim"]

ES9

对象展开

在ES9中提供了像数组一样的rest参数和扩展运算符

function test ({name, age, ...other}) {
	console.log(name); // 小明
	console.log(age); // 30
	console.log(other); // {height: "180cm", weight: "70kg"}
}
test({name:"小明", age:30, height:"180cm", weight:"70kg"});

const a = {name: "小红"};
const b = {age: 20};
const c = {cars: ["宝马", "法拉利"]};
// 对象的合并
const all = {...a, ...b, ...c};
console.log(all); // {name: "小红", age: 20, cars: Array(2)}

正则扩展-命名捕获分组

// ES5 方式
let str = "百度知道";
const reg = /(.*)<\/a>/;
const res = reg.exec(str);
console.log(res);
// 0: "百度知道"
// 1: "http://www.baidu.com"
// 2: "百度知道"
// groups: undefined
// index: 0
// input: "百度知道"

// 这个时候我们要去获取url和文本的话,可以用下标去获取,但是不方便维护,以后如果要获取字符串中的其他值,很可能要去改下标
console.log(res[1]); // http://www.baidu.com
console.log(res[2]); // 百度知道

// ES9中的命名捕获
let str = "百度知道";
const reg = /(?.*)<\/a>/;
const res = reg.exec(str);
console.log(res);
// 0: "百度知道"
// 1: "http://www.baidu.com"
// 2: "百度知道"
// groups: {url: "http://www.baidu.com", text: "百度知道"}
// index: 0
// input: "百度知道"

// 区别,捕获到的url和text会在groups中,这是我们就可以获取groups中的值
console.log(res.groups.url); // http://www.baidu.com
console.log(res.groups.text); // 百度知道

你可能感兴趣的:(面试,javascript,es6,面试)