Deep Learning of JavaScript objects and deep learning of javascript

Source: Internet
Author: User
Tags hasownproperty

Deep Learning of JavaScript objects and deep learning of javascript

In JavaScript, all objects except the five primitive types (numbers, strings, Boolean values, null, and undefined) are objects. Therefore, I don't know how to continue learning objects?


I. Overview

An object is a composite value that aggregates many values (original values or other objects) and can be accessed through attribute names. The attribute name can be any string that contains an empty string. JavaScript objects can also be called a data structure, as we often hear about "hash", "hashtable", and "dictionary) "," associative array )".

Objects in JavaScript canThere are three types:

① Built-in objects, such as arrays, functions, and dates;

② The Host object defined by the host environment embedded by the JavaScript interpreter (such as a browser), such as HTMLElement;

③ Custom object, defined by the programmer using code;

The property of the object can beThere are two types:

① Self-owned property: the property defined directly in the object;

② Inheritance property: the property defined in the object's prototype object (for details about the prototype object, see below );

Ii. Object Creation

Since learning objects, how can we not understand how to create objects? The following basic questions may have been asked by the interviewees:

What are the two methods for creating JavaScript objects? (Or: How to Create a JavaScript Object ?)

I have been asked this question twice. There are many online saying "two ways to create objects", but there are three methods as far as my books are concerned! Here we will talk about these three methods:

1. Direct object volume

A ing table composed of several name/value pairs. The name/value pairs are separated by colons, and the name/value pairs are separated by commas. The entire ing table is enclosed in curly brackets. The property name can be either a JavaScript identifier or a string's direct quantity. That is to say, the following two methods of creating object obj are exactly the same:

Var obj = {x: 1, y: 2 };
Var obj = {'X': 1, 'y': 2 };

2. Create an object through new

After the new operator is followed by a function call, that is, the constructor creates and initializes a new object. For example:

1 var o = new Object (); // create an empty Object, same {}
2 var a = new Array (); // create an empty Array, same []
3 var d = new Date (); // create a Date object that represents the current time

Let's talk about the constructor.

3. Object. create ()

ECMAScript5 defines a method named Object. create (), which creates a new Object. The first parameter is the prototype Object of this Object (it seems that the prototype Object has not been released... The second optional parameter is used to further describe the attributes of the object, and the second parameter is described below (because the third method is defined in ECMAScript5, so we used to talk about the two methods for creating objects? I think this is the reason ). This method is easy to use:

1 var o1 = Object. create ({x: 1, y: 2}); // The Object o1 inherits the attributes x and y
2 var o2 = Object. create (null); // The Object o2 has no prototype.

The following three are exactly the same:

1 var obj1 = {};
2 var obj2 = new Object ();
3 var obj3 = Object. create (Object. prototype );

To explain why the three methods are exactly the same, let's first explain the prototype objects in JavaScript (ah, let the guest wait !), Remember a great God said:

Javascript is an object-based language. Almost everything you encounter is an object. However, it is not a real Object-Oriented Programming (OOP) language, because its syntax does not contain class ).

Object-Oriented Programming Language JavaScript, no class !!! So how does it implement inheritance? Yes, it is through the prototype object. Basically, every JavaScript Object (except null) is associated with another object. Another object is the so-called prototype object (the prototype object can also be referred to as the prototype, it is not as complex as you think, and it is just an object ). Each object inherits attributes from the prototype object, and the value of the prototype attribute of an object (this attribute is automatically generated by default when the object is created, and does not need to be displayed with custom attributes) is the prototype object of this object, that is, obj. prototype is the prototype object of object obj.

The prototype object first mentioned this and then went back to the above question. With the understanding of the prototype object, the following JavaScript language does not need to be explained too much:

① All prototype objects created directly through objects are Object. prototype objects;

② The prototype Object of the Object created by the keyword new and the constructor is the value of the constructor prototype attribute. Therefore, the prototype of the Object created by the constructor Object is Object. prototype;

The meaning of the first parameter of Object. create () in the third method for Object creation is also supplemented.

3. query and setting properties

It is not enough to learn how to create an object, because only objects with some attributes can actually play a role! So, let's continue to learn the attributes of the object!

