JavaScript object learning

Keywords: Attribute JSON Javascript ECMAScript

object

Objects are dynamic -- attributes can be added or deleted, but objects are often used to simulate static objects and "structs" in static typed languages. Object attributes can be added and deleted.
Object characteristics
* Object prototype: Points to another object whose properties inherit from its prototype object.
* class of an object: A string representing the object type.
* extensible flag of an object: Indicates whether new attributes can be added to the object.

Attribute characteristics
* Writable (whether property values can be set)
* Enumerable (whether this property can be returned by a for in loop)
* Configurable (whether attributes can be deleted or modified)

Object creation

Object Direct Quantity
The easiest way to create objects is through direct quantities of objects.

var empty = {}; //Objects without any attributes
var point = {x:0, y:0}; // Two properties
var point2 = {x:point.x, y:point.y+1};
var student = {
name:"Allen", //Property names can be quoted without quotation marks
age:23,
school:{ //This property value is an object.
"primary school" :"Experimental Primary School",//Property names have spaces, and must be strings
"middle-school" :"Yucai Middle School" ,//Attribute names have connectors and must be strings
}
}
/*Finally, try to avoid using spaces, connectors, or keywords for attribute names, and use quotation marks if necessary.*/

Create objects through new

var mObj = new Object(); // Create an empty object, like {}
var arr = new Array(); // Create an empty array, just like []
var mDate = new Date(); // Create a Date object that represents the current time

Through Object.create()
Here, let's first figure out a noun - prototype, where each JS object (except null) is associated with another object. The "other" object is what we call a prototype, and each object inherits attributes from the prototype.
All objects created by direct quantities of objects have the same prototype object and can be referenced by JS code Object.prototype. The prototype of the object created by keyword new and constructor call is the value of the prototype attribute of the constructor. Therefore, just like creating objects with {}, creating objects through new Object() inherits from Object.prototype.

ECMAScript 5 defines a method called Object.create(), which creates a new object. The first parameter is the prototype of the object, and the second parameter is the optional parameter to describe the properties of the object further.
Object.create() is a static function, not a method provided for an object to call.

var obj = Object.create({x:1,y:2}); // obj inherits the attribute x,y
var obj2 = Object.create(obj); //The prototype of obj2 is obj, which inherits the attributes x,y.
// If you want to create an ordinary empty object, such as one created by {} or new Object(), you need to pass in Object.prototype.
var obj3 = Object.create(Object.prototype);//obj3 is the same as {} and new Object()

Now let's look at how we can write a function ourselves to create objects through prototypes. Let's look at examples.

function createObject(obj){
// First, judge the obj object to see if it is null and if it throws an exception
if(obj == null) throw TypeError();
// Whether Object.create is available or not, it returns
if(Object.create) return Object.create(obj);
// When unavailable, detect the type of object
var objType = typeof obj;
// If the object type is neither an Object nor a function, throw an exception
if(objType !=="object" && objType !=="function")
throw TypeError();
// Define an empty constructor and set the prototype of the function to obj
function mfunc(){};
mfunc.prototype = obj;
return new mfunc();
}

attribute

There are two ways for an object to access attributes. The attributes are obtained by (.) and ([]) operators. There is no explanation here.
Let's explain in detail how to get attribute values by ([]). This method of getting attribute values is very similar to an array, except that the index of an array is a number, and its index is a string. Such arrays are the associative arrays that we're going to illustrate. They also form hashes, maps, or dictionaries. Because JS is a weakly typed language, programs can create any number of attributes in any object. When accessing attributes of an object by ([]), the attribute name is a string, which is more conducive to modifying and creating attributes while the program is running.
Let's give an example to illustrate its flexibility. Suppose we go to the supermarket to buy something. We put the things we need to buy into the shopping cart. The function of this shopping cart is to show the name of the goods we put in, as well as the unit price and quantity of the goods. Do you have any ideas? Students who have learnt similar C language can think about how to achieve it. Let's briefly talk about my idea (using the way of thinking similar to C language, God does not spray, you can leave your idea). The shopping cart here is represented by a dictionary-like object. The Key of the dictionary is our commodity name, and the Value is an object. The attributes of the object include: commodity price, quantity. Now think about using JavaScript. The idea is similar to what I said above. Look at the code directly.

