The singleton pattern

Concept: Ensure that a class has only one instance and provide a global node to access it.

Normally we can create any instance with the new constructor.

(1) Static method:

Es6 syntax: A class is the prototype of an instance, and all methods defined in a class are inherited by the instance. If you prefix a method with the static keyword, it means that the method is not inherited by the instance, but is called directly from the class. This is called a “static method”.

Class Storage {static getInstance(){if(! Storage.instance){ Storage.instance = new Storage() } return Storage.instance } getStorage(key){ return localStorage.getItem(key) } setStorage(key,value){ return localStorage.setItem(key,value) } } const storagfe1 = Storage.getInstance() const storagfe2 = Storage.getInstance() storagfe1.setStorage('name', Function StorageBase(){storagfe1.getStorage('name') == storagfe1 //true // StorageBase.prototype.setItem = function (key,value) { return location.setItem(key,value) } StorageBase.prototype.getItem = function (key) { return location.getItem(key) } } const Storage = (function(){ let instance = null; return function () { if(! instance){ instance = new StorageBase() } return instance } })() const storagfe1 = new Storage() const storagfe2 = new Storage() storagfe1.setitem ('name',' zhang SAN ') storagfe2.getitem ('name')Copy the code

(2) Closure version:

// Implement a basic StorageBase class, Put the getItem and setItem method in its function on the prototype chain StorageBase () {} StorageBase. The prototype. The getItem = function (key) {return localStorage.getItem(key) } StorageBase.prototype.setItem = function (key, value) { return localStorage.setItem(key, Const Storage = (function(){let instance = null return function(){// Check whether the free variable is null if(! Instance = new StorageBase()} return instance}})() Const storage1 = new Storage() const Storage2 = new Storage() storage1.setitem ('name', GetItem ('name') // Return true storage1 === Storage2Copy the code

The prototype pattern

The prototype pattern is not only a design pattern, but also a programming paradigm, which is the foundation of JavaScript object-oriented system implementation.

Concept: In prototype mode, when we want to create an object, we find an object as a prototype, and then clone the prototype to create an object that shares the same set of data/methods as the prototype. In JavaScript, the Object.create method is a natural implementation of the Prototype pattern — specifically, as long as we’re using Prototype to create objects and inherit prototypes, we’re using the Prototype pattern.

The JavaScript classes introduced in ECMAScript 2015 are essentially syntactic sugar for JavaScript’s existing prototype-based inheritance. Class syntax does not introduce a new object-oriented inheritance model to JavaScript. – the MDN

The core idea of the prototype programming paradigm is to use instances to describe objects and use instances as the basis for defining objects and inheritance. In JavaScript, the prototype programming paradigm is represented by inheritance based on prototype chains. Among them, the understanding of prototype and prototype chain is the key.

Prototype:

In JavaScript, each constructor has a prototype property that points to the constructor’s prototype object, which has a constructor property that points back to the constructor; Each instance has a __proto__ attribute, and when we use the constructor to create an instance, the instance’s __proto__ attribute points to the constructor’s prototype object.

// create a Dog constructor. Age) {this.name = name this.age = age} dog.prototype. eat = function() {console.log(' bones are yummy ') Const dog = new dog (' fortune ', 3)Copy the code

The prototype chain:

Dog.eat () // Outputs "[object object]" dog.tostring ()Copy the code

The eat and toString methods were successfully called even though they were not defined manually in the dog instance. This is because when I try to access the properties/methods of a JavaScript instance, it first searches for the instance itself; When it finds that the instance does not have a corresponding property/method defined, it searches for the instance’s prototype object instead. If it can’t find any of the prototype objects, it searches for the prototype object of the prototype object, and the trajectory of the search is called the prototype chain.

Deep copy and shallow copy?

Js variable types are divided into value type (basic type) and reference type value type: Number, Undifine, String, Boolend, Null Deep copy and shallow copy for reference type. Copy a value for reference type. Copy an address for reference type

Var a = 1; var b = a; a = 2 ; Console. log(a,b) //2,1 // var a = {c:1}var b = a; a.c = 2; The console. The log (a.c, biggest) / / 2, 2Copy the code

Shallow copy (actually traversing object properties)

function shallowClone(source){ if(typeof source ! = 'object' || source == null){ return source } let copy = {} if(Object.prototype.toString.call(source) == '[object Array]'){ copy = [] } for(let key in source){ copy[key] = source[key] } return copy }Copy the code

Deep copy (shallow copy plus recursion)

function deepCopy (obj) { if(typeof obj ! = 'object' || obj == null){ return obj } let copy = {}; if(Object.prototype.toString.call(obj) == '[object Array]'){ copy = [] } for(let key in obj){ if(obj.hasOwnProperty(key)){ copy[key] = deepCopy(obj[key]) } } return copy; } deepCopy([{id:1,name:' sadar '}]) var b = a; a = 2 ; Console. log(a,b) //2,1 // var a = {c:1} var b = a; a.c = 2; The console. The log (a.c, biggest) / / 2, 2Copy the code

Tool deep Copy (json.stringfy)

const liLei = { name: 'lilei', age: 28, habits: ['coding', 'hiking', 'running'] } const liLeiStr = JSON.stringify(liLei) const liLeiCopy = JSON.parse(liLeiStr) liLeiCopy.habits.splice(0, 1) console.log(' Lileicopy.habits ', lilei.habits) console.log(' Lileicopy.habits ', lilei.habits)Copy the code