preface

This paper mainly answers the following questions:

  • 1. What are objects?
  • 2, how to use objects (create and access, add, delete, modify attributes)?
  • 3. Prototype chain and inheritance?

What is an object?

What exactly is the object? What is object-oriented programming?

  • Object, a term in object Oriented, not only represents a specific thing in the Namespace of the objective world, but also represents the basic elements in the solution space of the software system.
  • In a software system, objects have unique identifiers, including Properties and Methods. Properties are the information to be remembered, while Methods are the services that objects can provide. In Object Oriented software, an Object is an Instance of a Class. — Wikipedia

1. Characteristics of JavaScript objects

In JavaScript, the state and behavior of an object are abstracted as properties. To improve abstraction, JavaScript properties are designed to be more complex than other languages, providing data properties and getter/setter properties.

2. Two classes of properties for JavaScript objects

Properties are not simply names and values for JavaScript. JavaScript uses a set of attributes to describe properties.

Data attributes

Data attributes have four characteristics:

attribute describe
value The value of the attribute
writable Determines whether the attribute can be assigned
enumerable Determines whether for in can enumerate this property
configurable Determines whether the attribute can be removed or the eigenvalue changed

The code that normally defines a property creates a data property, which defaults to Writable, Enumerable, and different. We can look at this using the built-in getOwnPropertyDescripter function.

var o = { a: 1 };
o.b = 2;

// both a and b are data attributes
Object.getOwnPropertyDescriptor(o,"a");
// {value: 1, writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyDescriptor(o,"b");
// {value: 2, writable: true, enumerable: true, configurable: true}

Copy the code

Accessor (getter/setter) properties Four characteristics of accessor properties:

attribute describe
getter Function or undefined, called when the value of an attribute is fetched
setter Function or undefined, called when setting property values
enumerable Determines whether for in can enumerate this property
configurable Determines whether the attribute can be removed or the eigenvalue changed

Accessor properties allow properties to execute code while they are being read and written. Accessor properties allow users to get completely different values when they write and read properties. Accessor properties can be considered syntactic sugar for functions.

Object system

Object classification in JavaScript

Host objects: Objects provided by the JavaScript host environment whose behavior is entirely determined by the host environment. Built-in objects: Objects provided by the JavaScript language.

  • Native object: Object instances that are automatically created as JavaScript runtime is created, as specified by the standard.
  • Native objects: objects that can be created by the user using built-in constructors such as Array, RegExp, or special syntax.
  • Plain Object: An Object created by the {} syntax, the Object constructor, or the class keyword definition class that can be inherited by the stereotype.
  1. The host object

In the browser environment, we know that the global object is a window, and that window has many properties, such as Document. The properties on the global object Window come partly from the JavaScript language and partly from the browser environment. Global object properties are specified in the JavaScript standard, and other properties of Window objects are specified in various W3C standards.

The JavaScript language specifies the properties of global objects.

  1. Built-in objects · Inherent objects

Three values: Infinity, NaN, undefined. Nine functions: eval, isFinite, isNaN, parseFloat, parseInt, decodeURI, decodeURIComponent, encodeURI, encodeURIComponent Array, Date, RegExp, Promise, Proxy, Map, WeakMap, Set, WeakSet, Function, Boolean, String, Number, Symbol, Object, Error, EvalError, Ran GeError, ReferenceError, SyntaxError, TypeError, URIError, ArrayBuffer, SharedArrayBuffer, DataView, Typed Array, Float32Array, Float64Array, Int8Array, Int16Array, Int32Array, UInt8Array, UInt16Array, UInt8ClampedArray Four objects used as namespaces: Atomics, JSON, Math, Reflect

  1. Built-in objects · Native objects

In JavaScript, objects that can be created through the language’s own constructor are called native objects.

With these constructors, we can create new objects with the new operation. Almost all of these constructor capabilities cannot be implemented in pure JavaScript code, nor can they be inherited using the class/extend syntax. These native objects are “privileged objects” designed for specific capabilities or capabilities.

Special behavior object Array: The length property of an Array changes automatically based on the largest subscript. Object.prototype: As the default prototype for all normal objects, it can no longer be prototyped. String: In order to support subscripting, the positive integer attribute of String is searched in the String. Arguments: Arguments’ non-negative integer subscript property is associated with the corresponding variable. Module namespace object: there are many special places, completely different from normal objects, try to use only import. Type arrays and array buffers: Associated with memory blocks, subscript operations are special. Bind function: associated with the original function.

How are objects used?

[A] Declare the object

There are two ways to create objects:

  • Object literals (a shortcut to creating objects that simplify the creation of objects with a large number of attributes, syntax sugar).
  • Use the new operator followed by a constructor of type Object
