Skip to content

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
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 = 0arr = [] 的区别

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)
// [] 释放内存
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('&')
}
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()
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
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())
// 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
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
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
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
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)
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)