您的位置:首页 > Web前端 > JavaScript

面向对象的JavaScript-007-Function.prototype.bind() 的4种作用

2016-05-24 16:05 661 查看
1.

// Function.prototype.bind() 的作用

// 1.Creating a bound function
this.x = 9;
var module = {
x: 81,
getX: function() { return this.x; }
};

console.log(module.getX()); // 81

var retrieveX = module.getX;
console.log(retrieveX());
// 9, because in this case, "this" refers
// to the global object

// Create a new function with 'this' bound to module
// New programmers might confuse the
// global var x with module's property x
var boundGetX = retrieveX.bind(module);
console.log(boundGetX()); // 81

// 2.Partially applied functions

// The next simplest use of bind() is to make a function with pre-specified initial arguments. These arguments (if any) follow the provided this value and are then inserted at the start of the arguments passed to the target function, followed by the arguments passed to the bound function, whenever the bound function is called.
function list() {
return Array.prototype.slice.call(arguments);
}

var list1 = list(1, 2, 3); // [1, 2, 3]
console.log(list1);
// Create a function with a preset leading argument
var leadingThirtysevenList = list.bind(undefined, 37);
console.log(leadingThirtysevenList);
var list2 = leadingThirtysevenList();
// [37]
console.log(list2);
var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
console.log(list3);

// 3.With setTimeout

//y default within window.setTimeout(), the this keyword will be set to the window (or global) object. When working with class methods that require this to refer to class instances, you may explicitly bind this to the callback function, in order to maintain the instance.
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}

// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};

LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};

var flower = new LateBloomer();
flower.bloom();
// after 1 second, triggers the 'declare' method

// 3.Bound functions used as constructors
// Bound functions are automatically suitable for use with the new operator to construct new instances created by the target function. When a bound function is used to construct a value, the provided this is ignored. However, provided arguments are still prepended to the constructor call:
function Point(x, y) {
this.x = x;
this.y = y;
}

Point.prototype.toString = function() {
return this.x + ',' + this.y;
};

var p = new Point(1, 2);
p.toString(); // '1,2'

// not supported in the polyfill below,

// works fine with native bind:

var YAxisPoint = Point.bind(null, 0/*x*/);

var emptyObj = {};
var YAxisPoint = Point.bind(emptyObj, 0/*x*/);

var axisPoint = new YAxisPoint(5);
axisPoint.toString(); // '0,5'

console.log(axisPoint instanceof Point); // true
console.log(axisPoint instanceof YAxisPoint); // true
console.log(new Point(17, 42) instanceof YAxisPoint); // true

// Example can be run directly in your JavaScript console
// ...continuing from above

// Can still be called as a normal function
// (although usually this is undesired)
console.log(YAxisPoint(13));

console.log(emptyObj.x + ',' + emptyObj.y);
// >  '0,13'

// 4.Creating shortcuts
var slice = Array.prototype.slice;

// ...

slice.apply(arguments);
// same as "slice" in the previous example
var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.apply.bind(unboundSlice);

// ...

slice(arguments);

// Polyfill
// The bind function is an addition to ECMA-262, 5th edition; as such it may not be present in all browsers. You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of bind() in implementations that do not natively support it.
if (!Function.prototype.bind) {
Function.prototype.bind = function(oThis) {
if (typeof this !== 'function') {
// closest thing possible to the ECMAScript 5
// internal IsCallable function
throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
}

var aArgs   = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP    = function() {},
fBound  = function() {
return fToBind.apply(this instanceof fNOP
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};

if (this.prototype) {
// Function.prototype doesn't have a prototype property
fNOP.prototype = this.prototype;
}
fBound.prototype = new fNOP();

return fBound;
};
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: