2015년 9월 6일 일요일

Javascript object model and inheritance


Let's see Javascript Object model and Inheritance. We'll see Javascript specific things and something is good to know. Learning test is written using Jasmine. Please refer Jasmine usage which I wrote before if you have interest it. 

Class based object model and prototype based object model
   
There is clear concept in programming language which use class based object model. It is class and instance. The class abstract characteristics of  objects which are in specific set(or category) using member variable and method. For example, The "Talent class" abstract general attributes of who have talented some area. On the other hand,  The instance represents one of talented people. "SteaveJobs instance" is that the actual instance of "Talent class" type. It have all attributes of "Talent class".

Like Javascript, the programming language which use prototype based object model, there is no clear distinction between class and instance. They are just an object. In those language, there is the object which can be a prototype. This prototype object become a template of other objects. Any object can be a prototype of other object in run-time or compile time. Objects which are created by prototype, they are share properties of prototype.

When you create object in javascript, you don't need to define class separately like we do in java. Instead of that, you can define attributes of object using "constructor function". Any javascript function can be a constructor function, you can create new object using constructor function with "new" keyword

Class-based
Prototype-based
Distinguish class and instance
All object can be inherited from other object
Need explicit class definition. Instance can be created by constructor.
Object definition and creation can be possible using "constructor function"
Create one object with new keyword
same
Define inheritance structure like subclass using class definition.
Define inheritance structure by assign prototype object with constructor function
Not possible to add attribute in runtime.
Possible to add/remove attribute in runtime


I'll use following inheritance structure as an example.



1. Inheritance

Let's see Painter object which inherit from Talent object. As see in [line 10], Talent.call(this) method is called in Painter object. About call function, look at this. You can call the "construct function" of Talent with"this" and additional arguments. Then, as see in [line 13], Talent.prototype is assigned to Painter.prototype. The prototype property is a special attribute in javascript, all function have this attribute. (Just for your reference, the function is declared like  function finctName {...} but not assigned to attribute of some object. The method is a function which is assigned to attribute of object.)

Let's see javascript internal object creation procedure. 

var psy = new Singer;

If there is new keyword, create generic object and make it as the value of this keyword in Signer's constructor function. Then, the "majorTalent" attribute is assigned explicitly in constructor function. In that order, the __proto__ attribute is assigned to the prototype attribute of Singer's constructor function implicitly.(The __proto__ attribute determine prototype which contains attribute to be returned)

When javascript read some attribute, javascript check the attribute in object first. If the attribute is not exist in object, javascript check prototype chain using __proto_ attribute. If the object in prototype chain have the attribute, javascript return it. If the property is not exist in prototype chain, javascript say that the attribute is not exist.


2. More flexible object creation - constructor function with arguments
Make constructor function can receive arguments.


3. More flexible object creation - default value
As see in [line4 ~ line6], you can set default value using "||" operator. If there is a value, it is used. But if there is no value, empty value is used as a default. The constructor function of Talent object is assigned to base attribute like [line 11]. The base attribute is not a special attribute. Any name is possible. Then, call constructor function in [line 12]

4. why we should assign "prototype" attribute explicitly?
Let's see TalentedForMusic and TalentedForPaint closely. The prototype attribute of TalentedForMusic is not assigned as its parent's prototype. Look at [line 43 - 46]. If you add additional attribute of Talent.prototype, the hummingMan object which instance of TalentedForMusic don't have this attribute. i.e. The attribute is not added since TalentedForMusic don't have parent's prototype attribute.

5. "The property in constructor function" vs "object.prototype.property = vlaue"
Let's see "name" attribute and "grade" attribute closely. The "name" attribute is declared in constructor function, the "grade" attribute is declared as prototype property like "Talent.prototype.grade = "none". This is an important difference. As see in [line32 - 43], if you assign new value to name attribute, values of instances are not changed. On the other hand, if it declared as a prototype attribute like [line 46 - 48], values of its instances will be changed as new value is assigned.

6. instanceof, __proto__
As see in [line 38], you can find the class using instanceof keyword. All javascript object have __proto__ attribute except Object.(All javascript function have prototype attribute). When object is created, the prototype attribute of constructor function is assigned to __proto__ attribute. As see in [line 39 - 41], the __proto_ property of object is same with the property of constructor function.

7. Use global value in constructor function
You have to be careful when use global variable in constructor function. You might be expected the value of count 1 in [line 35], but it is 3 since it called [line32], [line29], [line17]. i.e. it is also called when assign prototype attribute.


8. Javascript doesn't support multiple inheritance.
You might assume that TalentForMusic constructor function crates two object Talent and Personality. Actually, it is possible to use of attributes of Personality from Personality. But as see in [line 35], if you add new attribute to Personality, this attribute is not added to TalentedForMusic.


9. Reference
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

댓글 없음:

댓글 쓰기