The This__java of JavaScript

Source: Internet
Author: User
This is the JavaScript 1. Why use this
Let's take a look at an example:
function identity () {return
	this.name.toUpperCase ();
}

function speak () {return
	"Hello, I ' m" + identity.call (this);
}

var me = {
	name: ' Rod Chen '
}

var = {
	Name: ' Others in Aug '
}

console.log (Identity.call ( Me));  ROD CHEN
Console.log (identity.call);//others in AUG

console.log (Me)     ; Hello, I ' m ROD CHEN  
console.log (Speak.call (You));    Hello, I ' m others in AUG
The result of the output is obvious, as mentioned in the previous article in the use of call, the first parameter is the value passed in to this in the function.
This code can be used to reuse functions identify () and speak () in different context objects (me and you), and if we don't apply this, then we need the identity and speak display to pass in a context object, as in the following way
function identity (context) {return
	context.name.toUpperCase ();
}

Function speak {return
	"Hello, I ' M" + identity (context);
}

var me = {
	name: ' Rod Chen '
}

var = {
	Name: ' Others in Aug '
}

Console.log (Identity (Me)); 
  console.log (Identity (You));

Console.log (speak (Me));
Console.log (speak (you));
Summary: This provides a more elegant way to implicitly "pass" an object reference, so you can design the API more succinctly
and easy to reuse. As usage patterns become more complex, explicit delivery of context objects can make code more confusing, and using this does not
Such

2. Misunderstanding about this
(1) pointing to itself
Misunderstanding: It is easy to interpret this as the function object itself.
Not really, first look at an example:

The Console.log statement produced 4 outputs, proving that Foo (..) was actually called 4 times, but Foo.count is still 0. Obviously it is wrong to understand this from the literal sense. Executing foo.count = 0 o'clock, you did add a property count to the function object foo. But this does not point to that function object in the function's internal code this.count, so although the property name is the same, the root object does not phase
The same, the confusion arises, in fact counter is a Window object, as you can see from the example above, the way to execute is window.foo (), so this refers to the global Scope Window object.

(2) This scopeMisunderstanding: This points to the scope of the function.
This does not point to the lexical scope of the function in any case. Within JavaScript, scopes do resemble objects, and the visible identifiers are its properties. But the scope "object" cannot be accessed through JavaScript code, which exists inside the JavaScript engine. But we can access the This object.
function foo () {
	var a = 2;
	This.bar ();
}

function Bar () {
	"use strict";
	Console.log (THIS.A);
}

Foo (); Undefined

3. This is exactly what
This is binding at run time, not binding at compile time, and its context depends on the various conditions of the function call. The binding of this is not related to the location of the function declaration, only depending on how the function is invoked. When a function is called, an activity record (sometimes called an execution context) is created. This record contains information about where the function was invoked (call stack), the function's invocation method, and the incoming arguments. This is one of the attributes of the record, which is used during the execution of the function.

Method invocation: This points to the object that called the method, or the Call,apply function displays the parameters passed in.
The way the function is called: window or undefined

4. This comprehensive analysis
(1). Call Location
The call location is where the function is invoked in the code (rather than the declared location), and most importantly, the call stack is parsed (all functions called to reach the current execution location). The call location We care about is in the previous call to the function that is currently executing.
function Baz () {
	//The current call stack is: Baz
	//Therefore, the current call position is the global scope
	console.log ("Baz");
	Bar (); <--Bar's call location
}

function Bar () {
	//Current call stack is Baz-> bar
	//Therefore, the current call location is in Baz
	console.log ("Bar" );
	Foo (); <--Foo's call location
}

function foo () {
	//Current call stack is Baz-> bar-> foo
	//Therefore, the current call location is in bar
	cons Ole.log ("foo");
}

Baz (); Call location for <--Baz
The call stack can be thought of as a function call chain, but this approach is too tiring, because it's too cumbersome to do it when we have different file modules in the project. We can use the developer tools to view: The Red box section in the following figure


(2) Binding rules
A. Independent function callsYou can think of this rule as a default rule when you cannot apply another rule. In Code, foo () is invoked directly using a function reference without any adornments, so you can only use the
Default bindings, other rules cannot be applied. The This value at this time is window or undefined


B. Implicit binding 1) Implicit bindingAnother rule to consider is whether the call location has a context object, or whether it is owned or contained by an object.
function foo () {
	console.log (THIS.A);
}

var obj = {
	a:2,
	foo:foo
};

Obj.foo (); 2
The first thing to notice is how the Foo () is declared and how it is later added to obj as a reference property. However, whether directly defined in obj or first defined and then added as a reference attribute, this function is strictly not a obj object, except that the Foo attribute in obj points to the location of the Foo function under the global scope.
However, the call location uses the obj context to refer to the function, so you can say that the Obj object "owns" or "contains" it when the function is invoked. Whatever you call this pattern, when Foo () is called, its foothold does point to the Obj object.

Note: The object attribute reference chain has only the topmost layer or the last layer affects the call location (that is, the nearest location to the calling function)
function foo () {
	console.log (THIS.A);
}

var obj2 = {
	a:42,
	foo:foo
};

var obj1 = {
	a:2,
	obj2:obj2
};

Obj1.obj2.foo (); 42

2) implicit loss ofOne of the most common this binding problems is that an implicitly bound function loses a bound object, meaning that it applies the default binding, which binds this to the global object or undefined.
function foo () {
	console.log (THIS.A);
}

var obj = {
	a:2,
	foo:foo
};

var bar = Obj.foo; function alias.
var a = "oops, global";//A is the properties bar () of the global object
;//"Oops, global"
Although bar is a reference to Obj.foo, in fact it refers to the Foo function itself, so the bar () is actually a function call without any modification, so the default binding is applied, which also shows that the value of this is determined by the calling method.


c. Show BindingsWhen analyzing implicit binding, we have to include a property in an object that points to a function, and indirectly, by referencing the function, to bind this indirect (implicit) to this object. So what if we don't want to include a function reference inside an object and want to force a function on an object?
That's call (..) and apply (..). There is little more to say about call and apply, as in the previous article, you can view the article JavaScript functions, scopes, and closures.
1 Hard bind bind
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
Bind (..) Returns a hard-coded new function that sets the argument to the context of this and invokes the original function, which has the function class decision I created, not the caller.

2 The context of the API callMany of the functions of the third Third-party, as well as the JavaScript language and many of the new built-in functions in the hosting environment, provide an optional parameter, commonly referred to as the context, which acts as a bind (..), ensuring that your callback function uses the specified this.
Please look at the diagram:


d. New BindingUse new to invoke a function, or, when a constructor call occurs, the following actions are performed automatically.
1. Create (or construct) an entirely new object.
2). The new object will be connected by a [[prototype]] connection.
3). This new object is bound to this of the function call.
4. If the function does not return other objects, the function call in the new expression will automatically return the object.


(3). Priority Level
Now we can determine which rule the function applies at a call location based on the priority. You can follow the following
Order to make judgments:
1. Whether the function is called in new (new binding). If so, this binds the newly created object.
var bar = new Foo ()
2. Whether the function is called by call, apply (explicitly bound), or hard binding. If so, this binds the
The specified object.
var bar = Foo.call (OBJ2)
3. Whether the function is invoked in a context object (implicit binding). If so, this binds the one on the
The following object.
var bar = Obj1.foo ()
4). If not, use the default binding. If in strict mode, bind to undefined, otherwise bind to the
The global object.
var bar = foo ()

(4). Arrow function
ES6 describes a special function type that cannot use these rules: the arrow function.
The arrow functions are not defined using the Function keyword, but are defined using the operator => called the "Fat arrow." The arrow function does not use the four standard rules of this, but rather is based on the outer (function or global) scope
Set this.


Arrow functions are most commonly used in callback functions, such as event handlers or timers
function foo () {
	settimeout () => {/) This
	is inherited from Foo ()
		console.log (THIS.A);
	},100);

var obj = {
	a:2
};

Foo.call (obj); 2

function foo1 () {
	settimeout (function () {
	/) This is window
		console.log (THIS.A);
	},100 );
}

var obj = {
	a:2
};

Foo1.call (obj); Undefined


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.