Objective
If you want to ask which of the two knowledge points in JavaScript are confusing, scoping queries and mechanisms are definitely at the this
top. So this article starts this
with four binding rules in JavaScript, so let's take a look.
Binding rules
1. Default Bindings
When you call a stand-alone function, point to the this
global object, and if you use strict mode, the global object cannot be bound to with the default binding this
undefined
.
function foo () {
console.log (THIS.A);
}
var a = 2;
Foo (); 2
When strict mode:
function foo () {
"use strict";
Console,log (THIS.A);
}
var a = 2;
Foo (); Typeerror:this is undefined
2. Implicit binding
When a function references a context object (that is, the function is added to the object as a reference property), the implicit binding rule binds the function call this
to the context object.
function foo () {
console.log (THIS.A);
}
var obj = {
a:2,
foo:foo
};
Obj.foo (); 2
The object attribute reference chain has only the topmost or last layer that affects the call location:
Obj1.obj2.foo (); This in Foo is bound to Obj2
2.1 Implicit loss
Implicit loss refers to this missing bound object in a function, which applies the default binding rule of article 1th, which this
binds to the global object or to it undefined
, depending on whether it is running in strict mode. Implicit loss can occur in the following situations:
The function bound to the context object is assigned to a new function, and then the new function is called:
function foo () {
console.log (THIS.A);
}
var obj = {
a:2,
foo:foo
};
var bar = Obj.foo; function Alias
var a = "This is a global variable oh";
Bar (); "This is a global variable."
When you pass in the callback function:
function foo () {
console.log (THIS.A);
}
function Dofoo (FN) {
fn ();//<--call location
}
var obj = {
a:2,
foo:foo
};
var a = "This is a global variable oh";
Dofoo (Obj.foo); "This is a global variable."
In fact, this is the first variant of the situation, in fact, parameter transfer is an implicit assignment. In addition to developer-defined functions, setTimeout
implicit loss can also occur when functions are passed into a language-built function such as.
3. Explicit binding
The core of explicit binding is the JavaScript built-in and the methods that are available call(..)
apply(..)
in most of the functions that JavaScript provides, as well as on all the functions created by the developer themselves.
call(..)
And apply(..)
The first argument is an object (the difference is in the form of the arguments passed in later, not the focus, not the discussion), and they bind this to the object. Because you can specify this
the bound object directly, this rule is referred to as an explicit binding.
function foo () {
console.log (THIS.A);
}
var obj = {
a:2
};
Foo.call (obj); 2
If the first argument that call or apply passes in is the original value (string type, Boolean type, or numeric type), the original value is converted to its object form ( new String()
, new Boolean()
or new Number()
), commonly known as "boxing".
Explicit binding still does not resolve the missing binding problem.
3.1 Hard Binding
As a variant of an explicit binding, hard binding resolves a missing binding problem.
function foo () {
console.log (THIS.A);
}
var obj = {
a:2
};
var bar = function () {
foo.call (obj);
};
Bar (); 2
settimeout (bar);//2
bar.call (window);//invalid, hard-bound bar will not modify it again
Force the binding to an object inside a new function, this
no matter how the new function is invoked after that, it this
is not lost.
A typical scenario is to create a package function, pass in all parameters, and return all the values received:
function foo (something) {
console.log (THIS.A, something);
return THIS.A + something;
}
var obj = {
a:2
};
var bar = function () {return
foo.call (obj, arguments);
var B = Bar (3); 2 3
Console.log (b);//5
Or you can change the bound object to configurable so that it becomes a secondary binding function:
...
function bind (FN, obj) {return
function () {return
fn.apply (obj, arguments);
}
...
Because hard binding is too common, ES5 provides a built-in Function.prototype.bind
and uses the following:
function foo (something) {
console.log (THIS.A, something);
return THIS.A + something;
}
var obj = {
a:2
};
var bar = foo.bind (obj);
var B = Bar (3); 2 3
Console.log (b);//5
3.2 The "context" of API calls
JavaScript itself, as well as many Third-party library functions, provide an optional parameter, often referred to as the "context", which acts as the bind(..)
same as ensuring that the callback function uses the specified this
.
function foo (EL) {
console.log (el, this.id);
}
var obj = {
id: "Awsome"
};
Bind this to obj
[1,2,3].foreach (foo, obj) when calling Foo (..);
1 awsome 2 awsome 3 awsome
In fact, these functions are still invoked behind call()
or apply()
, except that the developer needs to write less code.
4. New Binding
new
when you use to invoke a function, the following actions are performed automatically:
1, create a new object
2, this new object will be executed [[prototype]] Connection
3, this new object will be bound to the function calledthis
4, if the function does not return other objects, then new
the function call in the expression will automatically return the new object
Examples are as follows:
function foo () {
this.a = A;
}
var bar = new Foo (2);
Console.log (BAR.A); 2
new
foo(..)
when invoked, a new object is constructed and bound to the foo(..)
top of the call this
.
Priority level
Specific inference details are no longer stated, and the use of the above four binding rules is inferred as follows:
1. Is the function new
called ( new
binding) in? If so, this
the newly created object is bound.
2. Does the function pass call
, apply
(display binding), or hard binding? If so, the this
bound is the specified object.
var bar = Foo.call (OBJ2);
3. Is the function invoked in a context object (implicit binding)? If so, the this
binding is the context object.
4, if not, use the default binding. Bind to a global object if it is bound to in strict mode undefined
.
Binding exceptions
If you null
undefined
pass in this
, or, the binding object that you are using, the call
apply
values are bind
ignored when invoked, and the default binding rules are actually applied. (The book suggests using an empty object to bind this).
Indirect references. This situation is easy to occur when assigning values:
function foo () {
console.log (THIS.A);
}
var a = 2;
var o = {a:3, foo:foo};
var p = {A:4};
O.foo (); 3
(P.foo = O.foo) ();//2
p.foo()
is actually referenced foo()
, so the default binding is applied.
In addition ES6 to change this
the chaotic binding made the corresponding efforts, the birth of the arrow function, based on the current lexical scope to determine this
rather than the above four rules, specifically, the arrow function will inherit the outer function call of the this
binding (this actually and ES6 in the code before the self = this
is a truth).
Summarize
The above is the entire content of this article, I hope to be able to learn or work to bring certain help, if there is doubt you can message exchange.