From: Thomas 'PointedEars' Lahn on 14 Nov 2008 14:11 vwkng1987(a)gmail.com wrote: > Please look at the code below: (I am picking up JS from Crockfold and > a few other online sources too) It would appear you picked up the bad examples. > *************************************************************** > function Employee(name){ > this.name = name || 'default'; > } > > function WorkerBee(name, dept){ > this.base = Employee; //Not Employee(); > this.base(name); Another, less compatible possibility is Employee.call(this, name); > this.dept = dept; > } > > var test1 = new WorkerBee('test1', 'Input/Output'); > > Employee.prototype.speciality = 'none'; > > ((test1.speciality) ? test1.speciality : 'undefined').writeln(); // > returns 'undefined' > > WorkerBee.prototype = new Employee; This inheritance pattern, which unfortunately originates from the first versions of Netscape JavaScript References and has survived in numerous tutorials to date (even the Wikipedia article), is essentially a wrong one, meaning that it does not do what it is intended to do. It does *not* insert the prototype object of `Employee'[1], `Employee.prototype', in the prototype chain of `Workerbee' objects so that `Workerbee' objects would inherit from `Employee.prototype': A: (new WorkerBee) --> WorkerBee.prototype --> Employee.prototype Instead, it inserts a new `Employee' object in the prototype chain so that `WorkerBee' objects inherit from that: B: (new WorkerBee) --> new Employee --> Employee.prototype That little thing makes a big difference when the `Employee' constructor adds properties to the object or modifies prototype properties, as here, because the lookup algorithm finds the dynamically added properties of *the same object* first. Unless you need behavior B, use the following pattern to achieve A instead: function inheritFrom(Constructor) { function Dummy() {} Dummy.prototype = Constructor.prototype; return new Dummy(); } WorkerBee.prototype = inheritFrom(Employee); The result is the following prototype chain: A2: (new WorkerBee) --> WorkerBee.prototype --> (new Dummy) --> Employee.prototype Since `Dummy' objects have no properties of their own, they don't interfere with the property lookup. NOTE: This isn't exactly news around here. > ((test1.speciality) ? test1.speciality : 'undefined').writeln(); // > STILL returns 'undefined' It's inefficient and harder to maintain to begin with. Consider this instead: (test1.speciality || 'undefined').writeln(); But since when has a String object (that the primitive string value is being converted to here) a writeln() method? Maybe you were looking for document.writeln(test1.speciality || 'undefined'); BTW: Maybe I'm wrong, but I think the word should be "specialty". > var test2 = new WorkerBee('test2', 'Computer Science'); > > test2.speciality.writeln(); //NOW this returns 'none'! ^^^^^^^^^^^^^^^^^^^^ If this really works chances are you are using some kind of framework that augments the `String.prototype' object, so all bets are off until you post the (*stripped-down*) code of that method. By default (per Specification) String objects do not have or inherit a writeln() method. > *********************************************************************************************** > > My questions are follows: > 1) How does the base in WorkerBee works? When I call > var test1 = new WorkerBee('test1', 'Input/Output'); > base gets assigned to Employee (as a function) and 'test1' is passed > to Employee as a parameter which return the field "name : 'test1' '" > right? No. In a constructor, `this' refers to the object that is being constructed with it; not to the constructor itself. So the newly created `Employee' object is augmented with a `base' property that is called afterwards. > So If I were to check for the presence of a parameter named Employee > in test1 I would not find anything Correct aside from the use of the term "parameter". You mean a *property*. > because what the function of > Employee merely did was pass this statement "name : 'test1' " to the > body of test1. Is this true? No. Although this has been explained here ad nauseam before -- <http://jibbering.com/faq/#posting> --, why not use a debugger to find it out for yourself? <http://jibbering.com/faq/#debugging> > (I did check test1.hasOwnProperty(Employee) and results = false); Works as designed. `Employee' is a reference to a Function object. Object.prototype.hasOwnProperty() expects (of course) as *string value* to contain the property *name*. If the argument was not of type string, it would be converted to string. The string representation of `Employee' is something along "function Employee(...) {\n ...\n}", and there is no property with *that* name. But even if you passed "Employee", the method would return `false', for the reason explained above. > 2) IF my understanding of prototype is true, then when I called > WorkerBee.prototype = new Employee; > this would like the function WorkerBee's prototype to an Employee > Object, and this Employee Object's prototype field is linked to > another anonymous object with the field 'speciality' = 'none'. Roughly speaking that's correct. However, you need to use proper terms: In ECMAScript implementations, objects have *properties*, not fields. Objects are *being referred to* (with *references* that are values, and properties to hold those values), not being linked. > If this were true, how come my second call to find out the speciality > of test1 STILL returned null? Impossible to say. A `TypeError' exception should have been thrown ("test2.speciality.writeln is not a function"). Either your framework has interfered, like String.prototype.writeln = function() { document.write(this); }; or you don't post exactly the code that you are using, or you are not testing nearly as thorough as you think. HTH PointedEars ___________ [1] For the sake of brevity I am referring to identifiers as objects, even though they only represent references to objects of which there can be more than one. -- Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300dec7(a)news.demon.co.uk>
From: Thomas 'PointedEars' Lahn on 14 Nov 2008 14:28 disappearedng wrote: > 1) Whenever you call a constructor, the engine creates an anonymous > object and assigns the value of its parameter to that anonymous > object, but then that object's __proto__ field is assigned the value > of the Constructors' prototype right? No. The object is augmented with a `__proto__' *property* with that value *in (Netscape/Mozilla.org) JavaScript* (so not in Microsoft JScript and other incompatible implementations). > 2) When I call another constructor within a constructor, do I also > create ANOTHER ANONYMOUS OBJECT by the method of 1) above? No. > So in this illustration, > fn_WorkerBee.prototype---->anonymous_object.__proto__ where > anonymous_object.base------>another_anonymous_object created by > Employee's constructor? Please restate your request. > 3) > " > Because the internal [[prototype]] property of an existing object is > NOT > updated when the value of the 'prototype' property of its constructor > function changes. > When you create test2, that changed prototype is used, however, and > is responsible to give the result 'none'. > " That's not the reason why. The internal [[prototype]] property does not need to be updated then without the prototype chain to break, if the latter has been set up properly in the first place. What properties an object effectively has (meaning provides as it owns and inherits them) is determined *on lookup*, not before. > If i were to indicate the direction of the link with the arrow, There is no link. > does this mean > > fn_workerbee.prototype---->my_Object.__proto__ No. > hence if fn_workerbee.prototype gets any changes my_Object will not be > able to detect since it is in the reverse side of the inheritance > chain Again, only if the prototype chain was set up that way (not properly). > but like what you said, shouldn't the function workerbee have access > to the my_object since fn_workerbee.prototype is directly linked to my > object? Please restate your request. > Does this mean that every object created is linked to their > constructor? No. PointedEars -- Use any version of Microsoft Frontpage to create your site. (This won't prevent people from viewing your source, but no one will want to steal it.) -- from <http://www.vortex-webdesign.com/help/hidesource.htm>
First
|
Prev
|
Pages: 1 2 Prev: node.offsetWidth vs clientWidth vs scrollWidth Next: Alt Gr keycode, Ctrl left or right... |