From: Stone Zhong on 18 May 2010 02:18 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.
From: Thomas 'PointedEars' Lahn on 18 May 2010 09:04 Stone Zhong wrote: > 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 -- Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. -- Tim Berners-Lee
|
Pages: 1 Prev: There I fixed it? Next: replace Function.prototype does not work |