javascript basic knowledge sharing and the like with functionalization

  • 2020-12-19 20:55:40
  • OfStack


1. Objects are suitable for collecting and managing data and easily form a tree structure. 
Javascript including 1 A stereotype chain feature that allows an object to inherit from another 1 Properties of an object. Properly used, it can reduce object initialization time and memory consumption. 
2. The functions are javascript The basic module unit for code reuse, information hiding, and composite invocation. Functions are used to specify the behavior of an object. 1 Generally speaking, programming is going to 1 Group requirements are decomposed into 1 Ability to group functions and data structures. 
3. Modules We can construct modules using functions and closures. Module is 1 A function or object that provides an interface but hides the implementation state and implementation. 

1. Custom types -- Constructor Pattern (pseudo-class pattern)

In class-based systems, an object is defined such that a class is used to describe what it is. If a building is a class-based system, the architect draws a blueprint of the house, and the house is built according to that blueprint.

When implementing inheritance using a custom type pattern, we simply pass the arguments to the constructor and then mount them on the instance object. No other method about an instance object passes a parameter because it can be accessed by this inside the method invoked by the instance object. Variables mounted on instance this objects are called instance variables.

Composition -- Inheritance


function Person (name, age, job) {
  //  The instance variables 
  this.name = name;
  this.age = age;
  this.job = job;
}
Person.prototype.sayName = function () {
  alert(this.name);
}

var person1 = new Person('Nicholas', 29, 'Software Engineer');
var person2 = new Person('Greg', 27, 'Doctor');
function SuperType (name) {
  this.name = name;
  this.colors = ['red','blue', 'green'];
}

SuperType.prototype.sayName = function () {
  console.log(this.name);
}

function SubType (name, age) {
  //  Inherit the attributes 
  SuperType.call(this,name);
  this.age = age;
}

//  Inherited methods 
SubType.prototype = new SuperType();

SubType.prototype.sayAge = function () {
  console.log(this.age)
}

var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black')
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType('Greg', 27)
console.log(instance2.colors);
instance2.sayName();
instance2.sayAge();

In inherit to the attributes and methods, we 1 call the superclass constructor twice, when through new calls the superclass constructor to create the prototype of the subclass constructor, have a problem, the prototype of the subclass constructor object is the superclass constructor instance now, so there will be in the superclass constructor for instance objects this add attributes, just value for undefined, i.e. new calls the superclass constructor function to change the subclass transformation of the prototype, so on the prototype of the subclass constructor will have redundant attributes. This leads to waste. What we really need is a subclass constructor stereotype that can inherit the methods of the superclass constructor stereotype. So what we need is,

1. Create a subclass constructor prototype object.

2. This subclass constructor stereotype inherits from the superclass constructor stereotype.

3. Since we overwrote the prototype object of the subclass constructor in 1, i.e., recreated the prototype object, we need to add the constructor property to the newly created prototype object and assign it to the subclass constructor function.

Rewrite 1 of the above code as shown below.

About the constructor attribute: An attribute that is only available on the prototype of the constructor function and points to the constructor, the overridden prototype object defaults to no constructor attribute.

Parasitic combination - inheritance


function inheritPrototype (subType,superType) {
  var prototype = Object.creat(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
};

function SuperType (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
  console.log(this.name);
}
function SubType(name, age) {
  // Inherit the attributes 
  SuperType.call(this,name);
  this.age = age;
}
// Inherited methods 
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function () {
  console.log(this.age);
}

var instance = new SubType();

By hiding the details of the so-called prototype operation, it now looks less bizarre. But has anything really been found:
There is no private environment, and all properties are public. The method of the parent class cannot be accessed. Difficult to debug

Prototype 2.

In a pure prototype mode, we would get rid of classes and focus on objects instead. Prototype-based inheritance is conceptually simpler than class-based inheritance: a new object can inherit the properties of an old object. You start by building useful objects, and then you can build more objects like that object. This completely avoids the classification process of breaking an application into a series of nested abstract classes
In a prototype-based system, we create objects that look like all the objects of this type we want, and then we tell the javascript engine that we want more objects like this. If the building is based on prototype, the architect will build a house first, and then build all the houses like this.

As an alternative to the new operator, the method ES51en. creat() adds a more prototype-based feel when you create an javascript object using it.


function myMammal = {
  name : 'Herb the Mammal',
  get_name : function () {
    return this.name;
  },
  says : function () {
    return this.saying || '';
  }
}

var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
  var i, s = '';
  for (i = 0;i < n; i += 1) {
    if(s) {
      s += '-'
    }
    s += 'r';
  }
  return s;
}

