Home  >  Article  >  Web Front-end  >  JS object-oriented basic explanation (factory mode, constructor mode, prototype mode, mixed mode, dynamic prototype mode)_javascript skills

JS object-oriented basic explanation (factory mode, constructor mode, prototype mode, mixed mode, dynamic prototype mode)_javascript skills

WBOY
WBOYOriginal
2016-05-16 16:39:341016browse

What is object-oriented? Object-oriented is a thought! (nonsense).

Object-oriented can regard the key modules in the program as objects, and the modules have properties and methods. In this way, if we encapsulate some properties and methods, it will be very convenient to use in the future, and we can also avoid tedious and repetitive work. Next, I will explain the object-oriented implementation in JS.

Factory mode

Factory pattern is a well-known design pattern in the field of software engineering. Since classes cannot be created in ECMAScript, function encapsulation is used to create objects with specific interfaces. The implementation method is very simple, that is, create an object within the function, assign properties and methods to the object, and then return the object.

function createBlog(name, url) {
  var o = new Object();
  o.name = name;
  o.url = url;
  o.sayUrl= function() {
    alert(this.url);
  }
  return o;
}

var blog1 = createBlog('wuyuchang', 'http://www.jb51.net/');

You can see that the implementation method of the factory pattern is very simple, which solves the problem of creating multiple similar objects. However, the factory pattern cannot identify the type of objects because they are all Objects, unlike Date, Array, etc., so there is Constructor pattern.

 Constructor Pattern

Constructors in ECMAScript can create objects of specific types, similar to native JS objects such as Array and Date. The implementation method is as follows:

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = function() {
    alert(this.url);
  }
}

var blog = new Blog('wuyuchang', 'http://www.jb51.net/');
console.log(blog instanceof Blog);  // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能

Except for the different function names between this example and the factory model, careful children should find many differences:

The first letter of the function name should be capitalized (Although the standard does not strictly require that the first letter be capitalized, by convention, the first letter of the constructor should be capitalized
No created object shown
Directly assign properties and methods to this object
No return statement
Use new to create objects
Able to recognize objects (this is where the constructor pattern is better than the factory pattern)

Although the constructor is easy to use, it is not without its shortcomings. The biggest problem with using the constructor is that the method must be re-created every time an instance is created (in theory, the properties of the object are different every time an object is created. The methods of the object are the same), but it is not necessary to create exactly the same method twice, so we can move the function outside the object (maybe some children have already seen the shortcomings, boo!).

function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = alertUrl;
}

function alertUrl() {
  alert(this.url);
}

var blog = new Blog('scjb51', 'http://sc.jb51.net/'),
  blog2 = new Blog('jb51', 'http://www.jb51.net/');
blog.alertUrl();  // http://sc.jb51.net/
blog2.alertUrl();  // http://www.jb51.net/

We set alertUrl as a global function, so that blog and blog2 access the same function. But the problem comes again. We define a function in the global scope that is actually only used by Blog. The display allows The global scope is somewhat worthy of its name. What is even more unacceptable is that many methods are defined in the global scope that are only used by specific objects. Not to mention wasting space, it obviously loses object-oriented encapsulation, so this can be solved through prototypes. question.

 Prototype mode

Every function we create has a prototype attribute, which is a pointer to an object, and the purpose of this object is to contain properties and methods that can be shared by all instances of a specific type. The advantage of using a prototype object is that all object instances can share the properties and methods it contains.

function Blog() {
}

Blog.prototype.name = 'wuyuchang';
Blog.prototype.url = 'http://tools.jb51.net/';
Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];
Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend );
}

// 以下为测试代码
var blog = new Blog(),
  blog2 = new Blog();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4
blog2.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4

blog.name = 'wyc1';
blog.url = 'http://***.com';
blog.friend.pop();
blog2.name = 'wyc2';
blog2.url = 'http://+++.com';
blog.alertInfo();  // wyc1http://***.comfr1,fr2,fr3
blog2.alertInfo();  // wyc2http://+++.comfr1,fr2,fr3

The prototype pattern is not without its shortcomings. First of all, it omits the constructor to pass initialization parameters. As a result, all instances obtain the same attribute values ​​​​by default. This is very inconvenient, but it is still not a prototype. The biggest problem, the biggest problem with the prototype pattern is caused by the nature of sharing. Because of sharing, if one instance modifies the reference, the other also changes the reference. Therefore, we usually do not use prototypes alone, but combine prototype pattern and constructor pattern.

 Mixed mode (prototype mode, constructor mode)

function Blog(name, url, friend) {
  this.name = name;
  this.url = url;
  this.friend = friend;
}

Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend);
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']),
  blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);

blog.friend.pop();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2
blog2.alertInfo();  // wychttp://**.coma,b

In mixed mode, constructor mode is used to define instance properties, while prototype mode is used to define methods and shared properties. Each instance will have its own instance attributes, but at the same time share methods, saving memory to the maximum extent. In addition, this mode also supports passing initial parameters. The advantages are many. This mode is the most widely used and recognized method of creating custom objects in ECMAScript.

 Dynamic Prototype Mode

The dynamic prototype mode encapsulates all information in the constructor, and by initializing the prototype in the constructor (only the prototype is initialized when the first object is instantiated), you can choose whether to initialize the prototype by judging whether the method is valid. .

function Blog(name, url) {
  this.name = name;
  this.url = url;

  if (typeof this.alertInfo != 'function') {
    // 这段代码只执行了一次
    alert('exe time');
    Blog.prototype.alertInfo = function() {
      alert(thia.name + this.url);
    }
  }
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net'),
  blog2 = new Blog('wyc', 'http:***.com');

You can see that in the above example, the window only pops up once, 'exe time', that is, when the blog is initialized. In this way, blog2 no longer needs to initialize the prototype. It is perfect for creating objects using this mode.

This blog post refers to the 3rd edition of "Advanced Programming with JavaScript ", but the language has been simplified and the examples have been rewritten. If there is anything you don't understand, please leave a reply and the author will update the blog.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn