I like to use OOP in large projects that I'm currently working on. I need to create several classes in JavaScript, but if I remember correctly, there are at least two ways to do this. What is grammar and why is it used in this way?
I want to avoid using third-party libraries - at least in the first place.
In search of other answers, I found the article“ Object oriented programming using JavaScript ", part I: Inheritance - Document JavaScript , this article discusses JavaScript Object oriented programming in. Is there a better way to inherit?
#1 building
var Animal = function(options) { var name = options.name; var animal = {}; animal.getName = function() { return name; }; var somePrivateMethod = function() { }; return animal; }; // usage var cat = Animal({name: 'tiger'});
#2 building
Here are the methods I've used to create objects in javascript so far
Example 1:
obj = new Object(); obj.name = 'test'; obj.sayHello = function() { console.log('Hello '+ this.name); }
Example 2:
obj = {}; obj.name = 'test'; obj.sayHello = function() { console.log('Hello '+ this.name); } obj.sayHello();
Example 3:
var obj = function(nameParam) { this.name = nameParam; } obj.prototype.sayHello = function() { console.log('Hello '+ this.name); }
Example 4: The actual benefits of Object.create(). Please refer to [this link]
var Obj = { init: function(nameParam) { this.name = nameParam; }, sayHello: function() { console.log('Hello '+ this.name); } }; var usrObj = Object.create(Obj); // <== one level of inheritance usrObj.init('Bob'); usrObj.sayHello();
Example 5 (customized Crockford's Object.create):
Use ES6 / ES2015 to update the answer at any timeObject.build = function(o) { var initArgs = Array.prototype.slice.call(arguments,1) function F() { if((typeof o.init === 'function') && initArgs.length) { o.init.apply(this,initArgs) } } F.prototype = o return new F() } MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example var userB = { init: function(nameParam) { this.id = MY_GLOBAL.nextId(); this.name = nameParam; }, sayHello: function() { console.log('Hello '+ this.name); } }; var bob = Object.build(userB, 'Bob'); // Different from your code bob.sayHello();
A class is defined as follows:
class Person { constructor(strName, numAge) { this.name = strName; this.age = numAge; } toString() { return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')'; } } let objPerson = new Person("Bob",33); console.log(objPerson.toString());
#3 building
You may want to create a type using collapse mode:
// Here is the constructor section. var myType = function () { var N = {}, // Enclosed (private) members are here. X = this; // Exposed (public) members are here. (function ENCLOSED_FIELDS() { N.toggle = false; N.text = ''; }()); (function EXPOSED_FIELDS() { X.count = 0; X.numbers = [1, 2, 3]; }()); // The properties below have access to the enclosed fields. // Careful with functions exposed within the closure of the // constructor, each new instance will have it's own copy. (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() { Object.defineProperty(X, 'toggle', { get: function () { var before = N.toggle; N.toggle = !N.toggle; return before; } }); Object.defineProperty(X, 'text', { get: function () { return N.text; }, set: function (value) { N.text = value; } }); }()); }; // Here is the prototype section. (function PROTOTYPE() { var P = myType.prototype; (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() { Object.defineProperty(P, 'numberLength', { get: function () { return this.numbers.length; } }); }()); (function EXPOSED_METHODS() { P.incrementNumbersByCount = function () { var i; for (i = 0; i < this.numbers.length; i++) { this.numbers[i] += this.count; } }; P.tweak = function () { if (this.toggle) { this.count++; } this.text = 'tweaked'; }; }()); }());
This code will give you a type called myType. It will have internal private fields called switches and text. It will also have the following exposed members: number of fields and numbers; property toggle, text and number length; method increment NumbersByCount and tweak.
The folding mode is described in detail here: Javascript folding mode
#4 building
ES2015 course
In the ES2015 specification, you can use class syntax, which is just the basis of the prototype system.
class Person { constructor(name) { this.name = name; } toString() { return `My name is ${ this.name }.`; } } class Employee extends Person { constructor(name, hours) { super(name); this.hours = hours; } toString() { return `${ super.toString() } I work ${ this.hours } hours.`; } }
benefit
The main advantage is that static analysis tools find it easier to target this syntax. It's also easier for other people from a class based language to use that language as a multilingual.
Matters needing attention
Pay attention to its current limitations. To get private properties, you must Use Symbols or WeakMaps . In future releases, it is likely that classes will be extended to include these missing features.
Support
Browser support Isn't it good now (almost everyone just supports IE), but you can use these functions like transpiler now Babel .
Resources and resources
- Classes in ECMAScript 6 (final semantics)
- What? Wait. Really? Not good! (articles on ES6 and Privacy)
- Compatibility table - classes
- Sky Tower - class
#5 building
Object based classes with inheritance
var baseObject = { // Replication / Constructor function new : function(){ return Object.create(this); }, aProperty : null, aMethod : function(param){ alert("Heres your " + param + "!"); }, } newObject = baseObject.new(); newObject.aProperty = "Hello"; anotherObject = Object.create(baseObject); anotherObject.aProperty = "There"; console.log(newObject.aProperty) // "Hello" console.log(anotherObject.aProperty) // "There" console.log(baseObject.aProperty) // null
Simple, intimate, can be done.