myCat.get_name = function () {
  return this.says + ' ' + this.name + this.says;
}

This is a "differentiated inheritance". By customizing a new object, we show how it differs from the base object on which it is based.
Sometimes, it is useful for situations where some data structures inherit from other data structures.

3. Functional -- Factory mode

In pseudo-class mode, the constructor function Cat has to repeat what the constructor Mammal has already done. That is no longer needed in functional mode, because the constructor Cat will call the constructor Mammal and let Mammal do most of the work of object creation, so Cat will just focus on its own differences.
Functional patterns have a lot of flexibility. Not only does it provide less work than pseudo-class patterns, it also gives us better encapsulation and information hiding, as well as the ability to access superclass methods.

If we create an object with a functional style and none of its methods use this or that, then the object is persistent. A persistent object is a collection of simple functions.

Private variables: Any variables defined in a function can be considered private because they cannot be accessed outside the function.

closure

Closures are methods that prevent the garbage collector from removing a variable from memory, making it accessible outside of the execution environment in which it was created.
Remember: closures are created by functions. Each call to the function creates a unique execution environment object. After the function executes, the execution object is discarded unless the caller references it. Of course, if the function returns a number, you cannot reference the function's execution environment object. But if a function returns a more complex structure, such as a function, an object, or an array, saving the return value to a variable creates a reference to the execution environment.


Function.prototype.method = function (name,func) {
  this.prototype[name] = func;
  return this; 
}
//  The factory mammal function 
var mammal = function (spec) {
  var that = {};

  that.get_name = function () {
    return spec.name;
  }
  that.says = function (spec) {
    return spec.saying || '';
  } 

  return that;
}

//  The factory cat function ( Based on the mammal The function of )
var cat = function (spec) {
  spec.saying = spec.saying || 'meow';
  var that = mammal(spec);
  that.purr = function (n) {
    var i, s = '';
    for (i = 0; i < n; i += 1) {
      if(s) {
        s += '-';
      }
      s += 'r';
    }
  }
  that.get_name = function () {
    return that.says() + ' ' + spec.name + ' ' + that.says();
  }
  return that;
}

//  create myCat object 
var myCat = cat({name: 'Henrietta'});

Object.method('superior',function (name) {
  var that = this,
    method = that[name];
  return function () {
    return method.apply(that, arguments)
  }
})

//  The factory coolcat function ( Based on the cat function )
var coolcat = function (spec) {
  var that = cat(spec),
    super_get_name = that.superior('get_name');
  that.get_name = function (n) {
    return 'like ' + super_get_name() + ' baby';
  }
  return that;
}

var myCoolCat = coolcat({name : 'Bix'});

var name = myCoolCat.get_name();

The functional modular pattern has a lot of flexibility. Not only does it provide less work than the constructor pattern, it also gives us better encapsulation breaks and hiding, and the ability to access superclass methods. If all states of an object are private, then the object becomes an "tamper-ES87en" object. The properties of the object can be replaced or deleted while the integrity of the object is not compromised. If we create an object in a functional style and none of its methods use this or that, the object is a persistent object. A persistent object is a collection of simple functions.
1 persistent object cannot be invaded. When accessing a persistent object, an attacker will not access the internal state of the object unless there is method authorization.

The module pattern

The previous pattern is for custom types to create private variables and privileged methods. The modular pattern that Douglas refers to is the creation of private variables and privileged methods for singletons. A singleton is an object with only one instance. (Objects created using object literal representation)


var singleton = function () {
  //  Private variables and functions 
  var privateVariable = 10;

  function privateFunction () {
    return false;
  }
  // privilege / Public methods and properties 
  return {
    publicProvperty: true;

    publicMethod: function () {
      privateVariable++;
      return privateFunction();
    }
  }
}

Essentially, this object literal defines the public interface of the singleton. This pattern is useful when you need to do some initialization on a singleton while maintaining its private variables. In short, if you have to create an object and initialize it with some data, you also have to expose some method that has access to that private data.

Enhanced module mode

This enhanced module pattern is appropriate for cases where the singleton must be an instance of some type and must be enhanced by adding some properties and methods.


var singleton = function () {
  //  Private variables and functions 
  var privateVariable = 10;

  function privateFunction () {
    return false
  }
  //  Create an object 
  var object = new CustomType();

  //  Add privileges / Public properties and methods 
  object.publicProperty = true;
  object.publicMethod = function () {
    privateVariable++;
    return privateFunction();
  }

  return object;
}()


Related articles: