What is object-oriented? Object-oriented is a kind of thought! (nonsense).
Object-oriented can treat all key modules in a program as objects, and modules have attributes and methods. In this way, if we encapsulate some properties and methods, it will be very convenient to use in the future and can also avoid tedious and repetitive work. Next, we will explain the object-oriented implementation in JS.
Factory model
Factory pattern is a well-known design pattern in the field of software engineering, and since classes cannot be created in ECMAScript, objects are created with function encapsulation. The implementation method is very simple, that is, create an object in the function, assign attributes 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', '//www.VeVB.COM/');It can be seen that the implementation method of the factory pattern is very simple, solving the problem of creating multiple similar objects, but the factory pattern cannot identify the type of the object because it is all Object, unlike Date, Array, etc., so the constructor pattern appears.
Constructor mode
The constructor 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', '//www.VeVB.COM/');console.log(blog instanceof Blog); // true, determine whether the blog is an instance of Blog, that is, it solves the problem that the factory mode cannot beThis example is different from the factory model except for the function name, careful children's shoes should find many differences:
The first letter of the function name is capitalized (although the standard does not strictly stipulate that the first letter is capitalized, according to convention, the first letter of the constructor is capitalized.
Create object not displayed
Assign attributes and methods directly to this object
No return statement
Create an object using new
Be able to recognize objects (this is where constructor patterns outweigh factory patterns)
Although constructors are easy to use, they are not without disadvantages. The biggest problem with using constructors is that they have to recreate the method every time they create an instance (theoretically, the properties of the object are different every time they create an object, and the methods of the object are the same). However, it is not necessary to create exactly the same method twice, so we can move the function outside the object (maybe some children's shoes have seen the disadvantages, shhhh!).
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.VeVB.COM/'), blog2 = new Blog('jb51', '//www.VeVB.COM/');blog.alertUrl(); // http://sc.VeVB.COM/blog2.alertUrl(); // //www.VeVB.COM/We set alertUrl to a global function, so that blog and blog2 access the same function, but the problem comes again. A function that actually only wants the Blog to use is defined in the global scope, which shows that 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 only is it wasted space, it obviously loses object-oriented encapsulation, so this problem can be solved through prototypes.
Prototype mode
Each 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 prototype objects is that all object instances can share the properties and methods it contains.
function Blog() {}Blog.prototype.name = 'wuyuchang';Blog.prototype.url = 'http://tools.VeVB.COM/';Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];Blog.prototype.alertInfo = function() { alert(this.name + this.url + this.friend );}// The following is the test code var blog = new Blog(), blog2 = new Blog();blog.alertInfo(); // wuyuchanghttp://tools.VeVB.COM/fr1,fr2,fr3,fr4blog2.alertInfo(); // wuyuchanghttp://tools.VeVB.COM/fr1,fr2,fr3,fr4blog.name = 'wyc1';blog.url = 'http://***.com';blog.friend.pop();blog2.name = 'wyc2';blog2.url = 'http://+++.com';blog.alertInfo(); // wyc1http://***.comfr1,fr2,fr3blog2.alertInfo(); // wyc2http://++.comfr1,fr2,fr3The prototype pattern is not without its shortcomings. First of all, it omits the link of the constructor passing initialization parameters. As a result, all instances obtain the same attribute value by default, which is very inconvenient, but this is not the biggest problem of the prototype. The biggest problem with the prototype pattern is caused by the nature of sharing. Due to sharing, one instance modifies the reference, and the other also changes the reference. Therefore, we usually do not use prototypes alone, but combine prototype patterns with constructor patterns.
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.VeVB.COM/', ['fr1', 'fr2', 'fr3']), blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);blog.friend.pop();blog.alertInfo(); // wuyuchanghttp://tools.VeVB.COM/fr1,fr2blog2.alertInfo(); // wychttp://**.coma,bIn hybrid mode, the constructor mode is used to define instance attributes, while the prototype mode is used to define methods and shared attributes. Each instance will have its own instance attribute, but at the same time it shares methods, saving memory to the maximum extent. In addition, this mode also supports passing initial parameters. Many advantages. This pattern is the most widely used and most recognized method of creating custom objects in ECMAScript.
Dynamic Prototype Mode
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), this allows you to choose whether the prototype needs to be initialized by judging whether the method is valid.
function Blog(name, url) { this.name = name; this.url = url; if (typeof this.alertInfo != 'function') { // This code is only executed once alert('exe time'); Blog.prototype.alertInfo = function() { alert(thia.name + this.url); } }}var blog = new Blog('wuyuchang', 'http://tools.VeVB.COM'), blog2 = new Blog('wyc', 'http:***.com');You can see that in the example above, the window pops up once, 'exe time', that is, when blog is initialized, blog2 does not need to initialize the prototype. For creating objects using this pattern, it can be considered perfect.
This blog post refers to the third edition of "JavaScript Advanced Programming", but the language has been simplified and the examples have been rewritten. If you have any questions, please leave a message and reply, and the author will update the blog.