Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the objects in JavaScript

2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly explains "what are the objects in JavaScript". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what are the objects in JavaScript"?

An object

ECMAScript, a high-level abstract object-oriented language, is used to deal with Objects. Of course, there are native types, but if necessary, they also need to be converted to object.

Object is a collection of properties, and each has a separate prototype object [prototype object]. The prototype object [prototype object] can be an object or a null value.

Let's give an example of Object. First of all, let's make it clear that the prototype of an Object is a reference to an internal [[prototype]] attribute. In general, however, we use _ _ underscores instead of double parentheses, such as _ _ prototype__

Look at this code.

Var foo = {x: 10, y: 20}

As shown above, the structure has two explicit properties [explicit own properties] and one with implicit _ _ proto__ attribute [implicit].

_ _ proto__ property], which is the prototype of foo.

What is the use of this property? Let's look at an example of a prototype chain [prototype chain].

A prototype chain

Prototype objects are also of object type and will have their own prototypes. If there is still a non-empty prototype for this prototype, then the search continues to form a prototype chain [prototype chain].

A prototype chain is a limited chain of objects made up of a series of objects that inherit and share properties.

Consider such a situation.

There are two objects, only a small number of methods or properties are different, the rest are the same. Obviously, in a good design pattern, we need to reuse the same parts instead of repeatedly defining the same methods or properties in each object. In a system based on class [class-based], these reuse parts are called class inheritance.

-the same parts are put into class A, and then class B and class C inherit from An and have their own unique things.

ECMAScript has no concept of classes. However, the concept of reuse [reuse] is no different (in some respects, even more flexible than class-) and can be implemented by the prototype chain prototype chain. This inheritance is called delegation

Based inheritance- delegates based on inheritance, or, more generally, prototype inheritance.

In the above-mentioned Classes A _ Magi B ~ C, three objects can be created in ECMAScript: a ~ ~ b ~ ~ c. An is responsible for the same parts of b and c, while b and c are responsible for different and unique things.

Var a = {x: 10, calculate: function (z) {return this.x + this.y + z}}; var b = {y: 20, _ proto__: a}; var c = {y: 30, _ proto__: a}; / / call the inherited methodb.calculate (30); / / 60c.calculate (40); / / 80

Doesn't this look very simple? B and c can use the calculate method defined in a, which is implemented with a prototype chain to [prototype chain].

Let's take a look at the principle: if the calculate method is not found in object b (that is, it does not have this calculate property in object b), it will start looking along the prototype chain. If this calculate method is not found in the prototype of b, then the prototype of a will be found along the prototype chain, traversing the entire prototype chain. Remember, once found, return to the first property or method found. Therefore, the first property found becomes an inherited property. If you traverse the entire prototype chain and still can't find it, it returns undefined.

Note that the value of this in an inheritance mechanism still points to the object to which it originally belongs, rather than the object to which it belongs when it is found on the prototype chain. For example, in the above example, this.y is obtained from b and c, not a. Of course, you also found that this.x is taken from a because it is found through the prototype chain mechanism.

If the prototype of an object is not declared or defined, the default value of _ _ prototype__ is object.prototype, and object.prototype will also have a _ _ prototype__, which is the end of the prototype chain, which is set to null.

The following illustration shows the relationship between the aforementioned afield b and the c.

Let's consider another situation. Sometimes we need objects to use the same or similar structure (for example, the same set of properties), but with different values. In this case, we can consider using the constructor [constructor function], which is an object constructed by a specific structure.

Constructor

In addition to being able to construct specific objects, the constructor [constructor] has another useful function-creating a prototype object for a new object. This prototype object is placed in the prototype [ConstrutorFunction.prototype] of the constructor.

Let's rewrite the above example with a constructor.

/ / a constructor functionfunction Foo (y) {/ / which may create objects / / by specified pattern: they have after / / creation own "y" property this.y = y;} / / also "Foo.prototype" stores reference// to the prototype of newly created objects,// so we may use it to define shared/inherited// properties or methods, so the same as in// previous example we have:// inherited property "x" Foo.prototype.x = 10 / / and inherited method "calculate" Foo.prototype.calculate = function (z) {return this.x + this.y + z;}; / / now create our "b" and "c" / / objects using "pattern" Foovar b = new Foo (20); var c = new Foo (30); / / call the inherited methodb.calculate (30); / / 60c.calculate (40) / / 80 Foo.prototype / let's show that we reference// properties we expectconsole.log (b.potato protoplasts _ = = Foo.prototype, / / true c.protoplasts _ = Foo.prototype, / / true / / also "Foo.prototype" automatically creates / / a special property "constructor", which is a / / reference to the constructor function itself / / instances "b" and "c" may found it via / / delegation and use to check their constructor b.constructor = Foo, / / true c.constructor = Foo, / / true Foo.prototype.constructor = = Foo / / true b.calculate = b.__proto__.calculate, / / true b.__proto__.calculate = Foo.prototype.calculate / / true)

The above code has the following relationship

As can be seen in the above illustration, each object has a prototype. The constructor Foo also has its own _ _ proto__, or Function.prototype, and the _ _ proto__ of Function.prototype points to Object.prototype. Therefore, Foo.prototype is just an explicit property, that is, the _ _ proto__ attribute of b and c.

More complete and detailed information about this can be found in the Chapter 7 ES3 series. There are two parts: Chapter 7. 1. OOP. The general theory (the principle of various OOP and their comparison with ECMAScript), and Chapter

7.2. OOP. ECMAScript implementation (describes how to introduce the concept of OOP into ECMAScript)

Now that we understand the basic principles of object, let's take a look at the program execution environment in ECMAScript [runtime program execution]. This is commonly referred to as the "execution context stack" [execution

Context stack] . Each element can be abstractly understood as object. You may have found that, yes, object can be seen almost everywhere in ECMAScript.

Execution context stack

There are three types of code in ECMASscript: global, function, and eval.

The execution of each type of code depends on its own context. Of course, the context of global may cover many instances of function and eval. Each call to the function enters the context of the function execution and calculates the value of the variables in the function. Each execution of the eval function also enters the context of the eval execution to determine where to get the value of the variable.

Note that an function can create an infinite context because a call to a function (or even recursion) creates a new context.

Function foo (bar) {} / / call the same function,// generate three different// contexts in each call, with// different context state (e.g. Value// of the "bar" argument) foo (10); foo (20); foo (30)

One execution context can activate another context, just as one function calls another function (or the global context calls a global function) and then calls it layer by layer. Logically, this implementation is a stack, which we can call a context stack.

For example, if A context activates the context of B, then An is called caller,B and callee. One callee may also be the caller of another callee. (for example, a function in a global context calls its internal functions again. )

When a caller activates a callee, the caller suspends its own execution and gives control to the callee. So the callee is put on the stack, called the context in progress [running/active]

Execution context]. When the context of the callee ends, control is handed back to its caller, and the caller continues where it was paused. After the end of this caller, other contexts continue to be triggered. A callee can end its own context with return or exit with an exception.

All ECMAScript program execution can be thought of as an execution context stack [execution context (EC) stack]. At the top of the stack is the context in the active state.

When a program starts, it first enters the global execution context [global execution context], which is also the bottom element in the stack. This global program initializes, initializing and generating the necessary objects [objects] and functions [functions].

