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:
10
isNumber
Class, [10,20] ->Array
->Object
. - Each HTML element tag “contains
window
/document
And 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
Fn
Referred to asclassorThe constructorresult
One called the current classThe instance
The constructor executed with the new keyword does the following than the normal constructor:
- In the initialization
this
Previously, one was created by defaultAn empty object(as the returned instance object) at initializationthis
When willthis
creation-orientedInstance objects - So during code execution, in the body of the function
this.xxx = xxx
All assignment operations toInstance objects set private properties or methodsPrivate variables in context are not directly related to instance objectsthis.xxx = xxx
Is assigned to.) - 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 actuallyfunction
Type, essentiallyfunction(constructor), the instance object isObject
type
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”
instanceof
The 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
hasOwnProperty
and[attr] in obj
Object
For each objecthasOwnProperty
Method,obj.hasOwnProperty([attr])
detectionattr
Whether it isobj
The object’sprivateattribute[attr] in obj
: to testattr
Whether it isobj
A 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 in
cycle
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 iteration
Symbol
attribute - 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 toString
type
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
constructor
attribute
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