创建一个函数,调用func时,this绑定到创建的新函数,并且start之后的参数作为数组传入

本文介绍如何创建一个函数,当调用这个函数(如func)时,'this'上下文将绑定到新函数,并且在'start'后的所有参数将作为数组传递。这种方法常用于构建可复用的函数,特别是在处理事件处理程序或需要控制this上下文的情况下。
/**
 * 创建一个函数,调用func时,this绑定到创建的新函数,并且start之后的参数作为数组传入
 * Creates a function that invokes `func` with the `this` binding of the
 * created function and arguments from `start` and beyond provided as an array
 * @param {Function} func The funtion to apply a rest parameter to
 * @param {number} [start=func.length-1] The start position of the rest parameter
 * @returns {Function} Returns the new function
 * @example
 * const func = (one, two) => {
 *  console.log(one, "one")
 *  console.log(two, "two")
 * }
 * const say = rest(func)
 * say(1, 2, 3, 4)
 *
 * // => 1 "one"
 * // => [2, 3, 4] "two"
 *
 * const func1 = (one, two, three) => {
 *  console.log(one, "one")
 *  console.log(two, "two")
 *  console.log(three, 'three')
 * }
 * const say1 = rest(func1, 2)
 * say1(1, 2, 3, 4)
 *
 * // => 1 "one"
 * // => 2 "two"
 * // => [3, 4] 'three'
 */

import toInteger from "./toInteger" // 我的博客搜索【转换为整数】
import baseRest from "./baseRest"

const FUNC_ERROR_TEXT = "Expected a function"

function rest(func, start) {
  if (typeof func !== "function") {
    throw new TypeError(FUNC_ERROR_TEXT)
  }
  start = start === undefined ? start : toInteger(start)
  return baseRest(func, start)
}

export default rest
/**
 * The base implementation of `rest` which doesn't validate or coerce arguments
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter
 * @returns {Function} Returns the new function
 */

import setToString from "./setToString"

// 这个方法返回首个提供的参数。
function identity(value) {
  return value
}

/**
 * A specialized version of `baseRest` which transforms the rest array.
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start = func.length - 1] The start position of the rest parameter.
 * @param {Function} transform The rest array transform
 * @returns {Function} Returns the new function.
 */
function overRest(func, start, transform) {
  start = Math.max(start === undefined ? func.length - 1 : start, 0)
  return function() {
    var args = arguments,
      index = -1,
      length = Math.max(args.length - start, 0),
      array = Array(length)

    while (++index < length) {
      array[index] = args[start + index]
    }
    index = -1
    var otherArgs = Array(start + 1)
    while (++index < start) {
      otherArgs[index] = args[index]
    }
    otherArgs[start] = transform(array)
    return func.apply(this, otherArgs)
  }
}

function baseRest(func, start) {
  return setToString(overRest(func, start, identity), func + "")
}

export default baseRest
/**
 * Sets the `toString` method of `func` to return `string`
 * @param {Function} func The func to modify
 * @param {Function} string The `toString` result
 * @returns {Function} Returns `func`
 */

import baseSetToString from "./baseSetToString"

/**
 * Creates a function that'll short out and invoke `identity` instead
 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` milliseconds
 * @param {Function} func The function to restrict
 * @returns {Function} Returns the new shortable function
 */
// Used to detect hot functions by number of calls within a span of milliseconds
var HOT_COUNT = 800
var HOT_SPAN = 16

function shortOut(func) {
  var count = 0,
    lastCalled = 0

  return function() {
    var stamp = Date.now(),
      remaining = HOT_SPAN - (stamp - lastCalled)

    lastCalled = stamp
    if (remaining > 0) {
      if (++count > HOT_COUNT) {
        return arguments[0]
      }
    } else {
      count = 0
    }
    return func.apply(undefined, arguments)
  }
}

var setToString = shortOut(baseSetToString)

export default setToString
/**
 * The base implementation of `setToString` without support for hot loop shorting
 * @param {Function} func The function to modify
 * @param {Function} string The `toString` result
 * @returns {Function} Returns `func`
 * @example
 * var fun = () => {}
 * baseSetToString(fun, 'abc')
 * console.log(fun.toString())
 * // => 'abc'
 */

import getNative from "./getNative"

var defineProperty = (function() {
  try {
    var func = getNative(Object, "defineProperty")
    func({}, "", {})
    return func
  } catch (e) {}
})()

// 创建一个返回value的函数
function constant(value) {
  return function() {
    return value
  }
}

var baseSetToString = !defineProperty
  ? identity
  : function(func, string) {
      return defineProperty(func, "toString", {
        configurable: true,
        enumerable: false,
        value: constant(string),
        writable: true
      })
    }

export default baseSetToString
/**
 * Gets the native function at `key` of `object`
 * @param {Object} object The object to query
 * @param {string} key The key of the method to get
 * @returns {*} Returns the function if it's native, else `undefined`
 * @example
 * getNative(Array.prototype, 'push')
 * // => ƒ push() { [native code] }
 */

import baseIsNative from "./baseIsNative" // 我的博客搜索【检查value是否是一个原生函数】

function getValue(object, key) {
  return object == null ? undefined : object[key]
}

function getNative(object, key) {
  var value = getValue(object, key)
  return baseIsNative(value) ? value : undefined
}

export default getNative

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值