相信JS的新特性我们都一直在使用,不得不说,每个版本的新特性都能给我们带来不一样的"爽"体验。那么,你知道你使用的JS特性是哪个版本发布的呢?
❝面试官:你都在用哪个版本的JS新特性?蔡姬我:别急,我先总结一番。
❞
那就让我们一起来回顾下那些年使用过的JS特性。
解决之前只有函数才有作用域的问题
{
var a=1
let b=2
const c=3
b=10
c=20 // => Assignment to constant variable
}
a // => 1
b // b is not defined
由此可见,var 声明的变量是没有作用域的,使用 let 后就声明块级作用域了,值得注意的是用 const 声明的变量是不可以修改的
解决变量拼接字符串的繁琐写法
以前写法:
let name = '贩卖前端仔'
const str = '公众号:' + name
ES6之后:
let name = '贩卖前端仔'
const str = `公众号:${name}`
以前写法:
function test(a,b){
if(typeof b === 'undefined'){
b = '我是没有传入的参数'
}
}
ES6写法:
function test(a,b = '我是不传入数据时的默认数据'){
}
解决了this的指向问题。egg:小程序的使用场景
clickEdit(){
setTimeout(() => {
console.log('ES6的箭头函数测试')
}, 1000)
}
创建一个文件,用来向外提供一些方法
const add = (a,b) => a + b
const reduce = (a,b) => a - b
export {add,reduce}
App引入
import {add,reduce} from "./index.js"
console.log(add(1,2)) // => 3
console.log(reduce(2,1)) // => 1
数组解构赋值
const [a,b] = [1,2]
console.log(a,b) // => 1,2
对象解构赋值
let obj={
name:'前端仔',
age:18
}
const {name,age} = obj
console.log(name,age) // =>前端仔,18
rest就是为解决传入的参数个数不一定,它本身是一个数组。用来替代 arguments 对象
function getParams(...params) {
return params.length
}
console.log(getParams()) // => 0
console.log(getParams(2)) // => 1
console.log(getParams(3,6,10)) // => 3
可以通过 class 方式来声明类
class Calculator {
constructor(x, y) {
this.x = x
this.y = y
}
add() {
return this.x + this.y
}
reduce() {
return this.x - this.y
}
}
const fn = new Calculator(1, 2)
console.log(fn.add()) // => 3
console.log(fn.reduce()) // => -1
处理多个请求的先后顺序问题,也避免地狱回调,"金字塔"代码
new Promise((reslove, reject) => {
return setTimeout(() => {
reslove('贩卖前端仔')
// reject('我是出错的数据')
}, 1000)
})
.then((res) => {
console.log(res) // => 贩卖前端仔
})
.catch((err) => {
console.log(err) // => 我是出错的数据
})
setTimeout 模拟前端请求后台数据返回需要1秒的时候,当数据返回后将结果使用 reslove 出去,结果在 then 可以获取到,然后再进行下一步的操作
再举个🌰,前端常用的 axios 插件,它其实也是 return 出一个 promise 对象
axios.get('/user', {
params: {
ID: 12345
}
})
.then((res=>) {
console.log(res)
})
.catch((err)=>{
console.log(err)
})
相比ES6,ES7主要扩展了两个新特性
const number = [1,2,3]
console.log(number.includes(1)) // => true
console.log(number.includes(4)) // => false
console.log(2**3) // => 8
console.log(3**2) // => 9
在方法函数前添加关键字 async ,需要同步执行的程序前添加关键字 await ,即等程序执行完后才继续往下执行
async clickFn(){
const one = await this.One()
const two = await this.Two(one)
}
const options = {
name:'张三',
age:19,
marry:true
}
const {marry,...others} = options
console.log(marry) // => true
console.log(others) // => {name:'张三',age:19}
对象前添加扩展运算符 ... 就会浅拷贝对象属性复制给新的对象,举个🌰
const options = {
name:'张三'
}
const person = {age:19,...options}
console.log(person) // => {age:19,name:'张三'}
由上可见,扩展运算符和rest运算符其实是相反的方法。一个是展开对象属性,一个是合并对象属性
可以采用以下的任意一种声明一个BigInt类型变量
const num = 123456n
const num = BigInt(222222)
以前访问深层次属性的写法:
data() {
return {
obj: {
userInfo: {
name: "hzq",
tel: "1234567778",
other: { name: "hzq2", title: "名字" }
},
title: "哈哈"
},
}
}
//获取对象内部的other对象的name属性值值
mounted(){
console.log(this.obj && this.obj.useInfo && this.obj.userInfo.other && this.obj.userInfo.other.name)
}
//this.obj写的有点累...
使用ES11后:
data() {
return {
obj: {
userInfo: {
name: "hzq",
tel: "1234567778",
other: { name: "hzq2", title: "名字" }
},
title: "哈哈"
},
}
}
//可选链获取对象内部的other对象的name属性值
mounted(){
//简直不要太爽😊
console.log(this.obj?.userInfo?.other?.name)
}
可选链的使用还远远不止获取属性这么简单,它还可以访问 数组
function getLeadingActor(movie) {
return movie.actors?.[0]?.name
}
意犹未尽?再来一个🌰
const arr=[1,2,3]
// 之前的写法
if(arr.length) {
arr.map(res => {
// 处理你的逻辑
})
}
// 可选链的写法
arr?.map(res => {
// 处理你的逻辑
})
我们时常会遇到这样的情形:变量判断为空的时候,我们用三元运算符去给变量设置默认值,是这么写:
let c = a ? a : b
let c= a || b
这两种写法其实是有一个弊端的,它们都会过滤掉所有的假值,如:(0,' ',false),这些值或许是正常情况下有效的输入值,平时实际生产环境可能不会遇到,为此忽略了这个问题
为解决此问题,nulllish 横空出世,用 ?? 表示,它可以在第一项仅为null或undefined时才设置默认值
let c = a ?? b
//等价于
let c = a !== undefined && a !== null ? a : b
🌰不够,我还要
let a = null
let b = a ?? 500 // 500
let c = 0 // 真实有效的输入值
let d =c ?? 9000 // 0
//如果是传统写法
let x = c ? c:9000 // 9000
前端人直呼:"学不动了,拜托各位大佬不要再卷了"
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
面试题
】即可获取文章引用微信公众号"程序员大咖",如有侵权,请联系管理员删除!