Object orientation and class definition

Class: A class is a template of an object, and an object is an instance of a class. Objects usually need a template that represents common characteristics of a class of objects, from which objects are then generated

So what exactly is an object? We understand it on two levels. (1) An object is an abstraction of a single object. A book, a car, a person can be objects, as can a database, a web page, a remote server connection. When objects are abstracted into objects, the relationship between objects becomes the relationship between objects, so that the real situation can be simulated and the object can be programmed. (2) An object is a container that encapsulates properties and methods. Properties are the state of the object, and methods are the behavior of the object (to accomplish something). For example, we can abstract an animal as an animal object, using “attributes” to record which animal it is, and “methods” to represent certain behaviors of the animal (running, hunting, resting, etc.).

The object architecture of the JavaScript language is not based on “classes”, but on constructors and prototype chains.

The above concepts are from the Ruan Yifeng JavaScript tutorial – Object-oriented Programming

Development example: if a page has two round figure, I want to make the two round figure running alone, but the core code logic remains the same, and two instances each other, their core logic and operation performance are all the same, but need to separate to run their own logic, and have their own data and status, this time using the object-oriented development method. Plug-in encapsulation component encapsulation, are the application of object oriented thought, are the reasonable control of privatization and public ownership.

JS itself is an object-oriented programming language, and it itself is based on the idea of object-oriented language.

Object-oriented thinking:

  • Objects: Everything is an object
  • Classes: Categories and subdivisions of “objects”
  • Instance: A concrete member created from the template of a class

Built-in class

Class in JS: built-in class, custom class

Built-in types:

  • Each data type has its own built-in class:Number,String,Boolean,Symbol,BigInt,Object(Array,RegExp,Date,Set,Map,ArrayBuffer…). ,Function
  • The specific values we are exposed to are instances of the corresponding classes, for example:10isNumberClass, [10,20] ->Array -> Object.
  • Each HTML element tag “containswindow/documentAnd so on have their own built-in classes in JS, for example:div -> HTMLDivElement -> HTMLElement -> Element -> Node -> EventTarget -> Object

A DOM element object

Always remember to use object-oriented thinking when encapsulating and abstracting

Create your own class

Ordinary function execution

function Fn(x, y) {
    let total = x + y,
        flag = false;
    this.total = total;
    this.say = function say() {
        console.log(this.total);
    };
}
let result = Fn(10.20);
console.log(result);//undefined
Copy the code

Normal functions execute, and this in a function depends on the environment in which the function is run

Constructor execution

let result1 = new Fn(10.20);
let result2 = new Fn(30.40);
console.log(result1.say === result2.say); //->false
Copy the code

Using new means that the function is executed as a constructor, which is the custom class

  • FnReferred to asclassorThe constructor
  • resultOne called the current classThe instance

The constructor executed with the new keyword does the following than the normal constructor:

  1. In the initializationthisPreviously, one was created by defaultAn empty object(as the returned instance object) at initializationthisWhen willthiscreation-orientedInstance objects
  2. So during code execution, in the body of the functionthis.xxx = xxxAll assignment operations toInstance objects set private properties or methodsPrivate variables in context are not directly related to instance objectsthis.xxx = xxxIs assigned to.)
  3. If the function does not set a return value or returns a primitive value type, the default return is the created instance object, and the value returned by the user only if the object type is manually returned

Therefore, there is no direct relationship between the private properties or methods of the returned Result instance object and the private variables in the function context.

This makes new a closure because it returns an instance object, referenced by an external variable

So classes in JavaScript are actuallyfunctionType, essentiallyfunction(constructor), the instance object isObjecttype

instanceof

Instanceof: Checks whether an instance belongs to this class

console.log(result instanceof Fn); //->true
Copy the code

Distinguish between literals and values created by constructors

There are two ways to create a value:

  • Literal scheme
  • Constructor scheme
 let obj1 = {};
 let obj2 = new Object(a);Copy the code

There is no difference between the two schemes for objects, but for raw values:

 let n1 = 10; // An instance of the Number class "raw value"
 let n2 = new Number(10); // An instance of the Number class "object"
Copy the code

One is a primitive value type and one is an object type

console.log(n2.toFixed(2)); / / - > 10.00
console.log(n1.toFixed(2)); / / - > 10.00
Copy the code

Primitive value types have no properties and methods, so how do you do member access?

Js has its own internal processing mechanism: boxing and unboxing

Packing:

10->Object (10) Converts the original value type to “Object instance”, and then does the member access

Split open a case:

 console.log(n1 + 10); / / - > 20
 console.log(n2 + 10); / / - > 20
Copy the code

N2 object will, in turn, calls the Symbol. ToPrimitive/the valueOf (), n2 the valueOf () return to the original value of 10, this process is to “split open a case”

instanceofThe original value is not recognized

Note: Instanceof has limitations: it does not recognize the original value

 console.log(n2 instanceof Number); //->true
 console.log(n1 instanceof Number); //->false  
Copy the code

Note:

Each instance object is an independent memory address:

let result1 = new Fn(10.20);
let result2 = new Fn(30.40);
console.log(result1 === result2); //->false
console.log(result1.say === result2.say); //->false
Copy the code

hasOwnPropertyand[attr] in obj

  • ObjectFor each objecthasOwnPropertyMethod,obj.hasOwnProperty([attr])detectionattrWhether it isobjThe object’sprivateattribute
  • [attr] in obj: to testattrWhether it isobjA property ofWhether private or public
console.log(result1.hasOwnProperty('say')); //->true
console.log(result1.hasOwnProperty('hasOwnProperty')); //->false Result1 can call hasOwnProperty, indicating that hasOwnProperty is a member "property" of result1
console.log('say' in result1); //->true
console.log('hasOwnProperty' in result1); //->true 
Copy the code

Interview question: Write your own method hasPubProperty to check whether a property is a public property of an object

function hasPubProperty(obj, attr) {
    If hasOwnProperty is false, it must be public. If hasOwnProperty is false, it must be public
    return (attr inobj) && ! obj.hasOwnProperty(attr); }console.log(hasPubProperty(result1, 'hasOwnProperty')); //->true
console.log(hasPubProperty(result1, 'say')); //->false 
Copy the code

The downside of this method is that it can only be the case that “a property is not private but public”, but if the property is both private and public, the result is false based on this method, but the property is indeed its public property

for incycle

A for in loop can be used to iterate over objects

let arr = [10.20.30];

for (let i = 0; i < arr.length; i++) {
    console.log(arr[i], i);
}
for (let key in arr) {
    console.log(arr[key], key);// Note that the key is a string
}
Copy the code

For loop nature not iterate through group, is himself a digital control index of circular logic, such as I = 0 I < 3 i++, their control loop number three times, each round of cycle I value, just we want to get this item in the array index “I start from scratch, array index is also starting from scratch”, so based on member access to obtain again can. That is, for is a circular index, and the value is fetched by the index

For in essentially iterates over an object according to its own structure (key-value pairs)

So the for loop performs slightly better than the for-in loop

Built-in bug for in

  • Can’t iterationSymbolattribute
  • When iterating, it is not necessary to iterate in the order of the key-value pairs written by itself: “Iterate the numeric attributes {small -> large} first, and then iterate the non-numeric attributes {in the order written by itself}”
  • It will not only iterate over the private attributes of the object, but also iterate over some public attributes extended by itself to “iterate over enumerable {generally self-set are enumerable, built-in is not enumerable}”.
Object.prototype.sum = function sum() {};
let obj = {
    name: 'xxx'.age: 12.0: 100.1: 200.teacher: 'mtt'[Symbol('AA')]: 300
};
for (let key in obj) {
    console.log(key); //'0' '1' 'name' 'age' 'teacher' 'sum'
}
Copy the code

The order above is numeric attributes, non-numeric attributes, and public attributes

If we don’t want to iterate over public ones, we don’t let them do any processing even if the internal mechanism finds them:

for (let key in obj) {
    // The Symbol is not included in the Symbol, but is not included in the Symbol.
    if(! obj.hasOwnProperty(key))break;
    console.log(key);
} 
Copy the code