// Object literal method -- create
var obj = {
    name:'foo'.method:function{console.log(this.name); }}// Constructor method -- create
var  obj = new Object(a);//< == > obj = {}
obj.name = 'foo';
obj.method = function(){};
Copy the code

Several classic models; Factory pattern, constructor pattern, prototype pattern, hybrid constructor/prototype pattern, dynamic prototype pattern, parasitic constructor pattern, etc.

Factory pattern –> Encapsulates the details of creating objects with specific interfaces in functions

function person(name,age){ var obj = new Object(); // Use the Object constructor to create instance objects. obj.name = name; obj.age = age; obj.say = function(){ console.log(this.name); }; return obj; } var person1 = person('zhangsan','18'); var person2 = person('lisi','3'); console.log(instanceOf person1)//object console.log(instanceof person2)//objectCopy the code
  • Solved the problem of creating multiple similar objects,
  • Used to create multiple objects containing the same properties, and methods, to avoid repeated code writing;
  • Does not solve the object identification problem (How do you know the type of an object, all objects created using this pattern are instances of Object.)

Constructor pattern

A constructor is a normal function. It is created in the same way as a normal function, except that constructors usually start with a capital letter. Another difference is the way the call is made. Normal functions are called directly, while constructors need to be called using the new keyword.

var Car = function (model, year, miles) {this.model = model;this.year = year;this.miles = miles;this.run =function(){console.log(this. Miles); }};var baoma = new Car("Tom".2009.20000);
var benchi = new Car("Dudu".2010.5000);
Copy the code
  • Solve the problem of object recognition (how to know the type of an object)
  • Disadvantages: Each method is recreated on each instance (as in the example above, baoma.sayname! . = = benci sayName)
  • Solution: propose the constructor, in the global write a function declaration; (The disadvantage of this solution is that global functions are only called locally, and too many methods require the creation of multiple global functions, so there is no encapsulation);

The prototype pattern

function Person() {} Person.name ='tom'; Person.prototype.friends =['jerry','miqi','carry']; Person.prototype.logName = function() { console.log(this.name); } } var person1 = new Person(); person1.logName(); //' Tom '//-- for in access for(key in person1) {console.log(key); }Copy the code

Use a combination of constructor and stereotype patterns

function Person(name,age) { this.name = name; this.age = age; this.friends = ['ajiao','pangzi']; } Person.prototype = constructor: Person, logName: function() { console.log(this.name); } } var person1 = new Person('evansdiy','22'); var person2 = new Person('amy','21'); person1.logName(); //'evansdiy' person1.friends.push('haixao'); console.log(person2.friends.length); / / 3Copy the code

[b] Delete object attributes

// Delete obj.key = undefined // delete obj.keyCopy the code

[c] View object properties (read properties)

1. View all properties

// 1.1 View all properties
let obj = {name: 'Mia'.age: 18}

Object.keys(obj)     // Check your property name
Object.values(obj)   // View the value of its own property
ObjectEntries (obj) or obj// View objects

1.2 Viewing its own attributes and Common Attributes
console.dir(obj)

// 1.3 Viewing Common Attributes (not recommended)
obj.__proto__    / / do not recommend

// 1.4 Determine whether an attribute 'XXX' is own or common
obj.hasOwnProperty('xxx')     // true is self, false is common or nonexistent
// 'XXX' in obj can not determine whether this property is its own property or a common property, can verify whether the object is in the object
// obj.hasownProperty (' XXX ') can determine if this property is its own property
Copy the code

2. View an attribute

Obj [' key '] or obj. KeyCopy the code

[4] Modify/add the [own] attribute of the object (write attribute)

1. Direct assignment

obj.name = 'foo'Or obj ['name'] = 'foo'

Copy the code

2. Assign values in batches

let obj = {name: 'mou'}
Object.assign(obj, {name: 'Mia', age: 18, gender: 'female'})
Copy the code

3. Modify the prototype

Let obj = object.create (commonCopy the code

[v] Object traversal

for in
Object.keys
Copy the code

[6] Object detection and recognition

1, the typeof

Typeof returns a string representing the data type, including number, Boolean, string, symbol, object, undefined, function, etc., but null, array, etc

typeof Symbol(); // symbol valid typeof ''; // string Valid typeof 1; // number valid typeof true; // Boolean valid typeof undefined; //undefined valid typeof new Function(); // function Valid typeof null; //object Invalid typeof []; //object Invalid typeof new Date(); //object Invalid typeof new RegExp(); / / object is invalidCopy the code

2, instanceOf

Instanceof is an instanceof B used to determine whether A is an instanceof b. the expression A instanceof B returns true if A is an instanceof B, false otherwise. The instanceof operator tests whether an object has a constructor’s Prototype property in its prototype chain.

disadvantages

  • For primitive data types, there is a difference between the result created in literal form and that created in instance form
console.log(1 instanceof Number)//false
console.log(new Number(1) instanceof Number)//true
Copy the code
  • We use it to detect true whenever we are on the prototype chain of the current instance. In class prototype inheritance, the result that we finally detect may not be accurate.
  • Cannot detect NULL and undefined

3, the constructor

4. Object. The prototype. ToString. Call () Object. The prototype. ToString. Call () is the most accurate way of the most commonly used. First get the toString method on the Object prototype and let the method execute, with this in the toString method pointing to the value of the first parameter.

Object.prototype.toString.call('') ; // [object String] Object.prototype.toString.call(1) ; // [object Number] Object.prototype.toString.call(true) ; // [object Boolean] Object.prototype.toString.call(undefined) ; // [object Undefined] Object.prototype.toString.call(null) ; // [object Null] Object.prototype.toString.call(new Function()) ; // [object Function] Object.prototype.toString.call(new Date()) ; // [object Date] Object.prototype.toString.call([]) ; // [object Array] Object.prototype.toString.call(new RegExp()) ; // [object RegExp] Object.prototype.toString.call(new Error()) ; // [object Error] Object.prototype.toString.call(document) ; // [object HTMLDocument] Object.prototype.toString.call(window) ; //[object global] window is a reference to globalCopy the code

Object inheritance

1. Prototype chain (rarely used alone)

The function the Parent (name) {enclosing name = name | | 'Parent'; } Parent.prototype.say = function(){ alert(this.name); } function Sub(age){ this.age = age||'21'; }; Sub.prototype = new Parent(); Var oSub = new SubClass('10'); var oSub = new SubClass('10'); var oSub = new SubClass('10'); oSub.say();Copy the code

There are three main problems with using prototype chain inheritance:

  • Literal rewriting of the prototype breaks the relationship (need to be corrected using constructor)
  • Derived class stereotypes refer to base class instances, which are not initialized when the derived class is created (new), so derived classes cannot pass arguments to the base class.
  • Overwriting the stereotype of a derived class may result in base class attributes overwriting derived class attributes, all instances sharing parent class instance attributes, and all references being modified.

2. Class inheritance (constructor borrowing, object impersonation)

The function the Parent (name) {enclosing name = name | | 'Parent'; } Sub.prototype.say = function(){ alert(this.name); } function Sub(params){ Parent.call(this,params); this.sex ='male'; }; var oSub = new Sub(); oSub.say(); // Throw an exception, oSub does not have this methodCopy the code
  • Only constructor properties can be inherited, not stereotype properties
  • Each new instance has a copy of the superclass constructor
  • Each instance is a re-instantiated constructor, and there are no shared attributes
  • Parent.call(this,params) can be passed as an argument to the Parent constructor

3. Composite inheritance :(common inheritance pattern)

function Parent(name){ this.name = name; This. Arr = [' brother ',' sister ',' parent ']; } Parent.prototype.say = function () { return this.name; }; function Sub(name,age){ Parent.call(this,name); // Call this.age = age; } Sub.prototype = new Parent(); Var oSub = new Sub(' subclass ','21'); console.log(oSub);Copy the code

There are problems: supertypes are called twice during use; Once when the subtype is created and once inside the subtype constructor

4. Original type inheritance:

function inherits(obj){ var F = function(){}; F.prototype = obj; return new F(); } var Parent = {name:' Parent ', say:function(){alert(this.name); } } var oSub = inherits(Parent); // There is no need to create a separate subclass constructor to instantiate subclasses. oSub.say();Copy the code

Base class stereotypes point to existing instance objects: create objects based on existing instance objects without creating custom types.

5. Parasitic inheritance:

function inherits(obj){ var F = function(){}; F.prototype = obj; return new F(); } function create(o){ var obj= inherits(o); Obj. run = function () {alert('run '); // Again, references are shared}; return obj; } var Parent = {name:' Parent ', say:function(){alert(this.name); } } var oSub = create(Parent); console.log(oSub); oSub.say(); oSub.run();Copy the code

Encapsulate the creation process and hide implementation details.

6. Parasitic combination :(ideal inheritance implementation)

function inherits(obj){ var F = function(){}; F.prototype = obj; return new F(); } function create(parent,sub){ var obj= inherits(parent.prototype); // Subclass object obj.constructor = sub; } function Parent(name){ this.name = name; This. Arr = [' brother ',' sister ',' parent ']; } Parent.prototype.say = function () { return this.name; }; function Sub(name,age){ Parent.call(this,name); this.age = age; } create(Parent,Sub); Var oSub = new Sub(' subclass ','21'); console.log(oSub);Copy the code