/**
* 创建一个函数,调用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