You can use the dot (.) or square brackets ([]) operator to obtain and set attribute values. For vertex (.) the right side must be an identifier named after the property name (Note: JavaScript language identifiers have their own legal rules, not the same as strings with quotation marks ); for square brackets ([]), the square brackets must contain a string expression (the string variation is also acceptable, other values that can be converted into strings, such as numbers, can also be dropped.) This string is the name of the attribute. For example:

var obj = {x: 1, y: 2}; 
obj.x = 5; 
obj['y'] = 6 

As mentioned in the overview, JavaScript objects have "own attributes" and "inherited attributes ". When you query the property x of object obj, the system first checks whether there is x in the property of object obj. If not, it searches for the prototype object obj of object obj. whether prototype has attribute x. If not, the object obj will be searched. prototype object obj. prototype. whether prototype has attribute x, so that it can be found until x is found or the found prototype object is an undefined object. We can see that a pair of objects inherits many prototype objects, and these prototype objects constitute a "chain", which is what we usually call the "prototype chain ", this inheritance is prototypal inheritance in JavaScript ).

When an object o queries a property, it will follow the prototype chain step by step, but when it sets the value of a property, it will only modify its own property (if the object does not have this property, this attribute will be added and assigned values), and the attributes of other objects on the prototype chain will not be modified.

Iv. accessors attributes getter and setter

All of the above are common object attributes, which are called "data property". The data attribute has only one simple value. However, in ECMAScript 5, the attribute value can be replaced by one or two methods. The two methods are getter and setter, the attributes defined by getter and setter are called "accessors property ).

When the program queries the value of the accessor attribute, JavaScript calls the getter method (No parameter ). The return value of this method is the value of the attribute access expression. When the program sets the value of an accessor attribute, JavaScript calls the setter method and passes the value on the right of the value assignment expression as a parameter to setter. If the property has both the getter and setter methods, it is a read/write attribute. If it only has the getter method, it is a read-only attribute and no error is returned when assigning values to the read-only attribute, but it cannot succeed. If it only has the setter method, it is a write-only attribute, and the read-only attribute always returns undefined. Let's look at the actual example:

var p = { 
  x: 1.0, 
  y: 2.0, 
  get r(){ return Math.sqrt(this.x*this.x + this.y*this.y); }; 
  set r(newvalue){ 
    var oldvalue = Math.sqrt(this.x*this.x + this.y*this.y); 
    var ratio = newvalue/oldvalue; 
    this.x *= ratio; 
    this.y *= ratio; 
  }, 
  get theta(){ return Math.atan2(this.y, this.x); }, 
print: function(){ console.log('x:'+this.x+', y:'+this.y); } 
}; 

As shown in the example, the accessor property defines one or two functions with the same name as the property. The function definition does not use the function keyword, but uses get and set, the property name and function are not separated by the escape number. In comparison, the print attribute below is a function method. Note: The use of the this keyword in getter and setter here, JavaScript calls these functions as object methods, that is, this in the function body points to this object. The following describes the instance running result:


As the console outputs, r and theta are just a Value Attribute like x and y, and print is a method attribute.

Although the accessors added by ECMAScript 5 are more complex than common attributes, they make the operation object property key-value pairs more rigorous.

5. Delete attributes

The code of the program ape is generally used to add, delete, modify, and query the code. I have already mentioned the function of adding, modifying, and querying the code. Let's talk about deleting the code!

The delete operator can delete an object's attributes. Its operations should be an attribute access expression. However, delete only disconnects the property from the host object and does not operate on the property in the property:

var a = {p:{x:1}}; 
var b = a.p; 
delete a.p; 

After executing this code, B. the value of x is still 1. Because the reference of the deleted attribute still exists, sometimes this less rigorous code may cause memory leakage. Therefore, when destroying an object, you must traverse the attribute in the attribute, delete in sequence.

When the delete expression returns true:

