JavaScript ---> [study notes] & appreciated observer pattern & factory model objects & constructor mode

Explanation

  • This series (JS basis carding) to simulate the back of TCP implementations in preparation
  • Benpian main elements: the observer pattern, plant model, and the model constructor understanding of the objects

1. The observer pattern

1.1 Message registration method

"The subscriber registration message pushed into the message queue."

[Algorithm thinking]:

  1. When pushed into the message queue, if the message does not exist should create a type of the message and the message into the message queue
  2. If this message exists message should be pushed to perform a method to perform a method corresponding to the message queue (the plurality of modules to ensure a registration message can be smoothly performed)
regist: function(type, fn) {
  // 如果消息不存在则应该创建一个该消息类型
  if(typeof __message[type] === 'undefined') {
    // 将动作推入到该消息对应的动作执行队列中
    __message[type] = [fn];
  // 如果此消息存在
  } else {
    // 将动作方法推入该消息对应的动作执行序列中
    __message[type].push(fn);
  }
}

1.2 news release method

"For the news release method, and its function is executed when a message to all subscribers of the observers issued a message"

fire: function(type, args) {
  // 如果该消息没有被注册,则返回
  if(!__message[type])
    return;
  // 定义消息信息
  var events = {
    type: type,
    args: args || {}
  },
  i = 0,
  len = __message[type].length;
  // 遍历消息动作
  for(; i < len; i++) {
    // 依次执行注册的消息对应的动作序列
    __messages[type][i].call(this, events);
  }
}

1.3 Message logout methods

"Subscribers will be canceled to clear the message from the message queue."

remove: function(type, fn) {
  // 如果消息队列存在
  if(__messages[type] instanceof Array){
    // 从最后一个消息动作遍历
    var i = __message[type].length - 1;
    for(; i>= 0; i--) {
      // 如果存在该动作则在消息动作序列中移除相应动作
      __messages[type][i] === fn && __messages[type].splice(i, 1);
    }
  }
}

2. Object-oriented programming object

Object-oriented (Object-Oriented, OO) language has a sign that they have the concept of the class, and can create a plurality of objects with the same properties and methods by class. ECMAScript has no notion of class, so it's also different objects and object language class.

ECMA-262 put the object is defined as: "a set of unordered attributes, properties which may comprise the base value, the object or function." Strictly speaking, this is equivalent to say that the object is a set of values ​​no particular order. Each property and method of the object has a name, and each name is mapped to a value. Because of this, we can imagine ECMAScript object hash table: nothing more than a set of name-value pairs, where the value can be data or function

2.1 understand the object

  • The easiest way to create an object
  • Create an instance of an Object, and then add properties and methods to it
var person = new Object();
person.name = "Nicholas";
person.age = 29;
person.job = "Software Engineer";
person.sayName = function() {
  alert(this.name);
};

Early JavaScript developers to create objects using the above method. A few years later, the object literal as the preferred mode to create such objects:

var person = {
  name: "Nicholas",
  age: 29,
  job: "Software Engineer",

  sayName: function(){
    alert(this.name);
  }
};

2.1.1 Attribute Type

ECMA-262 5th Edition only defined by only the internal features (attribute), describe various characteristic properties (Property) of. ECMA-262 to define these characteristics in order to use the JavaScript engine, so in JavaScript, we can not access them directly. To show an internal characteristic value, it puts them in this specification two pairs of children square brackets, for example [[Enumerable]]

  1. Data attribute
    data attribute data comprising a position value. You can read and write values in this position. There are four data attributes describing its behavior characteristics

    • [[Configurable]]: delete Delete Attribute indicates whether through redefines properties, can modify the characteristics of the properties, or the ability to modify access attribute properties. Like the previous example above properties defined directly on the object, the default is true.
    • [[Enumberable]]: attribute indicating whether recycled back through the for-in, the default is true.
    • [[Writable]]: indicates whether to modify the attribute values, default is true.
    • [[Value]]: the data value of the property, the default is undefined

    For defined as before chestnut above directly on the object properties thereof [[Configurable]], [[Enumberable]] and [[the Writable]] properties are set to true, the [[the Value]] characteristic is set the specified value.

var person = {
  name: "Nicholas"
}

To modify the properties of the default properties, you must use ECMAScript5 of Object.defineProperty () method. This method accepts three arguments: the object attribute is located, and a name of an attribute descriptor object. Wherein the attribute descriptor (descriptor) of the object must be: configurable, enumerable, writable and value.

var person = {};
Object.defineProperty(person,"name", {
  writable: false,
  value: "Nicholas"
});
  1. Access properties
    accessor property does not contain data values; they contain a pair of children getter and setter functions. When read access properties, calls getter function, which is responsible for returning a valid value; when writing accessor property setter function calls and passing new values, this function is responsible for deciding how to handle the data.
  • [[Configurable]]: Indicates whether through Delete to delete the property in order to redefine the property.
  • [[Enumerable]]: Attribute indicating whether recycled back through the for-in.
  • [[Get]]: Function called when reading the property, the default value is undefined
  • [[Set]]: Function called when writing the property, the default value is undefined

Accessor properties can not be defined directly, you must use Object.defineProperty () is defined.

var book = {
  _year: 2004,
  edition: 1
};
Object.defineProperty(book, "year", {
  get: function() {
    return this._year;
  },
  set: function(newValue) {
    if(newValue > 2004){
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
});
book.year = 2005;
alert(book.edition);

2.1.2 define multiple attributes

ECAMAScript5 also defined a Object.defineProperties () method. Using this method can define multiple attributes descriptors

var book = {};
Object.defineProperties(book, {
  _year: {
    writable: true,
    value: 2004
  },
  edition: {
    writable: true,
    value: 1
  },
  year: {
    get: function() {
      return this._year;
    },
    set: function(newValue) {
      if(newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});

2.1.3 read attribute characteristics

Use Object.getOwnPropertyDescriptor ECMAScript5 () method can be achieved given property descriptor. This method takes two parameters: where object attributes and attribute names thereof descriptor to be read. The return value is an object, if it is an access attribute, the attribute of the object and configurable, enumerable, get and set; if data attributes, the attributes of the object and configurable, enumerable, writable and value.

var book = {};
Object.defineProperties(book, {
  _year: {
    value: 2004
  },
  edition: {
    value: 1
  },
  year: {
    get: function(){
      return this._year;
    },
    set: function(newValue){
      if (newValue > 2004) {
        this._year = newValue;
        this.edition += newValue - 2004;
      }
    }
  }
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value);    // 2004
alert(descriptor.configurable);   // false
alert(typeof descriptor.get);   // "undefined"

var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value);
alert(descriptor.enumerable);
alert(typeof descriptor.get);

2.2 Factory Pattern

  • Shortcoming object literal: Use a single interface to create many objects, it will generate a lot of duplicate code
  • Abstract the process of creating specific objects
  • Considering the ECMAScript can not create a class, developers invented the following function:
function createPerson(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.sayName = function(){
    alert(this.name);
  };
  return o;
}
var person1 = createPerson("Nicholas", 29, "Software Engineer");
var person2 = createPerson("Greg", 27, "Doctor");
  • Factory pattern disadvantage: the object recognition does not solve the problem, i.e. how to know the type of an object (as described above may be detected as a createPerson class).

2.3 Model constructor

  • Constructor in ECMAScript can be used to create a particular type of object.
function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  };
}
var person1 = new Person("Nicholas", 29, "Softwate Engineer");
var person2 = new Person("Greg", 27, "Doctor");

2.3.1 difference factory model constructor and

  • It does not appear to create objects
  • Directly assigned to the properties and methods of this object
  • No return statement

2.3.2 new constructor

  • Using the new operator calls the constructor will actually undergo the following four steps:
    (1) create a new object;
    (2) the scope of the constructor assigns a new object (this points to the new object);
    (3 ) constructor point code (added to the new object attribute);
    (4) returns a new object

[chestnut]:

  1. Person1 is not detected instances of Person
console.log(person1 instanceof Person);

Create a custom constructor means that in the future it can be identified as an instance of a particular type.

2.3.3 not use the new operator call the constructor

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
    alert(this.name);
  }
}
Person("Greg", 27, "Doctor");
alert(Window.name);     // "Greg"
  • These properties and methods should be mounted on a global object.

2.3.4 issue constructor

  • The main problem is that the constructor: "Every method must be re-created again in each instance."
// 前面的构造函数等价于
function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = new Function("alert(this.name)");
}
  • From the above point of view, each Person instance contains a different Function Examples
  • More specifically speaking, in order to create a constructor function, it will lead to a different scope chains and identifier resolution
  • The following code proof function is different.
console.log(person1.sayName === person2.sayName);   //false

3. Summary

3.1 Factory Pattern

  • The creation of abstract objects
  • The disadvantage is: the object is created using the factory pattern is not recognized as a certain class of

3.2 Constructor mode

  • Factory pattern recognition to solve the problem class.

  • Disadvantages are: between different instances of the same methods are different waste of resources.

  • Solution: prototype model

Published 177 original articles · won praise 22 · views 20000 +

Guess you like

Origin blog.csdn.net/piano9425/article/details/103926466
Recommended