Part 1 JavaScript 深度剖析
模块一 ES6+ 与 TypeScript
任务一 ECMAScript 新特性
1、var、let、const 的最佳实践
- 不用 var,主用 const,配合 let
2、对象结构赋值的别名和默认值
const obj = { name: 'pzh', age: 18 }
const { name: objName = 'abc' } = obj
console.log(objName) // pzh
3、模板字符串的标签函数
标签函数用来处理模板字符串,可以判断,重新组合之后输出字符串
const name = 'tom'
const gender = '0'
function myTagFunc(strings, name, gender){
const sex = gender === '0' ? 'male' : 'female'
return strings[0] + name + strings[1] + sex + strings[2]
}
const result = myTagFunc`hey,${name} is a ${gender}.`
console.log(result) //hey,tom is a male.
4、字符串的扩展方法
- includes,是否包含,返回布尔值
- startsWith,是否以之为开头,返回布尔值
- endsWith,是否以之为结尾,返回布尔值
const msg = 'Error, this is not a name'
console.log(msg.includes('name')) // true
console.log(msg.startsWith('Error')) // true
console.log(msg.endsWith('sex')) // false
5、函数参数默认值
参数默认值用来替代短路运算符做默认设置
<!-- 短路写法 -->
function foo(enable){
// enable = enable || true,传入 false 时,输出 true,应该输出false
enable = enable === undefined ? true : enable
console.log(enable)
}
foo() // true
foo(false) // false
<!-- 默认值写法 -->
function foo(enable = true){
console.log(enable)
}
foo() // true
foo(false) // false
6、剩余参数
... 剩余参数出现在函数入参的最后一位,并且只能够使用一次。(...后面接数组)
function foo(first, ...args){
console.log(args)
}
foo(1,2,3,4) // [2,3,4]
7、箭头函数与 this
8、Proxy 与 defineProperty
- defineProperty 只能监视对象属性的读写
- Proxy 能监视更多对象的操作(如:delete操作,方法的调用)
- Proxy 能更好监视数组对象
Proxy 对象内部的13个方法
| handler 方法 | 触发方式 |
|---|---|
| get | 读取某个属性 |
| set | 写入某个属性 |
| has | in 操作符 |
| deleteProperty | delete 操作符 |
| getPrototypeOf | Object.getPrototypeOf() |
| setPrototypeOf | Object.setPrototypeOf() |
| isExtensible | Object.isExtensible() |
| preventExtensions | Object.preventExtensions() |
| getOwnPropertyDescriptor | Object.getOwnPropertyDescriptor() |
| defineProperty | Object.defineProperty() |
| ownKeys | Object.getOwnPropertyNames() 或者 Object.getOwnPropertySymbols |
| apply | 调用一个函数 |
| construct | 用 new 调用一个函数 |
9、Reflect
Reflect 内部封装了一系列对对象的底层操作,Reflect 的成员方法就是 Proxy 处理对象的默认实现。
const obj = {
name: 'pzh',
age: 18
}
const objProxy = new Proxy(ojb, {
get(target, property){
console.log('自定义的处理逻辑')
return Reflect.get(target, property)
}
})
// 如果Proxy对象中没有定义,默认就是使用的 Reflect 的方法。
为什么要有 Reflect 对象
- 统一提供了一套用于操作对象的 API,而不是混合使用in、delete操作符和Object的方法
最佳实践:慢慢的要培养统一使用Reflect对象的方法,而不是混用。
10、Promise
11、class 类
function Person(name){
this.name = name
}
Person.prototype.say = function(){
console.log(`Hi, this is ${this.name}`)
}
// 等价于
class Person(){
constructor(name){
this.name = name
}
say(){
console.log(`Hi, this is ${this.name}`)
}
}
const p = new Person('lilei')
p.say()
12、静态方法
- 静态方法,挂载在构造函数上的方法
- 实例方法,挂载在构造函数的对象上的方法
class Person(){
constructor(name){
this.name = name
}
say(){
console.log(`Hi, this is ${this.name}`)
}
static create(name){
return new Person(name)
}
}
const tom = Person.create('tom')
tom.say()
13、类的继承(super)
class Student extends Person(){
constructor(number){
super(name)
this.number = number
}
hello(){
super.say()
console.log(`My school number is ${this.number}`)
}
}
const s = new Student('jack', 100)
s.hello()
//Hi, this is jack
//My school number is 100
14、Set
Set 对象内的元素不能重复。Set 内置的方法
- add()
- has()
- delete()
- clear()
const arr = [1,2,3,4,1,2]
const result = Array.from(new Set(arr))
const result1 = [...new Set(arr)]]
console.log(result) // [1,2,3,4]
console.log(result1) // [1,2,3,4]
15、Map
Map 对象可以用任意值作为键值,普通对象只能使用字符串作为键值
const m = new Map()
const tom = { name: 'tom' }
m.set(tom, 10)
console.log(m) // Map { {name: 'tom'} => 10 }
console.log(m.get(tom)) // 10
16、
模块二 函数式编程与 JS 异步编程、手写 Promise
任务一 函数式编程范式
1. 函数柯里化
- 当一个函数有多个参数的时候,先传递一部分参数调用它(这部分参数以后永远不变)
- 然后返回一个新的函数接收剩余的参数,返回结果
总结:
- 柯里化可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的信函上
- 这是一种对函数参数的“缓存”
- 让函数变得更灵活,让函数的粒度更小
- 可以把多元函数转换成一元函数,可以组合使用函数产生强大的功能
例一:
function getSum(a,b,c){
return a + b +c
}
const curried = _.curry(getSum)
console.log(curried(1,2,3))
console.log(curried(1)(2,3))
console.log(curried(1,2)(3))
例二:
function checkAge(min){
return function(age){
return age >= min
}
}
//ES6写法
let checkAge = min => (age=> age >= min)
let checkAge18 = checkAge(18)
let checkAge20 = checkAge(20)
checkAge18(30)
2.lodash 的柯里化方法
const _ = require('lodash')
const checkAge = _.curry(function(min,age){
return age >= min
})
let checkAge18 = checkAge(18)
let checkAge20 = checkAge(20)
checkAge18(30)
3. 缓存计算结果,不用每次计算,可用于耗时的计算,用 _.memoize() 函数。
const _ = require('lodash')
function getArea(r){
console.log(r)
return Math.PI * r * r
}
let getAreaWithMemoize = _.memoize(getArea)
console.log(getAreaWithMemoize(4))
console.log(getAreaWithMemoize(4))
console.log(getAreaWithMemoize(4))