var shoppingCart = {};//Here is the shopping cart.
// Method of Adding Commodities
function addGoods(name,price,count){
shoppingCart[name] = {m_price:price,m_count:count};
}

(1) Inheritance (Query and Setup of Properties)

JS objects have their own attributes and inheritance attributes. I think it is easier to illustrate the relationship between these two attributes by giving examples.
Examples of attributes of query objects are as follows:
Assuming you want to query the attribute x of obj, if there is no x in obj, you will continue to query attribute x in obj's prototype object. If there is no x in the prototype object, but the prototype object also has a prototype (the prototype is not null), you will continue to query on the prototype object until you find x or find an object whose prototype is null.
Examples of assigning attributes to an object:
Assuming that the attribute X of the object obj is assigned, if the attribute x already exists in obj (which is not inherited), then the assignment only changes the value of the existing attribute X. If there is no attribute X in obj, then the assignment operation adds a new attribute x to obj. If obj inherited from attribute x before, the inherited attribute would be overwritten by the newly created property of the same name.
Summary: Object attribute assignment, will not modify the prototype attribute value, will only create attributes or assign values to their own attributes. However, it should be noted that the attribute assignment operation first checks the prototype chain to determine whether assignment is allowed. If the inherited attribute is read-only, the assignment operation is not allowed.
Look at an example:

var obj = {x:1,y:2};
var obj2 = Object.create(obj);
console.log(obj); // ==> {x:1,y:2}
console.log(obj2); // ==> {x:1,y:2}
//Look at point 1 - ------------------------------------------------------------------------------------------------------
// Now modify the x value of the obj2 attribute to see the changes in obj and obj2
obj2.x = 100;
console.log(obj); // ==> {x:1,y:2}
console.log(obj2); // ==> {x:100,y:2}
/*It can be seen that the attributes of the object do not modify the attributes of the prototype.*/
// -------------------------------------------------------
//Look at point 2--
// At this point, we will modify the obj attribute x to see the changes.
obj.x = 111;
console.log(obj); // ==> {x:111,y:2}
console.log(obj2); // ==> {x:100,y:2}
/*It can be seen that --- object attribute assignment can only create attributes or assign attributes to itself, because when the x attributes of obj2 are assigned between them, there is no x attributes in obj2's own attributes, so obj2 will create new attributes x and assign values, and override the values of inherited attributes x.*/
// -------------------------------------------------------
//Look at point 3--
// Now let's modify the obj attribute y to see the changes
obj.y = 222;
console.log(obj); // ==> {x:111,y:222}
console.log(obj2); // ==> {x:100,y:222}
/*Here we can show the query process of the object attributes mentioned above, because the Y attribute of obj is modified to 222. When we query the Y attribute of obj2, there is no y value in the own attribute of obj2, so obj2 will go to its prototype (obj), the Y attribute in the prototype has been modified to 222, so the result of the query of the obj2 attribute y is 222.*/
// -------------------------------------------------------
//Look at point 4.
// Let's look at accessing a non-existent property.
console.log(obj2.m_string); // ==> undefined
console.log(obj2.m_string.length); // ==> Errors will be reported here.
/*When the accessed attribute does not exist, the system returns an undefined value, while null and undefined values have no attributes, so the second line of code above will report an error.*/
// We can avoid mistakes by judging.
var strLength;
if(obj2 && obj2.m_string) strLength = obj2.m_string.length;
//There's a more concise approach.
strLength = obj2 && obj2.m_string && obj2.m_string.length;

After the example above, do you understand inheritance?

(2) Deletion, detection and enumeration of attributes

