1

代码如下:

 function Teacher(name, age) {
        this.name = name;
        this.age = age;
    }
    Teacher.prototype.sayName = function() {
        alert(this.name);
    };
    Teacher.prototype.sayHi = function() {
        alert("Hi, I'm " + this.name);
    };
    console.log(Teacher.prototype instanceof Teacher);  // false
    console.log(Teacher.prototype instanceof Object);   // true
    console.log(Teacher.prototype);  // Teacher {sayName: function, sayHi: function}

ps 上面的输出是 chrome。第一个console.log显示Teacher.prototype不是Teacher的实例,但第三条显示Teacher.prototype是Teacher的实例(直觉上),这是矛盾的。

我知道第二个 console.log 是真的,因为 Object.prototype 在 Teacher.prototype 的原型链中,确切地说Teacher.prototype.__proto__ === Object.prototype。因此第一个 console.log 应该输出 false。

但我很困惑为什么第三个 console.log 的输出显示 Teacher.prototype 是 Teacher 的一个实例。谁能为我澄清一下?非常感谢。

4

2 回答 2

3

但我很困惑为什么第三个 console.log 的输出显示 Teacher.prototype 是 Teacher 的一个实例。谁能为我澄清一下?非常感谢。

你的想法没问题,Teacher.prototype不是Teacher. 让我在 DevTools 视图中做出有根据的猜测:

var obj = new Teacher();
obj.constructor;          // function Teacher
obj.constructor.name;     // "Teacher"

var proto = Teacher.prototype;
proto.constructor;        // function Teacher
proto.constructor.name;   // "Teacher"

看起来 Chrome DevTools 控制台.constructor.name会在漂亮打印对象时进行检查,这是合理的。原型对象(与函数一起创建并可以通过 访问.prototype)也有一个.constructor属性可以追溯到函数。

于 2013-04-29T17:59:39.777 回答
1

这就是 Chrome 控制台选择显示对象的方式。它查看constructor对象的属性,然后假定它是该构造函数的实例。

这适用于除原型对象之外的所有对象,因为它们的constructor属性指的是它们作为原型的函数,而不是创建它们的构造函数。

例子:

console.log(Teacher.prototype.constructor === Teacher); // logs true

// Lets overwrite the constructor
function Foo() {};
Teacher.prototype.constructor = Foo;

console.log(Teacher.prototype); 
// logs Foo {sayName: function, sayHi: function}
于 2013-04-29T17:57:01.230 回答