I've been busy with the project for the last one months, and I haven't written any notes, so I'm a little empty today.
A few days ago when writing a project about how to encapsulate each component when thinking about several ways, here to summarize:
1. Constructor (similar to the way Java writes): All properties and methods are hung on this inside the constructor:
1 functionTextarea (opts) {2 This. defaults = {3 //... Here are some default properties4 };5 This. options = $.extend (true, {}, This. defaults, opts);6 This. Creatdom =function() {7 //... It's a lot of code here .8 };9 This. Setval =function() {Ten //... This is a lot of code . One }; A This. Getval =function() { - //... This is a lot of code . - }; the}
The advantage of this approach is that the code is relatively compact, well understood and managed by the code, but so that each time we instantiate an object, we will open a new memory to store the object (including methods and properties)
We changed:
1 functionTextarea (opts) {2 This. defaults = {3 //... Here are some default properties4 };5 This. options = $.extend (true, {}, This. defaults, opts);//This is the property that overrides later6 This. Creatdom =Creatdom;7 This. Setval =Setval;8 This. Getval =Getval;9 }Ten functionCreatdom () { One //... This is a lot of code . A } - functionSetval () { - //... This is a lot of code . the } - functionGetval () { - //... This is a lot of code . -}
This saves some memory: But at the expense of the code's compactness;
We can know that every time we instantiate an object, three methods are actually common, so there's a second way to define the object.
2, prototype style: The properties and methods are hung on the object's prototype:
1 functionTextarea () {}2Textarea.prototype.defaults = {3 //...4 };5Textarea.prototype.options = $.extend (true, {}, This. defaults);6Textarea.prototype.creatDom =function() {7 //...8 };9Textarea.prototype.setVal =function() {Ten //... One }; ATextarea.prototype.getVal =function() { - //... - }; the //of course, you can put all the properties and methods on the object and then hang it on the prototype: - functionTextarea () {} -Textarea.prototype = { - defaults: {}, +Options: $.extend (true, {}, This. Defaults), -Creatdom:function() {}, +Setval:function() {}, AGetval:function() {} at};
However, this method is undesirable because it is not possible to construct an object instance by using parameters (typically the properties of each object are not the same); Just like everyone in the FE doesn't have the same name, but can laugh and write code;
To give a simple example:
1 function Person () {} 2 Person.prototype.name = "Winter"; 3 function return This . Name; 4 New Person ("Summer"). GetName (); // The winter is the name of the well-being;
3, constructor + prototype combination of ways:
1 functionTextarea (opts) {2 This. defaults = {};3 This. option = $.extend (true, {}, This. defaults, opts);4 }5Textarea.prototype = {6Creatdom:function() {},7Setval:function() {},8Getval:function() {}9};
Look at this way is not very perfect ...
It seems not perfect, so textarea.prototype is still out there,
We'll take it to the object as well:
1 functionTextarea (opts) {2 This. defaults = {};3 This. option = $.extend (true, {}, This. defaults, opts);4Textarea.prototype = {5Creatdom:function() {},6Setval:function() {},7Getval:function() {}8 };9}
Now it looks good, but what happens every time we instantiate?
Will execute the code:
1 textarea.prototype = {2 function() {},3 function() {},4 function() {}5 };
So let's do one more step, which is to let it execute only once:
1 functionTextarea (opts) {2 This. defaults = {};3 This. option = $.extend (true, {}, This. defaults, opts);4 if(!! This. Init) {5Textarea.prototype = {6Creatdom:function() {},7Setval:function() {},8Getval:function() {}9 };Ten This. init =true; One } A}
Ok! in general, public properties are written under prototype and need to be changed at the time of instantiation.
In addition, when we instantiate the object (new), we need to execute the initialization function in the process of new:
For example, in the case of var textarea = new textarea (opts), we want to execute the Creatdom function instead of the new textarea (opts). Creatdom ();
This is what we need:
1 functionTextarea (opts) {2 This. defaults = {};3 This. option = $.extend (true, {}, This. defaults, opts);4 This. Creatdom ( This. options);5 }6Textarea.prototype = {7Creatdom:function() {},8Setval:function() {},9Getval:function() {}Ten};
Extra: constructor below the This
1 varDie =BlackBerry;2 functionPhone () {3Console.log ( This. die);4 }5Phone ()//BlackBerry6 varDie =BlackBerry;7 functionPhone () {8 This. Die = "Nokia";9Console.log ( This. die);Ten } OnePhone ()//Nokia
The constructor direct call will treat this as a global window
Therefore, the object written in the prototype is not hung under this, the direct call to the constructor will not have these properties and methods
If an object is generated as a constructor, the corresponding object and method are generated under window when the constructor is called directly
Prototype the following this
1 functionPhone () {}2Phone.prototype = {3Name: "Nokia",4Init:function() {5 This. Name = "BlackBerry";6 }7 };8 varMyphone =NewPhone ();9 myphone.init ();TenConsole.log (Myphone.name);//BlackBerry OneConsole.log (Phone.prototype.name);//Nokia
What does this in init mean? Phone.prototype?
Here this refers to the instantiation object called Myphone, instead of the prototype object, look at the following:
Console.log (Myphone.hasownproperty ("name"));//true
The reason for this is true when calling Myphone.init () is to add a Name property to the instantiated object
Console.log (Myphone.hasownproperty ("Init"));//false
This is false because start is a property of the prototype and not an instantiated object
I almost got cheated: I thought myphone.init () when the code was executed, this.name = "BlackBerry"; it would overwrite the properties below Phone.prototype.
How objects (classes) are encapsulated (object-oriented JS Basics)