Delete attribute
Let's first look at the delete operator, which deletes the properties of an object. However, delete only disconnects the relationship between attributes and host objects, and does not manipulate attributes in attributes. The delete expression returns true when deleted successfully.
It should be noted that the delete operator can only delete its own attributes, inheritance attributes and non-configurable attributes.

// The operation of deleting attributes
var mframe = {point:{x:11,y:22},size:{width:100,heght:50}};
// Here, the point attribute of mfram e is referenced with the p object
var p = mframe.point;
// When we do the deletion, print p to see the result.
delete mframe.point;
console.log(p); // ==> {x:11,y:22};
/*After executing the code, we know that mframe has no point attribute, but because the references to deleted attributes still exist, memory leaks may occur in some implementations of JS because of this imprecise code, so when destroying objects, we need to traverse the attributes in attributes and delete them in turn.*/

Detection attribute
Detection attributes are mainly to determine whether an attribute exists in an object. We use code to introduce detection attributes.


// The in operator detects attributes, with the attribute name (string) on the left and the object on the right.
var mpoint = {x:1,y:2};
console.log("x" in mpoint); //==> true
console.log("z" in mpoint); //==> false
console.log("toString" in mpoint); //==> True, toString is an inheritance attribute;
// -------------------------------------------------------
// The hasOwnProperty() method is used to detect whether a given name is an object's own property, and it returns false for inherited properties.
console.log(mpoint.hasOwnProperty("x")); //==> true
console.log(mpoint.hasOwnProperty("z")); //==> false
console.log(mpoint.hasOwnProperty("toString")); //==> false
// -------------------------------------------------------
// ProperrtyIsEnumerable () is an enhanced version of hasOwnProperty(), which returns true only if it detects that it is an attribute that is enumerable.

Enumeration attribute
Often we traverse the attributes of an object, usually using a for / in loop. The for/in loop traverses all enumerable attributes (including proprietary and inherited attributes) in an object.
There are many utility libraries that add new methods or attributes to Object.prototype, which can be inherited and used by all objects, but before the ECMAScript 5 standard, these newly added methods cannot be defined as non-enumerable, so these attributes will be enumerated when enumerating using the for/in loop. To avoid this situation, we need to filter in for/in. There are two common methods:

for(p in obj){
if(!obj.hasOwnProperty(p)) continue; // Skip inheritance attributes
}
//---------------------------------
for(p in obj){
if(typeof obj[p] === "function") continue; // Skip method
}

In addition to the for/in loop, ECMAScript 5 defines two functions to enumerate attribute names.
* Object.keys(), which returns an array consisting of the names of the enumerable properties of the object.
* Object.getOwnPropertyNames(), which returns the names of all the objects'own properties (including enumerable and non-enumerable properties in their own properties).

getter and setter of attributes

JavaScript attribute values can be replaced by getter and setter methods, and the attributes defined by getter and setter are called accessor attributes. Accessor properties are inheritable.
Examples are given to illustrate:

var p = {
//x and y are common readable and writable data attributes
x: 1.0,
y: 1.0,
// r is a readable and writable accessor property with getter and setter
// Don't forget to put a comma after the function body ends
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;
},
// theta is a read-only accessor property, it has only getter methods
get theta(){return Math.atan2(this.y,this.x)},
};
console.log(p); // ==> (1,1) r = 1.41421356 theta = 0.785398
p.r = 2;
console.log(p); // ==> (1.41421356,1.41421356) r = 2 theta = 0.785398

Attribute characteristics

Data attribute characteristics are divided into: value, writable, enumerability, configurability.
Accessor properties are divided into: get, set, enumerability, configurability.
The properties we create are writable, enumerable and configurable by default.
We present an example of an approach (Object.definePeoperty()):

// We can call Object.definePeoperty() to set the properties of object properties.
// We can call Object.definePeoperty() to set the properties of object properties.
/*
*Parametric 1: Input Object
*Parametric 2: The name of the property to be created or modified (String)
*Parameter 3: Properties of attributes (default values for all four newly created attributes are false or undefined, and default values for existing attributes are unchanged)
*(Note: This method can only modify or create own attributes, but can not modify inherited attributes.
*/
//Look at 1
// A brief introduction to the use of the method
var obj = {};
Object.defineProperty(obj,"x",{value:2017,
writable:true,
enumerable:true,
configurable:true});
document.write(obj.x+"<br/>"); // ==> 2017
// This method also has a return value, which returns the modified object.
var obj1 = Object.defineProperty({},"x",{value:2017,
writable:true,
enumerable:true,
configurable:true});
document.write(obj1.x+"<br/>"); // ==> 2017
//-----------------------------------------------------------
//Look at 2
// For newly created own attributes, the default values for all four attributes are false or undefined
var obj2 = Object.defineProperty({},"x",{});
document.write(obj2.x+"<br/>"); // ==> undefined
obj2.x = 2017;
document.write(obj2.x+"<br/>"); // ==> undefined
//-----------------------------------------------------------
//Look at 3
// For existing attributes, the default feature value is unchanged
var obj3 = {x:2017}; // The x attribute is writable, enumerable, and configurable
Object.defineProperty(obj3,"x",{}); // No modifications have been made to the property description
obj3.x = 2000;
document.write(obj3.x+"<br/>"); // ==> 2000 shows that the x attribute is still writable
//-----------------------------------------------------------
//Look at 4
// This method can only modify its own properties or create its own properties, but can not modify inheritance properties.
var obj4 = Object.create(obj3);
var obj4_x = obj4.x; // Reference to obj4.x attributes with an object
document.write(obj4.hasOwnProperty("x")+ "<br/>"); //==> false x is not a proprietary property
Object.defineProperty(obj4,"x",{}); // Create x attributes and override inherited attributes
document.write(obj4.hasOwnProperty("x")+ "<br/>"); //==> ture
// As you can see from the above, through this approach, obj4 creates the X attribute and overrides the inherited x attribute.
document.write(obj4.x+"---"+obj4_x+ "<br/>");//undefined---2000
obj4.x = 123123; // Attempts to modify x's own attributes found to be invalid because writable is false
document.write(obj4.x+"---"+obj4_x+ "<br/>");//undefined---2000
// As you can see from the above, the newly created property x and the property description are default values, so value is undefined.
//-----------------------------------------------------------
//Look at 5
// Look at the data type properties, which can be modified to accessor properties
var obj5 = {x:888};
Object.defineProperty(obj5,"x",{get:function(){return 2017}});
document.write(obj5.x + "<br/>"); // ==> 2017
obj5.x = 123; // Since there is no set method for the memory property, it is read-only and cannot be modified.
document.write(obj5.x + "<br/>"); // ==> 2017
//-----------------------------------------------------------
//Look at 6
/*
*Object.defineProperties() Multiple attribute descriptions of an object can be modified
*Parametric 1: Object
*Parametric 2: A list of mappings (also objects, dictionaries), including attribute names, attribute descriptions
*/
var obj6 = Object.defineProperties({},{x:{value:100,writable:true,enumerable:true,configurable:true},
"y":{value:200}});
document.write(obj6.x +"---"+ obj6.y + "<br/>"); // ==> 2017

Let's see if we copy attributes to Object, and the attributes of these attributes are copied together.

// Characteristics of replication attributes
/*
*Add an enumerable extend() method to Object. prototype.
*This method inherits from the object calling it and copies the attributes of the object passed in as a parameter one by one.
*In addition to values, all attributes of attributes should be copied unless there are attributes with the same name in the target object.
*All owner objects of parameter objects (including non-enumerable attributes) should also be meaningfully duplicated.
*/
Object.defineProperty(Object.prototype,
"extend",
{
writable:true,
enumerable:false, // Countless
configurable:true,
value:function(obj){ // Value is a function
//Get all the own properties, including non-enumerable
var names = Object.getOwnPropertyNames(obj);
// ergodic
for(var i = 0; i < names.length; i++){
// If an attribute already exists, skip
if(names[i] in this) continue;
// Get the descriptor of the attribute in obj
var desc = Object.getOwnPropertyDescriptor(obj,names[i]);
// Use it to create an attribute for this
Object.defineProperty(this,names[i],desc);
}
}
});

