理解JavaScript原型

时间:2013-10-23 13:55:12

标签: javascript prototype prototypal-inheritance

我使用以下JS代码。我有两个问题。

1)为什么用户不是author_1的原型?

2)为什么在重置Author.prototype author_1之后不会成为作者的实例?

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"}

谢谢!

更新

感谢您的帮助!但现在我无法理解author_1如何知道它是作者

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 个答案:

答案 0 :(得分:4)

  1. 对象“User”是构造函数。 “用户”的每个实例都是不同的对象。因此,User.isPrototypeOf(author_1)false,因为对象“用户”根本不是原型;您创建的实例是原型。

  2. 当您更改原型时,先前创建的对象会保留其原始原型链,因此运行时系统似乎不再是“作者”的实例。

答案 1 :(得分:3)

1) 新运算符的行为如下:

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'

出于这个原因:

User.isPrototypeOf(author_1) // false because 
User.prototype.isPrototypeOf(author_1) // true

资源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

2) 行为的实例如下:

x instanceof F
// aproximately the same as this:
Object.getPrototypeOf(x) === F.prototype

执行F.prototype = {}时,您更改了F的属性,但未更改已创建对象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

资源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof