JavaScriptscope scope and this keyword

Source: Internet
Author: User
As a programmer, you may have been used to the reference (or pointer) of the current object in object-oriented language ),

As a programmer, you may have been used to the reference (or pointer) of the current object in object-oriented language, such as this in c ++ or self in python, of course, javascript with OO attributes (javascript is actually more of a so-called functional language) also has a pointer (or reference) to the object that references the current attribute ), that is, the this keyword.

To understand this keyword, if you only want to remember one sentence, it should be that this keyword always points to the owner object (Execution space) of the current function, for more information, see the following description.

So what is scope?

Wikipedia is interpreted as In computer programming, scope is an enclosing context where values and expressions are associated. Chinese is the so-called scope, which specifies the context associated with a value or expression (the executable space that can be referenced ).

What is the relationship between scope and this? From the above definition, this always points to the object that currently references this function, and when you want to determine the currently referenced object, you have to figure out the scope of the current function. See the following analysis.

This keyword

See the following examples.

An example of python:

Class Person (object): "a person class" def _ init _ (self, name): self. name = name # self points to the instantiated object, as shown in Magicdef get_name (self): return self. nameMagic = Person ("Magic") print Magic. name

An example of javascript:

Window. name = "Magic from window" var get_name = function () {// the specific point of this can only be determined at runtime, that is, the object that is called during runtime return this. name ;}; // output Magic from window. The object called by get_name is invalid walert (get_name (); var obj ={} obj. name = "Magic from obj"; // output Magic from obj. We forcibly use apply to change the called object and point it to objalert (get_name.apply (obj )); var innerobj = {"name": "Magic from innerobj"}; innerobj. get_name = get_name; // enables the get_name method of innerobj to point to the global scope get_name function alert (innerobj. get_name (); // output Magic from innerobj. At this time, this points to innerobj.

From the simple example above, this can always determine its specific point at runtime and its calling object. This is also an important feature of Dynamic Language.

So how to determine the reference object to which this currently points? It is usually possible to judge as follows:

  1. If you call the function in the global scope (see the following description to determine what global scope is), it points to the top-level Object window of boodle, for example, get_name ()
  2. If there is a reference similar to this, innerobj. Get_name () indicates that this points to innerobj.
  3. If we use apply and call to forcibly point the referenced object, it will obviously point to the forced object, such as get_name. Apply (obj ).
Apply and call

The two keywords can be easily resolved to force conversion of this reference object (runtime space). the syntax of the two keywords is as follows:

  • Fun. call (object, arg1, arg2 ,...)
  • Fun. apply (object, [arg1, arg2,...])

The purpose of the two is the same (dynamically changing the runtime space of the function, or changing the object pointed to by this), but the call methods on the parameters provided to the function are different.

The sample code is as follows:

var test_call_apply = function(name, gender, school){alert(this.age + name + gender + school);};test_call_apply.call({age:24}, "Magic", "male", "ISCAS");test_call_apply.apply({age:24}, ["Magic", "male", "ISCAS"]);  
Scope details
Var global_scope = "I'm global"; var fun = function () {var fun_scope = "I'm in fun scope"; return innerfun () {var inner_func_scope = "I'm in the inner fun scope"; return global_scope + fun_scope + inner_func_scope; // reference here is important, please note };}; alert (fun ()());

Pay attention to the above Code, where:

  1. Global_scope: global scope
  2. Fun_scope: It is located in the scope of a function.
  3. Inner_func_scope is the scope of a function located in a function.

You can also embed functions to generate several scopes.

So there is a problem. Why can the innerfun method reference variables not in its own scope?

Before answering this question, we need to introduce a concept scope chain. Scope chain refers to a chain of priority and related scopes formed in javascript code.

The above code is used as an example,

  1. For the global scope, it will create a global scope chain for itself (of course, this chain has only one scope ).
  2. For the scope of the fun function, it first establishes the same scope chain as global, and then adds its own scope (at this time, this chain has two scopes), similar to the following structure: global ==> fun
  3. For innerfun, in addition to the chain of the fun function, it will also add its own scope (of course, this chain has three scopes at this time), similar to this structure: global ==> fun ==> innerfun

Scope chain has the following features:

  1. Ordered
  2. Every time a function is created, a scope is automatically generated and added to its own scope chain.
  3. This chain is similar to a stack. It is always checked from the top when searching for variables.

The three parts correspond to the scope of the three variables in the above Code, and when you evaluate each variable, it is searched from top to bottom according to the scope chain in the figure, find the return value or return the undfined value until the scope chain is lifted.

Actually, it is easy to understand. When calculating an expression, it will perform a search from top to bottom on its own scope chain. if it finds it, it will return this value immediately, if the entire chain is not found, undefined is returned.

This lookup mechanism determines that the scope at the front-end of the chain usually has a higher priority.

For example, when javascript calculates global_scope + fun_scope + inner_func_scope; this expression, it searches for the scope chain shown in the preceding figure to determine the final result.

Notes

If you have figured out the above discussion, we should say that you already have a full knowledge base on the this keyword and scope, but we need to better use and understand these concepts in practice, in this way, the ability can be upgraded to another level, that is, the relationship between theory and practice.

See the following example:

Var change_color = function () {this. style. color = "red" ;}; window. onload = function () {var text = document. getElementById ("text"); text. onclick = change_color; // at this time, this points to the text object (dom object)}; // the following line of code is in the body // this requires special attention, inline script points to the window, which is not defined here. My color will be changed2.

Note the following:

  1. In inline event registration, this does not point to its own dom node, but to the windows of global scope. this can be proved from the above example.
  2. This kind of inline event registration is not advisable. We recommend Unobtrusive JavaScript (processing logic and page structure are separated)

Javascript is a very powerful dynamic language. It is a functional language dressed in C language. If you only think of it as a C-type imperative language, your knowledge level is too low. If you can understand the essence of javascript functional language, you are using javascript to understand jQuery and other libraries, you can even write some javascript on your own.

This article is available at http://www.nowamagic.net/librarys/veda/detail/1239.

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.