JavaScript Object Deep Learning Summary (classic) _javascript skills

Source: Internet
Author: User
Tags current time object object object serialization serialization shallow copy hasownproperty

I. Overview

An object is a composite value that aggregates many values (original values or other objects) and accesses them through the property name. The property 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 (hash), hash list (hashtable), Dictionary (dictionary), associative array (associative array).

Objects in JavaScript can be grouped into three categories:

① built-in objects, such as arrays, functions, dates, and so on;

② host objects, such as htmlelement, that are defined by the host environment (such as browsers) embedded in the JavaScript interpreter;

③ custom object, which is defined by the programmer in Code;

The properties of an object can be grouped into two categories:

① own properties (own property): attributes that are defined directly in the object;

② inherited properties (inherited property): attributes defined in the object's prototype object (details about the prototype object below);

Two. Creation of objects

Since learning objects, how can you not know how to create objects? The students who interviewed the front desk may have been asked this basic question:

What are the two ways to create a JavaScript object? (or: What about creating a JavaScript object?) )

I've been asked this question two times. "Two ways to create objects" is a lot of online, but there are three ways to read books. Here's a concrete discussion of these three approaches:

1. Direct volume of objects

The object's direct quantity is a mapping table consisting of several name/value pairs, separated by a colon, separated by a comma between the name/value pairs, and the entire mapping table enclosed in curly braces. The property name can be either a JavaScript identifier or a string literal, meaning that the following two creation objects obj are written in exactly the same way:

var obj = {x:1, y:2};
var obj = {' x ': 1, ' Y ': 2};

2. Creating objects from New

The new operator follows a function call, which is the constructor, that creates and initializes an object. For example:

1 var o = new Object (); Create an empty object, just like {}
2 var a = new Array (); Create an empty array, as with []
3 var d = new Date (); Creates a Date object that represents the current time

About the constructor-related content later.

3.object.create ()

ECMAScript5 defines a method named Object.create () that creates a new object in which the first parameter is a prototype object of the object (as if the prototype object has not yet been interpreted ...). The Second optional parameter is used to further describe the object's properties, and the second argument follows (because this third method is defined in ECMAScript5, so we used to say the two methods of creating objects) Personally think it should be this reason). This method is simple to use:

1 var O1 = object.create ({x:1, y:2}); Object O1 inherits properties X and Y
2 var O2 = object.create (null); Object O2 No prototypes

The following three species are exactly the same:

 var obj1 = {};
 var obj2 = new Object ();
var obj3 = object.create (Object.prototype);

To explain why these three ways are exactly the same, let's first explain the prototype object in JavaScript (hey, let the guest Nagyu wait!) ), remember a great God said:

JavaScript is an object-based (object-based) language, and almost all of the things you encounter are objects. However, it is not a true object-oriented programming (OOP) language because its syntax has no class (class).

Object-oriented programming language JavaScript, no class!!! So, how does it implement inheritance? Yes, it is through the prototype object. Basically, each JavaScript object (except NULL) is associated with another object, and the "Other" object is the so-called prototype object (the prototype object can also be abbreviated as a prototype, not as complicated as it is, and it is only an object). Each object inherits properties from the prototype object, and the value of the prototype property of an object (which is automatically generated by default when the object is created, and does not need to be displayed) is the prototype object of the object, i.e. Obj.prototype is the prototype object of object obj.

The prototype object comes to this, goes back to the question above, has the knowledge of the prototype object, the following is the JavaScript language rule that does not require too much explanation:

① the prototype object of all objects created by direct volume of objects is the Object.prototype object;

② the prototype object of the object created by the keyword new and constructor is the value of the constructor prototype property, so the prototype of the object created by the constructor object is Object.prototype;

It now complements the third method of creating an Object Object.create () The meaning of the first parameter.

Three. Queries and settings for properties

It's not enough to learn how to create objects, because objects can really play a role only if they have some attributes! Then, go down and learn the attributes of the object!

You can get and set the value of a property by using the dot (.) or square brackets ([]) operator. For points (.), the right side must be an identifier named after the property name (note: The identifier for the JavaScript language has its own legal rules and is different from the quoted string); for square brackets ([]), the square brackets must be a string expression (the string variable of course, too, Other values that can be converted to strings, such as numbers, can also be dropped, which is the name of the attribute. As in the following example:

var obj = {x:1, y:2}; 
obj.x = 5; 

As described in the overview, JavaScript objects have "own properties" and "Inherited properties". When querying the property X of Object obj, you first find out if the object obj has an X in its own property, and if not, it looks for the object obj's prototype object Obj.prototype whether there is an attribute x, and if not, then finds the object Obj.prototype's prototype object Obj.prototype.prototype whether there is an attribute x, so until you find an X or the prototype object you find is a undefined object. As you can see, an object inherits a lot of prototype objects, which form a chain, which is what we call the "prototype chain," which is "archetypal inheritance" in JavaScript (Prototypal inheritance).

Object o querying for a property, as mentioned above, is found along the prototype chain, however, when it sets the value of a property, it modifies its own property (which is added and assigned if the object does not have this property) and does not modify the properties of other objects on the prototype chain.

Four. Accessor Properties getter and setter

What we are talking about above is the common object attribute, which is called Data property, and the Data property has only one simple value. In ECMAScript 5, however, property values can be replaced by one or two methods, which are getter and setter, and properties that are defined by getter and setter are called accessor properties (accessor property).

When the program queries the value of accessor properties, JavaScript invokes the Getter method (no parameters). The return value of this method is the value of the property-access expression. When the program sets the value of an accessor property, JavaScript invokes the setter method, passing the value on the right side of the assignment expression as a parameter to the setter. If the attribute has both a getter and setter method, it is a read/write property, and if it has only the Getter method, it is a read-only property, and assigning the read-only property is not an error, but not a success; if it has only a setter method, it is a write-only property, Reading a write-only property always returns undefined. Look at a practical 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 the example says, the accessor attribute defines one or two functions with the same name as a property, which does not use the Function keyword, but uses get and set, and does not use a colon to separate the property name from the function body. In contrast, the following print property is a function method. Note: The use of this keyword in the getter and setter here, JavaScript calls these functions as object methods, that is, this point in the function body points to the object. Below is a look at the results of the example run:

As with the output of the console, R, Theta is just a value property as X,y, and print is a method property.

ECMAScript 5 adds this accessor, although more complex than ordinary properties, but also makes the action object attribute key value is more rigorous.

Five. Delete attributes

Program Ape code is generally to achieve increase, delete, change, check function, the front has said the increase, change, check, the following said to delete it!

The delete operator can delete an object's properties, and its operand should be a property access expression. However, delete simply disconnects the property from the host object and does not manipulate the properties in the property:

var a = {p:{x:1}}; 
var B = A.P; 

After executing this code, the value of b.x is still 1, because the reference to the deleted attribute is still present, so sometimes this kind of imprecise code will cause memory leak, so when destroying the object, we should walk through the property in the property and delete it in sequence.

The case in which the delete expression returns true:

① Delete succeeds or does not have any side effects (such as deleting nonexistent attributes);

② If delete is not a property access expression;

var obj = {X:1,get R () {return 5;},set R (newvalue) {this.x = newvalue;}};
Delete obj.x; Delete Object Obj's property x, return True
Delete obj.x; To delete a property that does not exist, return true
Delete OBJ.R; Delete Object Obj's property R, return True
Delete obj.tostring; No side effects (ToString is inherited and cannot be deleted), returns True
Delete 1; Number 1 is not an attribute access expression, returns True

The case where the delete expression returns false:

① deletes the configurable (configurable property is an attribute of the attribute, which is described below) when the property is false;

Delete Object.prototype; Returns the False,prototype property is not configurable

Variables declared by Var or function declared are not configurable properties of the global object
var x = 1;
Delete this.x; return False
function f () {}
Delete this.f; return False

Six. Attributes of properties

The attribute's configurable properties are mentioned above, because the properties and enumeration attributes are also used to attribute these concepts, so let's talk about attributes now.

In addition to containing names and values, attributes contain three features that identify them as writable, enumerable, and configurable. These attributes cannot be set in ECMAScript 3, and all properties created by the ECMAScript 3 program are writable, enumerable, and configurable and cannot be modified. ECMAScript 5 provides an API for querying and setting these property attributes. These APIs are useful for library developers because:

① can use these APIs to add methods to the prototype objects and set them to be not enumerable, which makes them more like built-in methods;

② can use these APIs to define objects that cannot be modified or deleted, thereby "locking" the object;

Here we look at the getter and setter methods of accessor properties as attributes. By this logic, we can also think of the value of a property as an attribute. Therefore, you can consider a property to contain a name and 4 attributes. The 4 attributes of a data property are its value, writeable (writable), enumerable (enumerable), and configurable (configurable). Accessor properties do not have value attributes and are writable by whether the setter method exists or not. Therefore, the 4 attributes of accessor properties are read (get), write (set), enumerable, and configurable.

To implement query and setup operations for attribute attributes, an object named property descriptor is defined in ECMAScript 5, which represents the 4 attributes. The properties of the descriptor objects are the same as the attribute attributes they describe. Therefore, the properties of the descriptor object for the Data property are value, writable, enumerable, and configurable. The descriptor object for accessor properties replaces value and writable with the Get property and the Set property. Where writable, enumerable, and configurable are Boolean values, of course, get and set properties are function values. You can get a property descriptor for an object-specific property by calling Object.getownpropertydescriptor ():

As can be seen from the function name, Object.getownpropertydescriptor () can only get the descriptor of its own property, and it returns undefined for both inherited and nonexistent attributes. To get the attributes of an inherited property, you need to traverse the prototype chain (not traversing the prototype chain). Don't worry, the following will be said.

To set attributes for a property, or to have a new property have some attribute, you need to call Object.definepeoperty (), pass in the object that you want to modify, the name of the property to create or modify, and the property descriptor object:

You can see:

① the property descriptor object for the incoming Object.defineproperty () does not have to contain all 4 attributes;

② can control the modification of the attribute value;

③-Enumerable controls whether an attribute is enumerable (enumerated properties, which are said below);

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

If you want to modify or create multiple properties at the same time, you need to use Object.defineproperties (). The first parameter is the object to modify, and the second parameter is a mapping table that contains the names of the properties to be created or modified, and their property descriptors, for example:

var p = object.defineproperties ({},{ 
  x: {value:1, writable:true, Enumerable:true, configurable:true}, 
  y: {valu E:2, Writable:true, Enumerable:true, configurable:true}, 
  r: {get:function () {return;}, 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 example: Object.defineproperty () and Object.defineproperties () both return the modified object.

Before we say getter and setter accessor properties use object Direct amount syntax to define accessor properties for new objects, but you cannot query the getter and setter methods of properties or add new accessor properties to an existing object. In ECMAScript 5, you can do this through Object.getownpropertydescriptor () and Object.defineproperty (). Before ECMAScript 5, however, most browsers (except IE) already supported get and set writing in object Direct-volume syntax. So these browsers also provide non-standard, old-fashioned APIs for querying and setting getter and setter. These APIs consist of 4 methods, all of which are owned by all objects. __lookupgetter__ () and __lookupsetter__ () are used to return the getter and setter methods of a named property. __definegetter__ () and __definesetter__ () are used to define getter and setter. All four methods are prefixed with two underscores, and two underline suffixes to indicate that they are non-standard methods. The following are their uses:

Seven. Detection properties

JavaScript objects can be viewed as a collection of attributes, so we sometimes need to determine whether a property exists in an object, which is the next detection attribute.

There are three ways to detect the properties of an object, and here's how they work and what's different!

1.in operator

The in operator is the property name (string) on the left and the object on the right. Returns true if the object's own property or inherited property contains this property, otherwise it returns false.

To experiment, we first add an enumerable property m to the object Object.prototype, an enumerable property n; Then, define two enumerable property X, an enumerable attribute Y, and object obj in Object direct form, to object obj. Inherited the Object.prototype. Look at the example below:

As you can see from the run result: The in operator is the property name (string) on the left and the object on the right. Returns true if the object's own or inherited properties, regardless of whether they are enumerable or not, return False if they are included in the property.

2.hasOwnProperty ()

The hasOwnProperty () method of an object is used to detect whether a given name is an object's own property, regardless of whether they are enumerable or not, and it returns false for inherited properties. Look at the example below:

3.propertyIsEnumerable ()

propertyIsEnumerable () is an enhanced version of hasOwnProperty () that returns true only if it detects a property of its own and if the property is enumerable true. Or an example:

Eight. Enumeration properties

In relation to detection properties, we are more commonly used to enumerate properties. Enumeration properties We usually use the for/in loop, which iterates through all the enumerable own and inherited properties in the object, assigning the property name to the loop variable. Continue to the previous instance:

I thought the for/in loop had something to do with the in operator, and now it looks like their rules are different. Of course, if you don't want to traverse the inherited attribute here, add a layer of hasownproperty () to the for/in loop:

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 property names:

①object.getownpropertynames (), which returns the name of all its own properties, whether or not enumerated;

②object.keys (), which returns the name of an enumerable property in an Object object;

Or an example:

Nine. Three special properties of objects

Each object has an associated prototype (prototype), Class (Class), and extensibility (extensible attribute). These three are the special attributes of the object (they are just the object's attributes, and they are not as complicated as they think).

1. Prototype properties

As mentioned earlier, the object's prototype property is used to inherit the property (a bit around ...). This attribute is so important that we often call the "O prototype" directly "O's prototype". The prototype property is set at the beginning of the instance (that is, the value of this property is automatically set by JavaScript by default, and we'll say how to set it ourselves manually), as mentioned earlier:

① objects created by direct volume of objects use Object.prototype as their prototypes;

② objects created by the New+ constructor use the prototype property of the constructor as their prototype;

③ objects created by object.create () use the first argument (if this argument is null, the object's prototype property value is undefined; if this parameter is undefined, an error is made: uncaught typeerror:object Prototype May is an Object or null:undefined as their prototype;

So, how do you query the prototype properties of an object? In ECMAScript 5, passing an object as a parameter into the object.getprototypeof () can query its prototype, for example:

But in ECMAScript 3, there is no object.getprototypeof () function, However, the expression Obj.constructor.prototype is often used to detect the prototype of an object because each object has a constructor attribute that represents the constructor of the object:

① the constructor property of the object created by the object's direct volume points to the constructor object ();

② the constructor property of the object created by the New+ constructor to point to the constructor;

③ the constructor property of an object created by Object.create () points to the same point as the constructor property of its prototype object;

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

There is also a nonstandard but many browsers have implemented the properties of the object __proto__ (also two underscore start and end to indicate that it is non-standard), to directly query/Set the object's prototype.

2. Class Properties

The class attribute of an object is a string that represents the type information of an object. ECMAScript 3 and ECMAScript 5 do not provide a way to set this property, and there is only one indirect way to query it. The default ToString () Method (inherited from Object.prototype) returns a string of this format: [Object class]. Therefore, to get the object's class, you can call the object's ToString () method, and then extract the characters between the 8th and penultimate positions of the returned string. However, many object-inherited ToString () methods override (for example, Array, date, and so on), and in order to invoke the correct toString () version, the Function.call () method must be called indirectly. The following code can return 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 pass in any type of argument. The following are examples of usages:

Summary: From the results of the run, you can see that the class properties of objects created in three ways are ' object '.

3. Scalability

The extensibility of an object is used to indicate whether a new property can be added to an object. All built-in and custom objects are displayed as extensible (unless they are converted to not extensible), and the extensibility of the host object is defined by the JavaScript engine. The functions used to query and set object extensibility are defined in ECMAScript 5:

The ① (query) determines whether the object is extensible by passing the object into the Object.isextensible ().

② (SET) if you want to convert an object to not extensible, you need to call Object.preventextensions () to pass the object to be converted as a parameter. Attention:

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

B.preventextensions () only affects the extensibility of the object itself, and if you add attributes to a prototype of an object that is not extensible, the object will inherit these new attributes as well;

Further, Object.seal () and object.preventextensions () are similar in that you can set all of the object's own properties to be not configurable except to set the object to be extensible. For those objects that have been closed (sealed), they cannot be solved. You can use object.issealed () to detect whether an object is closed.

Further, Object.freeze () will lock objects more tightly-"Frozen" (frozen). In addition to setting an object to be extensible and setting its properties to be not configurable, you can also set all of its own data properties to read-only (if the object's accessor properties have setter methods, accessor properties will not be affected and can still be called by assigning values to the property). Use Object.isfrozen () to detect whether the object is summarized.

Summary: Object.preventextensions (), Object.seal (), and Object.freeze () all return incoming objects, that is, they can be invoked in a nested way:

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

This statement uses the Object.create () function to pass in two parameters, that is, the first parameter is the prototype object of the created object, the second parameter is the property that is defined directly by the creation object, and the attribute is attached with the attribute defined.

10. Serialization of objects

In front of the object's properties and attributes of object properties, things are still quite a lot, do not know whether you have seen dizzy. However, the following is a more relaxed topic!

Object Serialization (serialization) refers to the conversion of the state of an object to a string, or to the return of a string to an object. ECMAScript 5 provides built-in functions json.stringify () and Json.parse () to serialize and restore objects. These methods use JSON as the data Interchange format, and the full name of the JSON is the "JavaScript object Notation"--javascript object notation, whose syntax and JavaScript objects are very similar to the syntax of the array's direct volume:

The final jsonobj is a deep copy of obj (about what is a deep copy, what is a shallow copy, can refer to: http://www.zhihu.com/question/23031215, second answer).

The syntax of JSON is a subset of JavaScript, which does not represent all the values in JavaScript. Supports objects, arrays, strings, infinity digits, True, false, and null, and they can be serialized and restored. Attention:

The results of ①nan, infinity, and-infinity serialization are null;

②json.stringify () can only serialize its own properties that can be enumerated by an object;

The result of a ③ Date object serialization is an ISO-formatted date string (referencing the Date.tojson () function), but Json.parse () retains their string shape rather than reverting them to the original date object;

④ functions, REGEXP, Error objects, and undefined values cannot be serialized and restored;

Of course, json.stringify () and Json.parse () can accept the second optional parameter, customizing the serialization or restore operation by passing in the list of properties that need to be serialized or restored, which we'll talk about later.

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

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.