Function.prototype does not work

S

Stone Zhong

Hi there,

I am reading the book "The Concise Guide to Dojo" and I saw some code
like below on page 11:

decafbad.school.PersonClassic.prototype = {...

I personally did a test like below

==== this code does not work ===
function Person(name) {
this.name = name;
Person.prototype = {
sayHi: function() { alert('hi ' + this.name); }
};
}
var a = new Person("JavaScript");
a.sayHi(); // I got error a.sayHi is not a function

however, if I change the code to below style , it worked,
function Person(name) {
this.name = name;
Person.prototype.sayHi = function() { alert('hi ' + this.name);
}
var a = new Person("JavaScript");
a.sayHi();

My conclusion is, a function's prototype already has some hidden
properties which might be important, replace function's prototype is
not good idea, only add property to function's prototype.
 
T

Thomas 'PointedEars' Lahn

Stone said:
I am reading the book "The Concise Guide to Dojo"

From what I have seen here, Dojo is junk as the people maintaining it do not
know what they are doing. Unlearn everything you have read there, and ask
for a refund.
and I saw some code like below on page 11:

decafbad.school.PersonClassic.prototype = {...

I personally did a test like below

==== this code does not work ===
function Person(name) {
this.name = name;
Person.prototype = {
sayHi: function() { alert('hi ' + this.name); }
};
}
var a = new Person("JavaScript");
a.sayHi(); // I got error a.sayHi is not a function

Read the ECMAScript Language Specification, Edition 3 or 5, sections 11.2.2
and 13.2.2:

The internal `[[Prototype]]' property of the newly constructed object
(instance), which is used for prototype chain lookup, is set to the current
value of the `prototype' property of the constructor *before* control enters
the execution context of the constructor (before its `[[Call]]' method is
called).

In the constructor, you are overwriting its `prototype' property, which
previously referred to the same object as the `[[Prototype]]' property of
the instance. But you are not overwriting the `[[Prototype]]' property of
the instance. So the prototype chain lookup for methods of the newly
referred value must fail.

It is also the explanation why you can augment the object referred to by a
constructor's `prototype' property *after* objects have been created with
it, and those objects can use the new properties inherited through the
prototype chain.
however, if I change the code to below style , it worked,
function Person(name) {
this.name = name;
Person.prototype.sayHi = function() { alert('hi ' + this.name);

There's a syntax error, the function expression is incomplete.
}
var a = new Person("JavaScript");
a.sayHi();

My conclusion is, a function's prototype already has some hidden
properties which might be important,

It has, most notably `constructor'.
replace function's prototype is not good idea, only add property to
function's prototype.

That is a fallacy. There are things to consider, though, see below.

It makes no sense *here* to define that method within the constructor,
creating a new function object with identical signature and body on each
constructor call, to begin with. `this' has nothing to do with scope.
So use

function Person(name)
{
this.name = name;
}

Person.prototype.sayHi = function () {
window.alert('hi ' + this.name);
};

var a = new Person("JavaScript");
a.sayHi();

or the equivalent

function Person(name)
{
this.name = name;
}

var a = new Person("JavaScript");

Person.prototype.sayHi = function () {
window.alert('hi ' + this.name);
};

a.sayHi();

or

function Person(name)
{
this.name = name;
}

Person.prototype = {
constructor: Person,

sayHi: function () {
window.alert('hi ' + this.name);
}
};

var a = new Person("JavaScript");

a.sayHi();

if you want to have a "public" method.

(However, with the last approach you have either an *enumerable*
`constructor' property. Or if you do not define it you have one that does
not refer to the instance's constructor; but there is no explicit harm in
having that, the language itself does not use the property.)

Which is why

function Person(name)
{
this.name = name;
}

var a = new Person("JavaScript");

Person.prototype = {
sayHi: function() {
window.alert('hi ' + this.name);
}
};

a.sayHi();

must fail (`Person.prototype' now refers to an object that is not in the
prototype chain of the instance.)


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,163
Latest member
Sasha15427
Top