Let's look at a topic first.
1234 |
var write = document.write; write( "hello" ); //1.以上代码有什么问题 //2.正确操作是怎样的 |
Does not execute correctly because the Write function loses context, and this point to the Global or Window object causes the execution to prompt for an illegal call to the exception, so we need to change the point of this
The right solution is to usebind/call/apply来改变this指向
Bind method
12 |
var write = document.write; write.bind(document)( ‘hello‘ ); |
Call method
12 |
var write = document.write; write.call(document, ‘hello‘ ); |
Apply method
12 |
var write = document.write; write.apply(document,[ ‘hello‘ ]); |
Bind function
bind()
The simplest use is to create a function so that the function has the same this value regardless of how it is called. The common mistake is to take the method out of the object, just like the example above, and then call it and want this to point to the original object. If you do not do special processing, you will generally lose the original object. The use bind()
of the method can be very beautiful to solve the problem:
12345678910111213141516171819 |
<script type=
"text/javascript"
>
this
.num = 9;
var
module = {
num: 81,
getNum: function(){
console.log(
this
.num);
}
};
module.getNum();
// 81 ,this->module var
getNum = module.getNum;
getNum();
// 9, this->window or global
var
boundGetNum = getNum.bind(module);
boundGetNum();
// 81,this->module
</script>
|
Partial function (partial Functions)
The partial functions is also called the partial applications, which intercepts a definition of the partial function:
Partial application can be described as taking a function this accepts some number of arguments, binding values to one or More than those arguments, and returning a new function that is only accepts the remaining, un-bound arguments.
This is a good feature, using the bind()
predefined parameters of the function that we set, and then passing in other parameters when called:
123456789101112131415161718 |
<script type=
"text/javascript"
>
function list() {
return
Array.prototype.slice.call(arguments);
} var
list1 = list(1, 2, 3);
console.log(list1);
// [1, 2, 3]
// 预定义参数37
var
leadingThirtysevenList = list.bind(undefined, 37);
var
list2 = leadingThirtysevenList();
console.log(list2);
// [37]
var
list3 = leadingThirtysevenList(1, 2, 3);
console.log(list3);
// [37, 1, 2, 3]
</script>
|
and settimeout or
setintervalUsed together
setTimeout()
in general, this refers to the window or global object. When you use the method of a class to point to a class instance, you can use this to bind()
bind to the callback function to manage the instance.
1234567891011121314151617181920 |
<script type=
"text/javascript"
>
function Bloomer() {
this
.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// 1秒后调用declare函数
Bloomer.prototype.bloom = function() {
window.setTimeout(
this
.declare.bind(
this
), 1000);
};
Bloomer.prototype.declare = function() {
console.log(
‘我有 ‘
+
this
.petalCount +
‘ 朵花瓣!‘
);
};
var
test =
new
Bloomer();
test.bloom();
</script>
|
Binding functions as constructors
The binding function is also useful for constructing an instance of the target function using the new operator. When using a binding function to construct an instance, note that this is ignored , but the parameters passed in are still available.
1234567891011121314151617181920212223 |
<script type=
"text/javascript"
>
function Point(x, y) {
this
.x = x;
this
.y = y;
}
Point.prototype.toString = function() {
console.log(
this
.x +
‘,‘
+
this
.y);
};
var
p =
new
Point(1, 2);
p.toString();
// 1,2
var
YAxisPoint = Point.bind(
null
,10);
var
axisPoint =
new
YAxisPoint(5);
axisPoint.toString();
// 10,5
console.log(axisPoint instanceof Point);
// true
console.log(axisPoint instanceof YAxisPoint);
// true
console.log(
new
Point(17, 42) instanceof YAxisPoint);
// true
</script>
|
In the example above, point and Yaxispoint share the prototype, so use the instanceof operator to determine true
Conversion of pseudo-arrays
Several of the above sections show bind()
that there are many usage scenarios, but the bind()
function is added to the fifth version of ECMA-262; it may not run on all browsers. This requires that we implement bind()
the function ourselves.
First, we can simply implement the method by assigning a scope to the target function bind()
:
123456 |
Function.prototype.bind = function(context){ self = this ; //保存this,即调用bind方法的目标函数 return function(){ return self.apply(context,arguments); }; }; |
Given the case of the function curry, we can build a more robust one bind()
:
12345678 |
Function.prototype.bind = function(context){
var
args = Array.prototype.slice.call(arguments, 1),
self =
this
;
return
function(){
var innerArgs = Array.prototype.slice.call(arguments);
var
finalArgs = args.concat(innerArgs);
return
self.apply(context,finalArgs);
};<br>}
|
This time the bind()
method can bind the object, and also support the argument when binding.
Continue, JavaScript functions can also be used as constructors, so when the bound function is called in this way, the situation is more subtle and involves the delivery of the prototype chain:
1234567891011121314 |
Function.prototype.bind = function(context){
var
args = Array.prototype.slice(arguments, 1),
F = function(){},
self =
this
,
bound = function(){
var
innerArgs = Array.prototype.slice.call(arguments);
var
finalArgs = args.concat(innerArgs);
return
self.apply((
this
instanceof F ?
this
: context), finalArgs);
};
F.prototype = self.prototype;
bound.prototype =
new
F();
return
bound;
};
|
This is the implementation of the pair in JavaScript Web application bind()
: By setting a transit constructor F, the bound function bind()
is on the same prototype chain as the calling function, and the new operator invokes the bound function. The returned object can also use instanceof normally, so this is the most rigorous bind()
implementation.
For a function to be supported in the browser bind()
, you only need to modify the above function slightly:
1234567891011121314151617181920 |
Function.prototype.bind = function (oThis) {
if
(
typeof
this
!==
"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 && oThis ?
this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments))
);
};
fNOP.prototype =
this
.prototype;
fBound.prototype =
new
fNOP();
return fBound;
};
|
The use and implementation of the bind () method in JavaScript