here is a spike, to show a simple way to implement pseudo-classical code reuse in javascript, using inheritance.
javascript is a prototyped language, so the normal classical inheritance is not exactly possible.
note: some say that code re-use in javascript is better done using Decorator pattern, or using composition.
however, most programmers are familiar with classical inheritance and so this could be a convenient way to structure code for reuse, in a team of developers.
reference book:
http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?s=books&ie=UTF8&qid=1377268395&sr=1-1&keywords=javascript+the+good+parts
javascript is a prototyped language, so the normal classical inheritance is not exactly possible.
note: some say that code re-use in javascript is better done using Decorator pattern, or using composition.
however, most programmers are familiar with classical inheritance and so this could be a convenient way to structure code for reuse, in a team of developers.
reference book:
http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?s=books&ie=UTF8&qid=1377268395&sr=1-1&keywords=javascript+the+good+parts
1: //////////////////////////////////////////////////////////////////////////////
2: //inheritance, with following features:
3: //- overriding of base methods
4: //- private members
5: //- shared internal members (bit like protected, only works UP as well as down the hierarchy).
6: //- simple coding of derived class
7: //
8: // ref: JavaScript the Good Parts - D. Crockford, pages 52-55.
9: //////////////////////////////////////////////////////////////////////////////
10: //helper functions
11: Function.prototype.addMethod = function (name, func) {
12: this.prototype[name] = func;
13: return this;
14: };
15: Object.addMethod('getMethodInBase', function (name) {
16: var that = this;
17: var method = that[name];
18: return function () {
19: return method.apply(that, arguments);
20: };
21: });
22: //////////////////////////////////////////////////////////////////////////////
23: //tryout:
24: var inheritanceTryout2 = {};
25: ////////////////////////////////////////////
26: //class CarBase
27: //internalMembers: this is a bit like a protected member, but is shared UP as well as down the hierarchy.
28: //when client creates an instance, they need to pass in new empty object like this {}
29: //We need to do this, because we need an internal object shared, and we cannot assume that this class is the most derived class.
30: //
31: inheritanceTryout2.CarBase = function (color, name, internalMembers) {
32: if (!internalMembers)
33: {
34: internalMembers = {};
35: }
36: //secret is private to the base object
37: var secret = {
38: name: name
39: };
40: //internal member:
41: internalMembers.color = color;
42: var that = {};
43: //add a public 'priviledged' method, that has access to the private members:
44: that.getName = function () {
45: return 'CarBase.getName() - ' + secret.name;
46: };
47: //another method:
48: that.getNameLength = function () {
49: return 'CarBase.getNameLength() - ' + secret.name.length;
50: };
51: //add an internal method. this method can only be called by base or derived part of the object. (NOT public).
52: internalMembers.getColor = function () {
53: return 'CarBase.getColor() - internal color:' + internalMembers.color;
54: };
55: return that;
56: };
57: ////////////////////////////////////////////
58: //class Porche
59: inheritanceTryout2.Porche = function (color, name, style, internalMembers) {
60: if (!internalMembers) {
61: internalMembers = {};
62: }
63: //secret is private to this part of the object (NOT accessible by base or derived).
64: var secret = {
65: style: style
66: };
67: //inherit from CarBase:
68: var that = inheritanceTryout2.CarBase(color, name, internalMembers);
69: //get access to a method in base class:
70: var baseGetName = that.getMethodInBase('getName');
71: //override a base public method:
72: that.getName = function () {
73: return 'Porche.getName() - porche name: ' + baseGetName();
74: };
75: //add a public method to this class:
76: that.getPorcheStyle = function () {
77: return 'Porche.getPorcheStyle() - ' + secret.style;
78: };
79: //add a public method, that calls an internal method:
80: that.getColorPublic = function () {
81: return 'Porche.getColorPublic() - colour from internal data: ' + internalMembers.getColor();
82: };
83: return that;
84: };
85: ////////////////////////////////////////////
86: //class PorcheConvertible
87: inheritanceTryout2.PorcheConvertible = function (color, name, style, roofState, internalMembers) {
88: if (!internalMembers) {
89: internalMembers = {};
90: }
91: //secret is private to this part of the object (NOT accessible by base or derived).
92: var secret = {
93: roofState: roofState
94: };
95: //inherit from Porche:
96: var that = inheritanceTryout2.Porche(color, name, style, internalMembers);
97: //get access to a method in base class:
98: var baseGetName = that.getMethodInBase('getName');
99: //override a base public method:
100: that.getName = function () {
101: return 'PorcheConvertible.getName() - porche name: ' + baseGetName();
102: };
103: //add a public method to this class:
104: that.getRoofState = function () {
105: return 'PorcheConvertible.getRoofState() - ' + secret.roofState;
106: };
107: that.setRoofState = function (value) {
108: secret.roofState = value;
109: };
110: return that;
111: };
112: ////////////////////////////////////////////
113: //class Ford
114: inheritanceTryout2.Ford = function (color, name, internalMembers) {
115: if (!internalMembers) {
116: internalMembers = {};
117: }
118: //inherit from CarBase:
119: var that = inheritanceTryout2.CarBase(color, name, internalMembers);
120: //get access to a method in the base class:
121: var baseGetName = that.getMethodInBase('getName');
122: //override a base public method:
123: that.getName = function (n) {
124: return 'Ford.getName(): ' + baseGetName();
125: };
126: return that;
127: };
128: inheritanceTryout2.write = function (msg) {
129: jsUtils.write(msg, 'carMessages');
130: };
131: //////////////////////////////////////////////////////////////////////////////
132: //TEST
133: $(function () {
134: inheritanceTryout2.test();
135: });
136: inheritanceTryout2.test = function () {
137: //create a Porche, passing in an internal object for internal data shared by base + derived parts:
138: var porche1 = inheritanceTryout2.Porche('pink', 'Cammy 1', 'classic');
139: //create another Porche:
140: var porche2 = inheritanceTryout2.Porche('violet', 'Cammy 2', 'groovy');
141: //create a Ford:
142: var ford1 = inheritanceTryout2.Ford('blue', 'Ford. 1');
143: //create a PorcheConvertible:
144: var porcheConv1 = inheritanceTryout2.PorcheConvertible('black', 'Porche 1', 'modern', 'up');
145: inheritanceTryout2.write('car testing ... ');
146: inheritanceTryout2.write('porche1: ' + porche1.getName());
147: inheritanceTryout2.write('porche1 style: ' + porche1.getPorcheStyle());
148: inheritanceTryout2.write('porche2: ' + porche2.getName());
149: inheritanceTryout2.write('porche2 style: ' + porche2.getPorcheStyle());
150: inheritanceTryout2.write('porche2 color: ' + porche2.getColorPublic());
151: inheritanceTryout2.write('ford1: ' + ford1.getName());
152: inheritanceTryout2.write('ford1: calling base public method: ' + ford1.getNameLength());
153: inheritanceTryout2.write('porcheConvertible1: ' + porcheConv1.getName());
154: inheritanceTryout2.write('porcheConvertible1 style: ' + porcheConv1.getPorcheStyle());
155: inheritanceTryout2.write('porcheConvertible1 color: ' + porcheConv1.getColorPublic());
156: inheritanceTryout2.write('porcheConvertible1: roof state: ' + porcheConv1.getRoofState());
157: porcheConv1.setRoofState('down');
158: inheritanceTryout2.write('porcheConvertible1: roof state: ' + porcheConv1.getRoofState());
159: //add global reference, so can access from browser console:
160: inheritanceTryout2.porche1 = porche1;
161: inheritanceTryout2.porche2 = porche2;
162: inheritanceTryout2.ford1 = ford1;
163: inheritanceTryout2.porcheConv1 = porcheConv1;
164: };
Comments
Post a Comment