During the execution of this global context, it may activate some methods (initialized, of course), then enter their context, and then add new elements to the stack. After these initializations are over, the system waits for events (such as the user's mouse click, etc.), triggers some methods, and then enters a new context.

In this illustration, the context of some methods is called EC1, and the global context is called Global EC. Let's take a look at the stack form and demonstrate the process of entering and launching EC1 from the global context.

This is how the ECMAScript execution system manages code execution.

More information about the context can be found in Chapter 1. Execution context

As we just said, the context of each execution in the stack can be thought of as an object [object]. Next to the block, we will look at its structure and the type of state (or attribute) when it executes its code.

Execution context

The context of an execution can be abstractly understood as object. Each execution context has a series of properties (we call it context state) that track the progress of the execution of the associated code. This diagram is the structure of a context.

Of course, in addition to these three necessary attributes, a context also depends on other attributes (states) as appropriate.

Let's take a closer look at these three attributes.

Variable object

A VO [variable object] is a series of data associated with the context of the execution environment. It is a special object that is closely related to the context and stores variables and function declarations defined in the context.

Note: function expression [function expression] (not function declaration [function]

Declarations] is not included in VO [variable object].

Variable Object is an abstract concept, in a way, it means to use different object. Hereinafter referred to as VO. For example, in the context of global, variable object is also a global object [global object]. This is why we can point to global variables through the properties of the global object.

Let's look at the global execution context in the following example.

Var foo = 10 function bar () {} / / function declaration, FD (function baz () {}); / / function expression, FEconsole.log (this.foo = = foo, / / true window.bar = = bar / / true); console.log (baz); / / ReferenceError, "baz" is not defined

As shown in the following figure

As you can see, the function baz is a function expression, so it is not in VO, so there will be a prompt for ReferenceError, because it is read in the global environment, that is, outside the function expression.

Note that in ECMAScript, unlike other languages (for example, cCompact +), only the function functions creates a new scope. Variables and internal functions defined in a function are not available externally and do not affect global variables.

With eval, we usually enter a new eval context. Eval can use global VO, or you can use caller's VO.

In the case of functions and their VO, in the context of a function, a VO represents the activation variable [activation object], hereinafter referred to as AO.

Activation object

When a function is called and activated, the special object called AO (activation object) is created. It covers normal parameters and a special arguments object (this is a mapping table of parameters and has indexed properties). We can also think that AO is actually the VO of the function context.

For example, the VO of a function is actually a simple VO, but in addition to these variables and function definitions, there are parameters and arguments objects, which are called AO.

Consider the following situation

Function foo (x, y) {var z = 30; function bar () {} / / FD (function baz () {}); / / FE} foo (10,20)

Then the diagram of AO is as follows:

By the same token, function expression is not in the ranks of AO.

The details of this AO can be found at Chapter 2. Variable object

Let's move on to the third major target. As we all know, in ECMAScript, we use the internal function [inner functions]. In these internal functions, we may refer to its parent function variable, or global variable. We turn these variable objects into context-scoped objects [scope

Object of the context]. Similar to the prototype chain [prototype chain] discussed above, we call it the domain chain [scope] here.

Chain] .

Scope chain

A scope chain is a series of objects encountered in the process of searching for identifiers in the context of code.

This principle is very similar to the prototype chain, if the variable is not in its own scope, then it will look for the parent to the top level.

The identifier [Identifiers] can be understood as variable names, function declarations, and normal parameters. For example, when a function needs to reference a variable inside its own function, but the variable is not declared inside the function (or is not a parameter name), then the variable can be called a free variable [free

Variable]. Then we need to use the domain chain to search for these free variables.

In general, a scope chain includes the parent variable VO, the function's own VO, and AO. However, there are cases where other objects are also included, such as those that are dynamically added to the scope chain during execution-such as with or catch statements.

When dealing with a variable, the scope chain starts the search from AO and then goes all the way to the top. Very similar to the prototype chain.

