Daz wrote:
[snip]
What's the difference between
someFunc.blah = function(){ ; }
and
someFunc.prototype.blah = function(){ ; }
? Does someFunc.blah call upon someFunc.prototype.blah?
No.
Is there any difference?
Yes, a very large one.
Properties of a prototype object are only significant when the function
- in this case, someFunc - is used as a constructor function. The
prototype object becomes part of the prototype chain, affecting what
values are obtained when reading a property of the new object.
When reading a property from an object, first the object itself is
checked to determine whether it has a property with that name. If so,
the value of that property is the result. If not, the first object in
the prototype chain is checked in the same way. This repeats until
either the property has been found, or the end of the chain has been
reached, in which case the result is the value, undefined.
This can be demonstrated quite simply.
var object;
function MyObject() {}
MyObject.myProperty = 'value';
object = new MyObject();
At this point, the function MyObject has a property named myProperty,
and an object has been created using that function. The aforementioned
property exists only on the function object -- the constructor function
-- and none of the objects created from it: the expression
typeof object.myProperty
will evaluate to 'undefined', not 'string'.
If, instead, the prototype object is modified:
var object;
function MyObject() {}
MyObject.prototype.myProperty = 'foo';
object = new MyObject();
different behaviour is seen. This time around, the constructor function
has no property named myProperty, but the object created using the
constructor does: the expressions
typeof object.myProperty
and
typeof MyObject.myProperty
will evaluate to 'string' and 'undefined', respectively. The value of
the former property is 'foo'.
Finally, it can be observed that adding a property directly to an object
obscures any value that might be obtained from the prototype chain.
Moreover, the prototype property remains unchanged:
var object, anotherObject;
function MyObject() {}
MyObject.prototype.myProperty = 'foo';
object = new MyObject();
anotherObject = new MyObject();
object.myProperty = 'bar';
Both objects have a property named myProperty, but the values differ:
the property of anotherObject obtains its value from the prototype
chain, whilst the property of object does not. The last assignment
statement creates a new property on the object, object, itself. In this
way, properties of a prototype object can be seen as default values for
object properties.
Keep in mind that the prototype chain is an internal property of
objects, and the chain itself cannot be changed once an object has been
created:
var object, anotherObject;
function MyObject() {}
MyObject.prototype.myProperty = 'foo';
object = new MyObject();
/* object.myProperty == 'foo' */
MyObject.prototype = {myProperty: 'bar'};
anotherObject = new MyObject();
/* object.myProperty == 'foo'
* anotherObject.myProperty == 'bar'
*/
If changing the value of the prototype property of MyObject had an
effect on existing objects, both objects would have observed a change in
value. As it happens, only new objects are affected.
However, if references to objects in the chain are retained,
modifications to them do have an effect:
var object;
function MyObject() {}
MyObject.prototype.myProperty = 'foo';
object = new MyObject();
/* object.myProperty == 'foo' */
MyObject.prototype.myProperty = 'bar';
/* object.myProperty == 'bar' */
Hope that helps,
Mike