Object.getOwnPropertySymbols(obj)

Object. GetOwnPropertySymbols Object (obj) for all private Symbol attribute “array”

Object.keys(obj)Object.getOwnPropertyNames(obj)

Object. The keys and Object (obj). GetOwnPropertyNames Object (obj) access to all the Symbol’s private property “array”

Put two together and you get all of themPrivate property

Write a function that iterates through all private members, including members of the symbol property:

function each(obj, callback) {
    let keys = Object.keys(obj),
        key = null,
        value = null,
        i = 0,
        len = 0;
    if (typeof Symbol! = ="undefined") {
        / / support Symbol
        keys = keys.concat(Object.getOwnPropertySymbols(obj));
    }
    len = keys.length;
    if (typeofcallback ! = ="function") callback = function () {};
    for (; i < len; i++) {
        key = keys[i];
        value = obj[key];
        callback(value, key);
    }
}
each(obj, (value, key) = > {
    console.log(value, key);
});
Copy the code

Note that object attributes can only be of type String or Symbol

Obj [1] = obj[‘1’]

Each value of type Symbol is unique

Will automatically convert the property toStringtype

The necessary basics of prototypes and prototype chains

protptype

JavaScript states that each function has a Prototype property that points to an object. For normal functions, this property is basically useless. However, in the case of constructors, this property automatically becomes the prototype of the instance object when the instance is generated.

All properties and methods of the prototype object can be shared with the instance object. That is, if properties and methods are defined on the stereotype, then all instance objects can be shared, saving memory and showing the relationship between instance objects.

function Animal(name) {
  this.name = name;
}
Animal.prototype.color = 'white';
Animal.prototype.meow  =  function () {
    console.log('meow meow');
  };

var cat1 = new Animal('heavy');
var cat2 = new Animal('二毛');

cat1.color // 'white'
cat2.color // 'white'
cat1.meow === cat2.meow // true
Copy the code

Advantages: Share attributes or methods, saving memory

function Cat(name, color) {
  this.name = name;
  this.color = color;
  this.meow = function () {
    console.log('meow meow');
  };
}
Copy the code

If you create an instance like this, you create a meOW method that behaves the same way, wasting system resources

constructorattribute

The Prototype object has a constructor property, which by default points to the constructor of the Prototype object.

Object.prototype.__proto__

The __proto__ property of an instance object that returns the prototype object of that object, the prototype property of the constructor.

var obj = new Object(a); obj.__proto__ ===Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true
Copy the code

The __proto__ attribute is only required for deployment by browsers, other environments may not have this attribute.

Prototype chain

JavaScript dictates that all objects have their own prototype object.

  • On the one hand, any object can serve as a prototype for other objects
  • On the other hand, since a prototype object is also an object, it also has its own prototype.

Therefore, there is a ‘prototype chain’ : object to prototype, prototype to prototype object…

If you layer up, all Object prototypes can eventually be traced back to Object.prototype, the Prototype property of the Object constructor. That is, all objects inherit the properties of Object.prototype. This is why all objects have valueOf and toString methods, because these are inherited from Object.prototype.

The Object. Prototype prototype is null. Null has no properties, no methods, and no prototype of its own. Thus, the end of the prototype chain is NULL.

Object.getPrototypeOf(Object.prototype)//null 
Copy the code

The object.getProtoTypeof method returns the prototype of the parameter Object

When reading a property of an object, the JavaScript engine looks for the property of the object itself; if it can’t find it, it looks for its prototype; if it still can’t find it, it looks for the prototype. If no Object. Prototype is found up to the top level, undefined is returned.

If the object itself and its prototype both define a property of the same name, then the property of the object itself is read first.

Summary of basic knowledge of prototype and prototype chain

  • Each class (function) has a prototype and the value is an object. All properties and methods on the prototype object can be shared with the instance object

  • The prototype object has a property constructor that points to the class itself

  • Every object (normal object, prototype, instance, function, etc.) has __proto__, the value of which is the prototype object of the class to which the current instance belongs

These are the basics of prototype chains, and the following articles will explain the mechanics of prototype chains in detail