UNPKG

rename-function

Version:

Rename a given function. Tries to be cross-platform and guaranteed. Useful when you want to preserve name of bound function. In bonus, allows passing context to the renamed function.

67 lines (57 loc) 1.89 kB
/*! * rename-function <https://github.com/tunnckoCore/rename-function> * * Copyright (c) 2016 Charlike Mike Reagent <@tunnckoCore> (http://www.tunnckocore.tk) * Released under the MIT license. */ 'use strict' var format = require('util').format var utils = require('./utils') /** * > Rename given `fn` with `name`. If given `name` is same as old, * then the `fn` is just returned earlier, nothing more is done. * * **Example** * * ```js * var rename = require('rename-function') * var getName = require('get-fn-name') * * var fn = rename(fixture () {}, 'abc') * * console.log(getName(fn)) // => 'abc' * console.log(fn.name) // => 'abc' * * // passing context * var bound = rename(fixture foo () { return this }, 'zoo', {a: 'b'}) * console.log(bound()) // => {a: 'b'} * console.log(bound.name) // => 'zoo' * console.log(getName(bound)) // => 'zoo' * ``` * * @param {Function} `fn` * @param {String|Object} `name` * @param {Object} `ctx` * @return {Function} or throws `TypeError` if `fn` not a function * @api public */ module.exports = function renameFunction (fn, name, ctx) { if (typeof fn !== 'function') { throw new TypeError('rename-function: expect `fn` be function') } var isObject = utils.isExtendable(name) if (utils.isInvalid(arguments, name, isObject)) { return fn } var fnName = utils.getFnName(fn) || '' ctx = isObject ? name : ctx name = typeof name === 'string' ? name : 123 name = name === 123 ? fnName : utils.namify(name) var str = format('return function %s() { return fn.apply(ctx || this, arguments) }', name) var func = (new Function('fn', 'ctx', str))(fn, ctx || this) // eslint-disable-line no-new-func utils.defineProperty(func, 'toString', function toString () { var named = format('function %s(', name) return fn.toString().replace(/^function .*?\(/, named) }) return func }