① When the deletion is successful or has no side effects (for example, deleting a non-existent attribute;

② If the delete operation is not an attribute access expression;

var obj = {x: 1, get r () {return 5;}, set r (newvalue) {this.x = newvalue;}};
delete obj.x; // Delete attribute x of object obj, return true
delete obj.x; // Delete non-existent attributes, return true
delete obj.r; // Delete property r of object obj, return true
delete obj.toString; // No side effects (toString is inherited and cannot be deleted), return true
delete 1; // Number 1 is not an attribute access expression, returns true

When the delete expression returns false:

① When you delete an attribute whose configurability is false (configurability is a feature of the attribute, which will be discussed below;

Delete Object. prototype; // false is returned. The prototype attribute cannot be configured.
// A variable declared through var or a function declared by function is a non-configurable attribute of a global object.
Var x = 1;
Delete this. x; // return false
Function f (){}
Delete this. f; // return false

6. Attributes

The configurable attributes of the attributes have been mentioned above, because the detection attributes and enumeration attributes mentioned below also use these attributes. So let's talk about the attributes first!

In addition to the names and values, attributes also contain three features that can be identified: writeable, enumerable, and configurable. You cannot set these features in ECMAScript 3. All the properties created through ECMAScript 3 are writable, enumerative, and configurable, and cannot modify these features. ECMAScript 5 provides APIs for querying and setting these attributes. These APIs are very useful for library developers because:

① You can use these APIs to add methods to the prototype objects and set them to non-enumerated, which makes them more like built-in methods;

② You can use these APIs to define attributes that cannot be modified or deleted for the object, so as to "Lock" the object;

Here we regard the getter and setter methods of the accessors attribute as the attribute features. According to this logic, we can also regard the attribute value as a property feature. Therefore, attributes can contain a name and four features. Data attributes have four features: value, writable, enumerable, and configurable ). Accessors attributes do not have value characteristics and writability. Their writability is determined by whether the setter method exists or not. Therefore, the four features of accessors are read (get), write (set), enumeration, and configurability.

To query and set attributes, ECMAScript 5 defines an object named "property descriptor", which represents the four attributes. The attributes of Descriptor objects and the attributes they describe are of the same name. Therefore, the descriptor objects of data properties include value, writable, enumerable, and retriable. The descriptor object of the accessor attribute replaces the value and writable with the get and set attributes. Writable, enumerable, and retriable are both boolean values. Of course, the get and set attributes are function values. You can call Object. getOwnPropertyDescriptor () to obtain the attribute descriptor of a specific Object attribute:


From the function name, we can see that Object. getOwnPropertyDescriptor () can only get the descriptor of its own attribute. It returns undefined for both the inherited attribute and the non-existent attribute. To obtain the properties of the inherited attributes, You need to traverse the prototype chain (not to traverse the prototype chain? Don't worry, as mentioned below ).

If you want to set the property features or make the new property have some features, you need to call the Object. definePeoperty:



You can see:

① The property descriptor Object passed into Object. defineProperty () does not need to contain all four features;

② Writability controls the modification of attribute values;

③ The enumerable property determines whether the attribute can be enumerated (as described below );

④ Configurability controls the modification of other features (including whether the previously mentioned attributes can be deleted;

If you want to modify or create multiple attributes at the same time, you need to use Object. defineProperties (). The first parameter is the object to be modified, and the second parameter is a ing table, which contains the names of the attributes to be created or modified, and their attribute descriptors, for example:

var p = Object.defineProperties({},{ 
  x: {value: 1, writable: true, enumerable: true, configurable: true}, 
  y: {value: 2, writable: true, enumerable: true, configurable: true}, 
  r: {get: function(){return 88;}, set: function(newvalue){this.x =newvalue;},enumerable: true, configurable: true}, 
  greet: {value: function(){console.log('hello,world');}, writable: true, enumerable: true, configurable: true} 
}); 

I believe you have also seen from the instance that both Object. defineProperty () and Object. defineProperties () return the modified Object.

As we mentioned earlier, when getter and setter accessors are used, the object Direct Volume syntax is used to define accessors for new objects, however, you cannot query the getter and setter methods of attributes or add new accessors to existing objects. In ECMAScript 5, you can do this through Object. getOwnPropertyDescriptor () and Object. defineProperty! However, before ECMAScript 5, most browsers (except IE) have supported the get and set statements in the object direct syntax. Therefore, these browsers also provide non-standard old-fashioned APIs for querying and setting getter and setter. These APIs consist of four methods, and all objects have these methods. _ LookupGetter _ () and _ lookupSetter _ () are used to return the getter and setter methods of a naming attribute. _ DefineGetter _ () and _ defineSetter _ () are used to define getter and setter. Both of these methods are prefixed with two underscores, and the two underscores are suffixed to indicate that they are non-standard methods. Their usage is as follows:


VII. Check attributes

JavaScript objects can be seen as a set of attributes, So we sometimes need to determine whether a property exists in an object. This is the detection attribute to be discussed next.

There are also three methods for detecting the attributes of an object. The following describes their functions and differences in detail!

1. in Operator

The left side of the in operator is the attribute name (string) and the right side is the object. True is returned if the property of an object contains its own property or an inherited property. Otherwise, false is returned.

In order to test, we first give the Object. add an enumerative property m to prototype, and a non-enumerative property n. Then, define two enumerated property x and one non-enumerative property y for object obj, in addition, the Object obj is created in the form of a direct Object, inheriting the Object. prototype. See the example below:


The running result shows that the attribute name (string) is on the left side of the in operator, and the object is on the right side. If an object's own or inherited attributes (whether or not these attributes can be enumerated) contain this attribute, true is returned; otherwise, false is returned.

2. hasOwnProperty ()

The hasOwnProperty () method of an object is used to check whether a given name is an object's own property (whether or not these attributes can be enumerated). It returns false for an inherited property. See the example below:


3. propertyIsEnumerable ()

PropertyIsEnumerable () is an enhanced version of hasOwnProperty (). It returns true only when its own property is detected and Its enumerable property is true. Or instance:


8. Enumeration Properties

Compared with the detection attribute, we usually use enumeration attributes. We usually use a for/in loop to enumerate the attributes. It can traverse all the self-owned and inheritance attributes that can be enumerated in the object in the loop body, and assign the attribute name to the loop variable. Continue instance:


I used to think that for/in loops have a great relationship with the in operator. Now they have different rules! Of course, if you do not want to traverse the inherited attributes here, add hasOwnProperty () in the for/in loop to judge:

for(prop in obj){ 
  if(obj.hasOwnProperty(prop)){ 
    console.log(prop); 
  } 
} 

In addition to the for/in loop, ECMAScript 5 also defines two functions that can enumerate attribute names:

① Object. getOwnpropertyNames (), which returns the names of all its own attributes of the Object, whether or not it can be enumerated;

② Object. keys (), which returns the names of its own attributes that can be enumerated in the Object;

Or instance:


9. Three special attributes of an object

Each object has prototype, class, and extensible attribute ). These three are the special attributes of objects (they are just attributes of objects, and they are not as complicated as they are ).

1. Prototype attributes

As mentioned above, the prototype property of an object is used to inherit attributes (a bit around ...), This attribute is so important that we often call "o's prototype attribute" directly "o's prototype ". The prototype property is set at the beginning of the Instance creation (that is, the value of this property is automatically set by JavaScript by default, and we will talk about how to manually set it later), as mentioned above:

① Objects directly created through objects use Object. prototype as their prototype;

② Objects created through the new + constructor use the prototype attribute of the constructor as their prototype;

③ Use Object. the object created by create () uses the first parameter (if this parameter is null, the prototype property value of the object is undefined; if this parameter is undefined, an error is returned: Uncaught TypeError: object prototype may only be an Object or null: undefined) as their prototype;

How can we query the prototype attributes of an object? In ECMAScript 5, you can pass an Object as a parameter to Object. getPrototypeOf () to query its prototype. For example:


However, in ECMAScript 3, there is no Object. getPrototypeOf () function, but the expression obj is often used. constructor. prototype is used to detect the prototype of an object, because each object has a constructor attribute to indicate the constructor of this object:

① The constructor attribute of the Object directly created by the Object directs to the constructor Object ();

② The constructor attribute of the object created through the new + constructor points to the constructor;

③ The constructor attribute of the Object created through Object. create () points to the same as the constructor attribute of the prototype Object;

To check whether an object is a prototype of another object (or is in the prototype chain), you can use the isPrototypeOf () method. For example:


There is also a non-standard but many browsers have implemented the object's property _ proto _ (also two underscores start and end, to indicate that it is not standard ), it is used to directly query/set the prototype of an object.

2. class attributes

The class attribute of an object is a string used to indicate the object type information. Both ECMAScript 3 and ECMAScript 5 do not provide methods to set this attribute, and only one indirect method can be used to query it. The default toString () method (inherited from Object. prototype) returns this type of string: [object class]. Therefore, to obtain the class of an object, you can call the toString () method of the object and extract the characters between the 8th and the penultimate position of the returned string. However, many toString () methods inherited by objects are overwritten (such as Array and Date). To call the correct toString () version, you must call Function indirectly. call () method. The following code returns the class of any object passed to it:

function classof(obj){
  if(o === null){
    return 'Null';
  }
  if(o === undefined){
    return 'Undefined';
  }
  return Object.prototype.toString.call(o).slice(8, -1);
}

The classof () function can input any type of parameter. The following is an example:



Conclusion: The running results show that the class attributes of the objects created in three ways are 'object '.

3. scalability

Object scalability indicates whether new attributes can be added to an object. All built-in and custom objects are displayed extensible (unless converted to unextensible), and the scalability of host objects is defined by the JavaScript engine. ECMAScript 5 defines the functions used to query and set object Scalability:

① (Query) Pass the Object into Object. isExtensible () to determine whether the Object is extensible.

② (SET) If you want to convert an Object to non-extensible, you need to call Object. preventExtensions () and pass the Object to be converted as a parameter. Note:

A. Once an object is converted to an extensible one, it cannot be converted back to extensible;

B. preventExtensions () only affects the scalability of the object. If attributes are added to the prototype of an unextensible object, the unextensible object will inherit these new attributes;

Furthermore, Object. seal () is similar to Object. preventExtensions (). In addition to setting an Object as unextensible, you can also set all its own attributes to unconfigurable. Objects that have been closed (sealed) cannot be unblocked. You can use Object. isSealed () to check whether the Object is closed.

Furthermore, Object. freeze () will lock the Object more strictly-"freeze" (frozen ). In addition to setting an object as not extensible and setting its properties as not configurable, you can also set all its own data attributes to read-only (if the object's accessor attribute has a setter method, the accessors attribute will not be affected and can still be called by assigning values to the attribute ). Use Object. isFrozen () to check whether the Object is summarized.

Summary: Object. preventExtensions (), Object. seal (), and Object. freeze () both return the passed objects, that is, they can be called through nesting:

Var obj = Object. seal (Object. create (Object. freeze ({x: 1}), {y: {value: 2, writable: true }));

This statement uses Object. the create () function passes in two parameters: the first parameter is the prototype object of the created object, and the second parameter is the property directly defined for the created object, the attributes are defined.

10. Object serialization

After we have finished the object attributes and the characteristics of the object attributes, there are still a lot of things. I wonder if you have looked dizzy. However, the following is a simple topic!

Object serialization refers to converting the object state to a string or restoring the string to an object. ECMAScript 5 provides built-in functions JSON. stringify () and JSON. parse () for serialization and restoration of objects. These methods use JSON as the data exchange format. The full name of JSON is "JavaScript Object Notation"-JavaScript Object Notation. Its syntax and JavaScript Object are very similar to the syntax of array direct quantity:


The final jsonObj is the deep copy of obj.

JSON syntax is a subset of JavaScript. It cannot represent all values in JavaScript. Objects, arrays, strings, infinite numbers, true, false, and null are supported, and they can be serialized and restored. Note:

① The result of NaN, Infinity, and-Infinity serialization is null;

② JSON. stringify () can only serialize self-owned properties that can be enumerated by objects;

③ The serialized Date object is a Date string in ISO format (refer to Date. toJSON () function), but JSON. parse () still retains their string form, rather than restoring them to original date objects;

④ Functions, RegExp, Error objects, and undefined values cannot be serialized or restored;

The above is all the content of this article, hoping to help you learn.


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.