手写 - call、apply、bind

call、apply、bind使用

代码示例:

  1. var Tom = {
  2. name: "tom",
  3. fn: function (from, to) {
  4. console.log(`name: ${this.name}, from: ${from}, to: ${to}`)
  5. },
  6. }
  7. var Eric = {
  8. name: "eric",
  9. }
  10. Tom.fn("成都", "上海") // name: tom, from: 成都, to: 上海
  11. Tom.fn.call(Eric, "成都", "上海") // name: eric, from: 成都, to: 上海
  12. Tom.fn.apply(Eric, ["成都", "上海"]) // name: eric, from: 成都, to: 上海
  13. Tom.fn.bind(Eric, "成都", "上海")() // name: eric, from: 成都, to: 上海

相同:

  • 可以让一个对象使用另一个对象的方法,并将 this 指向当前对象。
  • 第一个参数都是 this 的指向对象。

    不同:

  • call 的参数如普通函数。

  • apply 的所有函数都是第二个参数。
  • bind 返回值是一个函数。还需要考虑实例化后对原型链的影响。

    call

    1. Function.prototype.myCall = function (target, ...args) {
    2. const key = Symbol()
    3. target[key] = this
    4. const res = target[key](...args)
    5. target[key] = null
    6. return res
    7. }

    aplly

    1. Function.prototype.myApply = function (target, args) {
    2. const key = Symbol()
    3. target[key] = this
    4. if (args) {
    5. res = target[key](args)
    6. } else {
    7. res = target[key]()
    8. }
    9. target[key] = null
    10. return res
    11. }

    bind

    1. Function.prototype.bind = function (target, ...bindArgs) {
    2. const fn = this
    3. function resFn(...resArgs) {
    4. const resThis = this instanceof resFn ? this : target
    5. return fn.call(resThis, ...bindArgs, ...resArgs)
    6. }
    7. function tmp() {}
    8. tmp.prototype = fn.prototype
    9. resFn.prototype = new tmp()
    10. return resFn
    11. }

    手写 - new

    new做的事情:

  • 创建一个全新的对象。

  • 执行 prototype 链接。
  • 使 this 指向新创建的对象。
  • 若函数没有返回对象类型,则 new 返回该对象的引用。

    代码:

    1. function New(fn, ...args) {
    2. let obj = {
    3. __proto__: fn.prototype,
    4. }
    5. const res = fn.call(obj, ...args)
    6. if (res && (typeof res === "object" || typeof res === "function")) {
    7. return res
    8. }
    9. return obj
    10. }

    手写 - instanceOf

    instanceOf 用来判断一个对象的 prototype 是否在另外一个对象的原型链上。

    1. function isInstanceOf(child, parent) {
    2. const parentPrototype = parent.prototype
    3. let childProto = child.__proto___
    4. while (true) {
    5. // 全检测完了,没找到
    6. if (childProto === null) return false
    7. if (childProto === parentPrototype) return true
    8. childProto = childProto.__proto___
    9. }
    10. }

    方法 - 深拷贝

    1. function clone(obj) {
    2. if (typeof obj === "object") {
    3. const res = Array.isArray(obj) ? [] : {}
    4. for (const key in obj) {
    5. if (Object.hasOwnProperty.call(obj, key)) {
    6. obj[key] = clone(obj[key])
    7. }
    8. }
    9. return res
    10. }
    11. return obj
    12. }

    方法 - 数组去重

    原生js 去重

    1. const unique = arr => {
    2. const uniqueArray = []
    3. for (let i = 0; i < arr.length; i++) {
    4. if (uniqueArray.indexOf(arr[i]) === -1) {
    5. uniqueArray.push(arr[i])
    6. }
    7. }
    8. return uniqueArray
    9. }

    ES6 去重

    1. const unique = arr => {
    2. return [...new Set(arr)]
    3. }

    方法 - 防抖(debounce)

    防抖(debounce),指事件触发后,在n秒内只能触发一次,若中途再次触发,则会重新计算函数的延迟时间。直到时间到达后再触发。分为了两种:

  • 立即执行:多次触发事件,第一次会立即执行函数。之后在设定的时间内触发的事件不会触发。

  • 非立即执行:在设定的时间内多次触发事件,只会在最后一次触发,等待设定时间结束时执行。

    1. function debounce(fn, wait = 50, immediate) {
    2. let timer = null
    3. return function () {
    4. // 如果不为null,清空定时器
    5. if (timer) clearTimeout(timer)
    6. if (immediate) {
    7. if (!timer) fn.apply(this, arguments)
    8. setTimeout(() => {
    9. timer = null
    10. }, wait)
    11. } else {
    12. timer = setTimeout(() => {
    13. fn.apply(this, arguments)
    14. }, wait)
    15. }
    16. }
    17. }

    方法 - 节流(throttle)

    多次触发事件,在指定时间间隔内只会触发一次。

    1. function throttle(fn, wait) {
    2. let prev = new Date()
    3. return function () {
    4. let now = new Date()
    5. if (now - prev > wait) {
    6. prev = now
    7. fn.apply(this, arguments)
    8. }
    9. }
    10. }

    算法 - 斐波那契数列

    1. function fibonacci(n) {
    2. if (n === 1 || n === 2) {
    3. return 1
    4. }
    5. return fibonacci(n - 2) + fibonacci(n - 1)
    6. }
    1. function fibonacci(n) {
    2. let n1 = 1
    3. let n2 = 1
    4. let sum = 1
    5. for (let i = 2; i < n; i++) {
    6. sum = n1 + n2
    7. n1 = n2
    8. n2 = sum
    9. }
    10. }

    算法 - 冒泡排序

    1. function sort(arr) {
    2. for (let j = 0; j < arr.length; j++) {
    3. for (let i = 0; i < arr.length - j; i++) {
    4. if (arr[i] > arr[i + 1]) {
    5. const prev = arr[i]
    6. arr[i] = arr[i + 1]
    7. arr[i + 1] = prev
    8. }
    9. }
    10. }
    11. }

    算法 - 快速排序