Var x = 10; (function foo () {var y = 20; (function bar () {var z = 30 free variables / "x" and "y" are "free variables" / / and are found in the next (after// bar's activation object) object// of the bar's scope chainconsole.log (x + y + z);}) ();})

We assume that the object interaction of the scope chain is through an attribute called _ _ parent__, which points to the next object of the scope chain. This can be tested in Rhino Code, and this technique is indeed implemented in the ES5 environment (there is an outer link). Of course, you can also use a simple data to simulate this model. Using the concept of _ _ parent__, we can demonstrate the above code as follows. (therefore, the parent variable is in the [[Scope]] attribute of the existing function)

During code execution, if you use with or catch statements, the scope chain will be changed. These objects are simple objects, and they also have prototype chains. In this case, the scope chain will be searched from two dimensions.

First, in the original domain chain,

The chain of the scope of each link point (if the link point has a prototype)

Let's take a look at the following example

Object.prototype.x = 10 foo var w = 20 foo var y = 30 local variables var w / in SpiderMonkey global object// i.e. Variable object of the global// context inherits from "Object.prototype", / / so we may refer "not defined global// variable x", which is found in// the prototype chainconsole.log (x); / / 10 (function foo () {/ / "foo" local variables var w = 40; var x = 100 / / "x" is found in the / / "Object.prototype", because / / {z: 50} inherits from it with ({z: 50}) {console.log (w, x, y, z); / / 40, 10, 30, 50} / / after "with" object is removed / / from the scope chain, "x" is / / again found in the AO of "foo" context; / / variable "w" is also local console.log (x, w) / / 100,40 / and that's how we may refer / / shadowed global "w" variable in / / the browser host environment console.log (window.w); / / 20}) ()

We will have the following structural diagram. Note that before we search for _ _ parent__, we first go to the link to _ _ proto__.

Note that not all global objects are inherited by Object.prototype. The situation shown above can be tested in SpiderMonkey.

We will search the scope chain to find the variables we need. As mentioned earlier, at the end of a context, its state and itself will be destroyed. At the same time, this internal function is returned to the parent function. Perhaps this return function will activate another context later. How to keep a free variable still active? In theory, there is a concept that can solve this problem, called closure [Closure]. It is also directly related to the domain chain.

Closure

In ECMAScript, function [function] is the object of the basic level [first-class]. This means that a function can be used as an argument to another function (in this case, it is called "funargs", that is, "functional"

The function that receives arguments is called the high-level function [higher-order function], or similar to the operator [operator] in mathematics.

Similarly, a function can be returned as another function. A function that returns a function as a value is called a function that values [function valued functions] (or functions with functional).

Value)

With regard to the above funargs and functional value, one is called "Funarg problem" (or "A problem of a functional argument)". In order to solve this problem, we introduce "closure". Let's discuss these two problems in detail below (in ECMAScript, to solve these two problems, you need to use an attribute of the function [[Scope]]).

First of all, one type of "funarg problem" is bottom-up [upward funarg problem "]. When one function is the return value of another function, and the free variable [free] is used

It happens when variable]. Even if its parent context is over, it can refer to the parent's variable. When this internal function is created, the parent's scope chain is saved in its own scope [[Scope]]. When the function runs, the scope amount of the context is determined by the active variable [activation]

Object] and its [[Scope]] attribute.

Scope chain = Activation object + [[Scope]]

Note this important point again-during function creation [creation moment], the function saves the parent scope chain, because the saved scope chain is used to search for variables when the function is called later.

Take a look at the following function

Function foo () {var x = 10; return function bar () {console.log (x);};} / "foo" returns also a function// and this returned function uses// free variable "x" var returnedFunction = foo (); / / global variable "x" var x = 20 var / execution of the returned functionreturnedFunction (); / 10, but not 20

This form of scope is called static scope [static/lexical scope]. The x variable above is searched in [[Scope]] of the function bar. In theory, there will also be dynamic scope [dynamic]

Scope], the above x is interpreted as 20, not 10. However, EMCAScript does not use dynamic scope.

Another type of funarg problem is top-down [downward funarg problem]. In this case, the up and down of the parent will exist, but there will be ambiguity in judging the value of a variable. That is, which scope should this variable use? Is it the scope at the time the function is created or at execution time? To avoid this ambiguity, you can use closures, that is, static scopes.

Take a look at the following example

/ / global "x" var x = 10 there is no ambiguity / global functionfunction foo () {console.log (x);} (function (funArg) {/ / local "x" var x = 20; / / there is no ambiguity, / / because we use global "x", / / which was statically saved in / / [Scope] of the "foo" function, / / but not the "x" of the caller's scope, / / which activates the "funArg" funArg () / / 10, but not 20}) (foo); / / pass "down" foo as a "funarg"

From the above, we seem to conclude that the use of static scopes is a mandatory requirement of closures in the language. In some languages, however, it provides a combination of dynamic and static scopes that allow developers to choose which scope. In ECMAScript, however, only static scopes are used. So ECMAScript fully supports the use of attributes of [[Scope]]. We can define the closure as follows

A closure is a series of code blocks (functions in ECMAScript) and statically holds the scope of all parents. Use these saved scopes to search for free variables in the function.

Note that every function actually saves [[Scope]] during creation, so in theory, all functions in ECMAScript are closures.

It is also important that several functions may have the same parent scope (this is a common case, such as having several internal or global functions). In this case, variables that exist in [[Scope]] are shared. The change of variables in one closure will also affect that of another closure.

Function baz () {var x = 1; return {foo: function foo () {return + + x;}, bar: function bar () {return-- x;}};} var closures = baz (); console.log (closures.foo (), / / 2 closures.bar () / / 1)

The above code can be represented by this picture.

If you have this feature, it will be associated to create multiple functions in a loop. When we create a function in a loop, we may encounter unexpected situations, because all functions share the same variable. All functions have the same [[Scope]] and all point to the count of the last assignment.

Var data = []; for (var k = 0; k < 3; but not +) {data [k] = function () {alert (k);};} data [0] (); / / 3, but not 0data [1] (); / / 3, but not 1data [2] (); / / 3, but not 2

There are several ways to solve the problem of breeding pigeons. One is to provide a new object in the scope chain, such as adding a function.

Var data = []; for (var k = 0; k < 3; now it is correctdata +) {data [k] = (function (x) {return function () {alert (x);};}) (k); / / pass "k" value} / / now it is correctdata [0] (); / / 0data [1] (); / / 1data [2] (); / / 2

If you are interested in closures and their applications, you can check out Chapter 6. Closures.

For more in-depth links to the scope chain, check out Chapter 4. Scope chain

Let's move on to the next chapter, the last attribute of the context-this.

This value

Any object can use this in the context. I need to clarify a misunderstanding that in some descriptions this is always regarded as an attribute of a variable object. Please remember

This is an attribute of the execution context, not a property of a variable object

This feature is important because, unlike variables, this does not have a process similar to searching for variables. When you use this in your code, the value of the this is obtained directly from the context of the execution rather than from the scope chain. The value of this depends only on what happens when you enter the context in.

By the way, unlike ECMAScript, Python has a parameter for self, which is similar to this, but can be changed during execution. In ECMAScript, you can't assign a value to this, because again, this is not a variable.

In global context (global context), the value of this refers to the global object, which means that the is value is the variable itself.

Var x = 10 window.x console.log (x, / 10 this.x, / / 10 window.x / / 10)

In the function context [function context], this may become a different value based on each function call. This is provided by each caller, and caller is provided by calling the expression [call].

Expression] (that is, how this function is activated and called). For example, in the following example, foo is a callee that is activated in the global context. The following example shows that different caller causes different this.

/ / the code of the "foo" function// never changes, but the "this" value// differs in every activationfunction foo () {alert (this);} / caller activates "foo" (callee) and// provides "this" for the calleefoo (); / / global objectfoo.prototype.constructor (); / / foo.prototypevar bar = {baz: foo}; bar.baz (); / bar (bar.baz) (); / / also bar (bar.baz = bar.baz) () / / but here is global object (bar.baz, bar.baz) (); / / also global object (false | | bar.baz) (); / / also global objectvar otherFoo = bar.baz;otherFoo (); / / again global object

To learn more about why the this changes every time a function is called, see Chapter 3. This.

Thank you for your reading, these are the contents of "what are the objects in JavaScript?" after the study of this article, I believe you have a deeper understanding of what the objects in JavaScript have, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report