// Licensed Materials - Property of IBM
//
// IBM Watson Analytics
//
// (C) Copyright IBM Corp. 2015
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
( function( Object, Function, ObjectPolyfill )
{
"use strict";
/**
* Polyfills for {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function Function}.
* @class module:barejs/polyfill.Function
*/
/** @lends module:barejs/polyfill.Function# */
var proto = {};
var fnProto = Function.prototype;
/*istanbul ignore else: We test with __ES__ set to 3*/
if ( __ES__ < 5 )
{
var slice = Array.prototype.slice;
/**
* Bind a function to a specific context. Allows for additional prefix arguments to be specified.
* @param {object} _thisArg The context to bind this method to.
* @returns {function} A function that will invoke the original function in the specified context,
* optionally with additional parameters prefixed.
*/
proto.bind = function bind( _thisArg /*, ... */ )
{
if ( !ObjectPolyfill.isCallable( this ) )
throw new TypeError( "Bind must be called on a function" );
var bound, fn = this, args = null, Anonymous = function(){};
if ( arguments.length > 1 )
args = slice.call( arguments, 1, arguments.length );
// Apply almost the same trick as Object.create, so if the bound method is used as a
// constructor, we do not change the context and the prototype chain is correct.
// We can't use Object.create since we need the Anonymous type for the instanceof check
// Prototype is undefined for native functions, so check it first.
Anonymous.prototype = fn.prototype /*istanbul ignore next*/|| Object.prototype;
// Only do parameter mangling if required. This optimization provides a significant speed boost
if ( args && args.length )
{
bound = function()
{
var len = arguments.length;
// Only concat the arguments if there are arguments during invocation (to avoid concat)
// If this bound method is used as a constructor, don't change the context
return fn.apply( this instanceof Anonymous ? this : _thisArg, len ? args.concat( slice.call( arguments, 0, len ) ) : args );
};
}
else
{
bound = function()
{
// If this bound method is used as a constructor, don't change the context
return fn.apply( this instanceof Anonymous ? this : _thisArg, arguments );
};
}
bound.prototype = new Anonymous();
// technically the bound function should have the same length as the function bound, but we can't emulate that
return bound;
};
}
( function()
{
var toString = fnProto.toString;
/*istanbul ignore next: not invoked since NodeJS has a name property on Function.prototype*/
function name()
{
//jshint validthis:true
if ( this === fnProto )
return "";
var match = toString.call( this ).match( /function\s*([a-zA-Z0-9_$]*)\s*\(/ );
Object.defineProperty( this, "name", { configurable: true, value: ( match && match[1] ) || "" } );
return this.name;
}
// See if the name property isn't exposed, but we can expose it (and it works)
/*istanbul ignore next: NodeJS has a name property on functions*/
if ( !name.name && Object.defineProperties && ( name.call( name ) === "name" ) )
Object.defineProperty( fnProto, "name", { configurable: true, "get": name } );
}() );
ObjectPolyfill.polyfill( Function, null, proto, exports, "Function" );
// End of module
}( Object, Function, require( "./Object" ) ) );