1
function Student() {
// initialization
}
2
var student = function(){
// initialization
};
在1和2的情况下,原型值是多少。谢谢。
第一个案例我得到Student
而第二个案件我得到Object
。为什么呢?
答案 0 :(得分:1)
您可以通过以下方式轻松查看对象的原型:
var s = new Student();
Object.getPrototypeOf(s);
和
Object.getPrototypeOf(student);
在第一种情况下(构造函数),您可以通过以下方式更改默认原型值:
Student.prototype = { foo: 'bar' };
var s = new Student();
Object.getPrototypeOf(s); // { foo: 'bar' }
在第二种情况下:
var student = Object.create({ foo: 'bar' });
student.prop = 'val';
Object.getPrototypeOf(student); // { foo: 'bar' }
您可以使用构造函数here查看用于创建对象的确切算法。 基本上是:
- 创建一个新的本机ECMAScript对象,让F成为该对象。
- 按照8.12中的说明设置F的[[Get]]除外的所有内部方法。
- 将F的[[Class]]内部属性设置为“Function”。
- 将F的[[Prototype]]内部属性设置为15.3.3.1中指定的标准内置函数原型对象。
- ...
醇>
根据标准:
生产ObjectLiteral:{}的计算方法如下:
返回一个新对象,就好像通过表达式new Object()一样 Object是具有该名称的标准内置构造函数。
这意味着当使用{}
时,内部应该被称为new Object
,这意味着您将Object
作为默认原型(请参阅上面的参考资料)。
答案 1 :(得分:1)
我将
console.log(Object.getPrototypeOf(new Student()));
放入谷歌浏览器的javascript控制台。
不同之处在于第二个示例是匿名构造函数。
function Student() {}
console.log(Student.name); // "Student"
var Student = function () {};
console.log(Student.name); // ""
var Student
不name
,仅引用它。但是,它也可以命名:
var Student = function Student() {};=
console.log(Student.name); // "Student"
无论如何,每个实例仍被识别为Student
s:
console.log(new Student() instanceof Student); // true for both
但是,Chrome正在尝试提供更多信息,因此它会跟随prototype
链,直到找到可以显示的name
:
var Student = function () {};
var base = Object.getPrototypeOf(Student.prototype);
console.log(base.constructor === Object); // true
console.log(base.constructor.name); // "Object"
答案 2 :(得分:0)
有很多材料可以解释原型的工作原理。在上面的示例中,您声明了两个等效的构造函数。也就是说,您可以从两个构造函数中创建“Student”类型的对象。
例如,我可以这样做:
function Student() {
// initialization
}
var pascal = new Student();
或者我能做到
var Student = function(){
// initialization
};
var pascal = new Student();
结果是一样的。
现在,这些构造函数有一个原型对象。如果您没有为其分配一个,则默认情况下会获得一个。例如,在任何一种情况下我都可以这样做:
Student.prototype.getName = function(){
return this.name;
};
然后我的任何学生实例都可以这样:
pascal.getName();
但是,您可以创建自己的原型对象并直接分配它们,以防您希望通过它们将某些内容暴露给给定构造函数的所有实例。例如。
你可以说学生的原型是另一个对象。
Student.prototype = {
takeExam: function(){
//define take exam
},
constructor: Student
};
现在这个合成对象是Student构造函数的原型。
或者您甚至可以使用此定义类型层次结构,如下例所示:
function FlyingThing(){ };
FlyingThing.prototype.fly = function(){
//fly
};
function Bird(){ }
Bird.prototype = new FlyingThing();
Bird.prototype.walk = function(){
//walk
};
现在,Bird的每个例子都可以飞行和行走。
现在,区分构造函数原型和实例原型非常重要。正如我已经展示的那样,您可以直接访问构造函数原型,您可以轻松地更改它,向其中添加新内容,或者在您认为合适的情况下进行更改。
为给定的构造函数创建实例时,会根据您用于创建它的构造函数为其分配一个原型对象。那个原型不是那么容易获得的。该原型是JavaScript将在属性查找中使用的原型。
如果您想知道给定实例对象的原型是什么,则需要使用Object.getPrototypeOf
和Object.isPrototypeOf
方法,如其他答案所示。
Student
实例的原型在逻辑上应该是您为Student构造函数定义的Student.prototype
对象。