Skip to content

Commit

Permalink
Merge pull request #1278 from stucox/fnbind
Browse files Browse the repository at this point in the history
Change `fnBind` to a normal lib function instead of a polyfill
  • Loading branch information
ryanseddon committed Apr 23, 2014
2 parents 7654a23 + 4e128f6 commit 72616be
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 96 deletions.
68 changes: 38 additions & 30 deletions src/fnBind.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,56 @@
define(['slice'], function( slice ) {
// Not implemented as a polyfill, as that would change the environment,
// which isn’t something Modernizr should do

// Defer to native .bind if available
if ('bind' in Function.prototype) {
return function fnBind (fn, that) {
return fn.bind(that);
};
}

// Adapted from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js
// es5.github.com/#x15.3.4.5
function fnBind (fn, that) {

if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) {
var target = fn;

var target = this;
if (typeof target != 'function') {
throw new TypeError();
}

if (typeof target != 'function') {
throw new TypeError();
}
var args = slice.call(arguments, 2);
var bound = function() {

var args = slice.call(arguments, 1);
var bound = function() {
if (fn instanceof bound) {

if (this instanceof bound) {
var F = function(){};
F.prototype = target.prototype;
var self = new F();

var F = function(){};
F.prototype = target.prototype;
var self = new F();
var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;

var result = target.apply(
self,
args.concat(slice.call(arguments))
);
if (Object(result) === result) {
return result;
}
return self;
} else {

} else {
return target.apply(
that,
args.concat(slice.call(arguments))
);

return target.apply(
that,
args.concat(slice.call(arguments))
);
}

}
};

};
return bound;

return bound;
};
}

return Function.prototype.bind;
return fnBind;
});
11 changes: 5 additions & 6 deletions src/testDOMProps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define(['is', 'fnBind'], function( is ) {
define(['is', 'fnBind'], function( is, fnBind ) {
/**
* testDOMProps is a generic DOM property test; if a browser supports
* a certain property, it won't return undefined for it.
Expand All @@ -14,11 +14,10 @@ define(['is', 'fnBind'], function( is ) {

item = obj[props[i]];

// let's bind a function (and it has a bind method -- certain native objects that report that they are a
// function don't [such as webkitAudioContext])
if (is(item, 'function') && 'bind' in item){
// default to autobind unless override
return item.bind(elem || obj);
// let's bind a function
if (is(item, 'function')) {
// bind to obj unless overriden
return fnBind(item, elem || obj);
}

// return the unbound function or obj or value
Expand Down
61 changes: 1 addition & 60 deletions test/js/unit.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*global module, ok, equal, test, expect, raises, animationStyle */
/*global module, ok, equal, test, expect, animationStyle */
// PhantomJS timesout so leave autostart on
if(navigator.userAgent.indexOf('PhantomJS') === -1) {
QUnit.config.autostart = false;
Expand All @@ -18,65 +18,6 @@ test('globals set up', function() {
ok(window.Modernizr, 'global modernizr object created');
});

test('bind is implemented', function() {

ok(Function.prototype.bind, 'bind is a member of Function.prototype');

var a = function(){
return this.modernizr;
};
a = a.bind({modernizr: 'just awsome'});

equal('just awsome', a(), 'bind works as expected');


// thank you webkit layoutTests


var result;

function F(x, y) {
result = this + ' -> x:' + x + ', y:' + y;
}

var G = F.bind('"a"', '"b"');
var H = G.bind('"Cannot rebind this!"', '"c"');

G(1,2);
equal(result, '"a" -> x:"b", y:1');
H(1,2);
equal(result, '"a" -> x:"b", y:"c"');

var f = new F(1,2);
equal(result, '[object Object] -> x:1, y:2');
var g = new G(1,2);
equal(result, '[object Object] -> x:"b", y:1');
var h = new H(1,2);
equal(result, '[object Object] -> x:"b", y:"c"');

ok(f instanceof F, 'f instanceof F');
ok(g instanceof F, 'g instanceof F');
ok(h instanceof F, 'h instanceof F');

// Bound functions don't have a 'prototype' property.
ok('prototype' in F, '"prototype" in F');

// The object passed to bind as 'this' must be callable.
raises(function(){
Function.bind.call(undefined);
});

// Objects that allow call but not construct can be bound, but should throw if used with new.
var abcAt = String.prototype.charAt.bind('abc');
equal(abcAt(1), 'b', 'Objects that allow call but not construct can be bound...');

equal(1, Function.bind.length, 'it exists');


});



test('document.documentElement is valid and correct',1, function() {
equal(document.documentElement,document.getElementsByTagName('html')[0]);
});
Expand Down

0 comments on commit 72616be

Please sign in to comment.