I play with following JS code. And I have 2 questions.
1) Why User is not prototype of author_1?
2) Why after the resetting of Author.prototype author_1 becomes not an instanceof Author?
function User(_fname){
this.fname = _fname;
return this;
}
function Author(){
this.book = "Magick of JS";
return this;
}
Author.prototype = new User('John');
author_1 = new Author;
console.log("=======================");
console.log(author_1 instanceof Author); // true
console.log(author_1 instanceof User); // true
console.log(User.isPrototypeOf(author_1)); // false (>>>> 1) WHY? <<<<)
console.log(author_1.constructor); // User(_fname)
console.log(author_1.__proto__); // User { fname="John"}
console.log(Object.getPrototypeOf(author_1)); // User { fname="John"}
console.log(author_1.constructor.prototype); // User {}
Author.prototype = new User('Alex');
author_2 = new Author;
console.log("=======================");
console.log(author_1 instanceof Author); // false (>>>> 2) WHY? <<<<)
console.log(author_1 instanceof User); // true
console.log(User.isPrototypeOf(author_1)); // false
console.log(author_1.constructor); // User(_fname)
console.log(author_1.__proto__); // User { fname="John"}
console.log(Object.getPrototypeOf(author_1)); // User { fname="John"}
console.log(author_1.constructor.prototype); // User {}
console.log("=======================");
console.log(author_2 instanceof Author); // true
console.log(author_2 instanceof User); // true
console.log(User.isPrototypeOf(author_2)); // false
console.log(author_2.constructor); // User(_fname)
console.log(author_2.__proto__); // User { fname="Alex"}
console.log(Object.getPrototypeOf(author_2)); // User { fname="John"}
console.log(author_2.constructor.prototype); // User {}
console.log("=======================");
console.log(author_1); // User {book: "Magick of JS", fname: "John"}
console.log(author_2); // User {book: "Magick of JS", fname: "Alex"}
Thanks!
UPDATE
Thanks for help! But now I can't understand how author_1 can know that it's an Author
function log(){ console.log.apply(console, arguments) }
function User(_fname){
this.fname = _fname;
return this;
}
function Author(){
this.book = "Magick of JS";
return this;
}
Author.prototype = new User('John');
author_1 = new Author;
log(author_1); // User { book="Magick of JS", fname="John"}
log(author_1.__proto__); // User { fname="John"}
log(author_1.constructor); // User(_fname)
log(author_1 instanceof Author); // true
// How author_1 kowns that it's an Author? Where is property?
// Can I find it in web inspector? Or it's hidden value?
2 Answers 2
The object "User" is the constructor function. Each instance of "User" is a different object. Hence,
User.isPrototypeOf(author_1)isfalsebecause the object "User" is simply not the prototype; that instance you created is the prototype.When you change the prototype, the object previously created retains its original prototype chain, and hence it appears to the runtime system not to be an instance of "Author" anymore.
3 Comments
User is just a function that is used as a template for your objects, it's not a class.1) The new operator acts like this:
var x = new F()
// approximately the same as this:
x = Object.create(F.prototype); // x inherits from the prototype of F
F.call(x); // F is called with x as 'this'
For this reason:
User.isPrototypeOf(author_1) // false because
User.prototype.isPrototypeOf(author_1) // true
Resources: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
2) Instanceof acts like this:
x instanceof F
// aproximately the same as this:
Object.getPrototypeOf(x) === F.prototype
When you do F.prototype = {}, you changed the property of F, but you didn't change the prototype chain of the already created object x.
var initialProto = {id:1};
F.prototype = initialProto;
var x = new F();
var anotherProto = {id:2};
F.prototype = anotherProto ;
Object.getPrototypeOf(x) === initialProto // true;
initialProto === anotherProto // obviously false
Resources: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
Comments
Explore related questions
See similar questions with these tags.
()afternew Authorfor both author_1 and author_2? That may vastly change your results.new ConstructorFunctionbehaves exactly the same asnew ConstructorFunction(). It's just less common syntax.return thisinside the functions acting like constructors?