Three attributes of an object

The three attributes of an object are prototype, class and extensible.
* Prototype attributes
Prototype attributes are set at the beginning of instance object creation. As we mentioned earlier, the prototype is Object.prototype through object creation directly. The prototype is the prototype of the constructor for the object created by new. The prototype is the first parameter for the object created through Object.create(). You can query its prototype through Object.getPrototypeOf(). The isPrototype Of () method can also be used to detect whether an object is a prototype of another object (or in a prototype chain), such as p. isPrototype Of (o) to detect whether p is a prototype of O.
* class attribute
The class attribute of an object is a string used to represent the type information of the object.
Because JS does not provide a way to set this property, we can only query it indirectly. The default toString() method (inherited from Object.prototype) returns a string in [object class] format, so we need to extract the string between the eighth position of the returned string and the penultimate position. (A tricky problem is that many objects override the toString() method, and in order to be able to call the correct version of toString(), the Function.call() method must be called concisely. Look at the example:

//This function is used to get the class attribute of the object
function classof(obj){
if(obj === null) return "Null";
if(obj ===undefined) return "Undefined";
return Object.prototype.toString.call(obj).slice(8,-1);
}
// Simple output function
function printClassName(obj){
document.write(classof(obj)+"<br/>");
}
printClassName(null); //==>Null
printClassName(1); //==>Number
printClassName(""); //==>String
printClassName(false); //==>Boolean
printClassName({}); //==>Object
printClassName([]); //==>Array
printClassName(/./); //==>RegExp
printClassName(new Date());//==>Date
printClassName(window); //==>Window
function f(){} // Define a custom constructor
printClassName(new f()); //==>Object

  • Extensibility
    Object extensibility is used to indicate whether new attributes can be added to an object. All built-in and custom objects are realistic extensible. We can use Object.esExtensible()) to determine whether the object is extensible. If we want to make an object non-extensible, we need to call Object.preventExtensions(). It is important to note that once an object becomes non-extensible, it can no longer be converted back to extensible, and this method only affects the extensibility of the object itself.
    Object.seal() method sets the object to be non-extensible and all its own attributes to be non-configurable, but does not change the writable attributes of the object attributes, that is, to enclose the object.
    Object.isSeal() method is used to detect whether the object is closed.
    Object.freeze()` is a strictly locked object that not only sets the object as non-extensible and its properties as non-configurable, but also sets all its own data properties as read-only (reader properties are not affected).

serialized objects

Object serialization refers to the transformation of the state of an object into a string or the restoration of a string to an object.
Json.stringify() is used to serialize JS objects.
Json.parse() is used to restore JS objects.
Note: The JSON syntax is a subset of JavaScript syntax, and it does not represent all the values in JavaScript. Supports objects, arrays, strings, infinite numbers, true, false, null, and they can be serialized and restored. The result of NaN, Infinity, and - Infinity serialization is null. Functions, RegExp, Error objects, and undefined values cannot be serialized and restored. Serialization can only serialize the enumerable attributes of an object. For attributes that cannot be serialized, attributes are omitted. These two methods accept the second parameter and the third parameter, so you can see the document.

var mObj = {
x:1,
y:{z:[false,null,"string"]},
func:function(){document.write("This is a function. func")}
};
var sObj = JSON.stringify(mObj);
document.write(sObj +"<br/>"); // ==> The method in the {x": 1,"y": {z": [false, null, string]} object is omitted.
var oObj = JSON.parse(sObj); // ==> {x:1,y:{z:[false,null,"string"]}}

Object method

All JS objects inherit attributes from Object.prototype, and these inherited attributes are mainly methods, because we are more interested in methods. These methods can also be rewritten.
Many object methods have been mentioned before. There is no specific explanation here.

Posted by gergy008 on Thu, 28 Mar 2019 01:18:31 -0700