JavaScript
学习记录&理解
函数函数柯里化
思路判断当前参数是否小于回调函数参数个数进行递归
js
function curry(fn: () => void) {
return function nest(...args) {
if (args.length < fn.length) {
return function (..._args) {
return nest(...args, ..._args)
}
}
else {
return fn(...args)
}
}
}
function add(a: number, b: number, c: number) {
return a + b + c
}
const curryAdd = curry(add)
curryAdd(1)(2, 2) // 5
数组销毁
arr.length = 0
和 arr = []
的区别
js
let a = [1, 2, 3, 4, 5, 6]
const b = a
a = null
console.log(b)
// [1, 2, 3, 4, 5, 6] 垃圾回收机制不能回收,因为b还保留了引用
a.length = 0
console.log(b)
// [] 释放内存
获取地址参数
把字符串 GET 参数转换为对象
js
function param2Obj(params) {
if (!params)
return {}
return params
.split('&')
.map(item => item.split('='))
.reduce((obj, [key, value]) => {
obj[key] = value
return obj
}, {})
}
function obj2Param(obj) {
return Object.keys(obj)
.map(key => `${key}=${obj[key]}`)
.join('&')
}
手撕 new 操作符
js
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.printName = function () {
console.log(this.name)
}
function mynew(Fun, ...args) {
const obj = {}
obj.__proto__ = Fun.prototype
const result = Fun.apply(obj, args)
return result instanceof Object ? result : obj
}
const p = mynew(Person, 'yang', 18)
console.log(p)
p.printName()
function mynew2(Fun, ...args) {
const obj = Object.create(Fun.prototype)
const result = Fun.apply(obj, args)
return result instanceof Object ? result : obj
}
const p2 = mynew2(Person, 'yang', 18)
console.log(p2)
p2.printName()
原型与原型链
js
function User() {}
User.prototype.constructor === User // true
User.prototype.__proto__.constructor === Object
User.prototype.__proto__.__proto__ === null
const user = new User()
user.__proto__.constructor === User // true
user.__proto__.__proto__.constructor === Object // true
user.__proto__.__proto__.__proto__ === null // true
继承
注意
原型链继承问题原型中包含的引用值所有实例间共享
js
// 1. 原型链继承 通过prototype 赋值
function SuperType() {
this.property = true
}
SuperType.prototype.getSuperValue = function () {
return this.property
}
function SubType() {
this.subproperty = false
}
// 继承SuperType
SubType.prototype = new SuperType()
SubType.prototype.getSubValue = function () {
return this.subproperty
}
const instance = new Subtype()
console.log(instance.getSuperValue())
2.盗用构造函数
注意
不能重用,必须在构造函数中定义方法 子类也不能访问父类原型上定义的方法
js
function SuperType(name) {
this.name = name
this.colors = ['red', 'blue', 'green']
}
function SubType() {
SuperType.call(this, 'Yang')
}
const instance1 = new SubType()
instance1.colors.push('black')
console.log(instance1.colors) // red, blue, green, black
const instance2 = new SubType()
console.log(instance2.colors) // red, blue, green, black
3.组合继承
js
function SuperType(name) {
this.name = name
this.colors = ['red', 'blue', 'green']
}
SuperType.prototype.sayName = function () {
console.log(this.name)
}
function SubType(name, age) {
SuperType.call(this, name)
this.age = age
}
SubType.prototype = new SuperType()
SubType.prototype.sayAge = function () {
console.log(this.age)
}
const instance1 = new SubType('yang', 20)
instance1.colors.push('black')
console.log(instance1.colors) // red, blue, green, black
instance1.sayName() // yang
instance1.sayAge() // 20
const instance2 = new SubType('yang2', 22)
console.log(instance2.colors) // red, blue, green
instance2.sayName() // yang2
instance2.sayAge() // 22
4.原型式继承
js
function object(o) {
function F() {}
F.prototype = o
return new F()
}
const person = {
name: 'Yang',
friends: [1, 2, 3],
}
const antherPerson = object(person)
antherPerson.name = 'Yang2'
antherPerson.friends.push(4)
const yetAntherPerson = Object.create(person)
yetAntherPerson.name = 'Yang3'
yetAntherPerson.friends.push(5)
console.log(person.friends) // 1,2,3,4,5
5.寄生式继承
注意
函数难以重用, 与构造函数模式类似
js
function createAnother(original) {
const clone = Object.create(original) // 通过调用函数创建一个新对象
clone.sayHi = function () {
console.log('Hi')
}
return clone
}
const person = {
name: 'Yang',
friends: [1, 2, 3],
}
const antherPerson = object(person)
antherPerson.sayHi() // Hi
6.寄生式组合继承
js
function object(o) {
function F() {}
F.prototype = o
return new F()
}
// 实现继承的核心函数
function inheritPrototype(subType, superType) {
const prototype = object(superType.prototype) // 创建对象
prototype.constructor = subType // 增强对象
subType.prototype = prototype // 赋值对象
}
// 设置父类
function SuperType(name) {
this.name = name
this.colors = ['red', 'blue', 'green']
SuperType.prototype.sayName = function () {
console.log(this.name)
}
}
// 设置子类
function SubType(name, age) {
// 构造函数式继承--子类构造函数中执行父类构造函数
SuperType.call(this, name)
this.age = age
}
SubType.prototype = new SuperType()
SubType.prototype.constructor = SubType
SubType.prototype.sayAge = function () {
console.log(this.age)
}
// 核心:因为是对父类原型的复制,所以不包含父类的构造函数,也就不会调用两次父类的构造函数造成浪费
inheritPrototype(SubType, SuperType)
// 添加子类私有方法
SubType.prototype.sayAge = function () {
console.log(this.age)
}
const instance = new SubType('Yang', 18)
console.dir(instance)