Object.prototype和Function.prototype

时间:2016-11-24 07:17:09

标签: javascript javascript-objects

在JS函数中被称为对象。现在,当针对对象测试函数时,它们的行为会有所不同。

a = {};
console.log(a.prototype);   //undefined

function myFunc() {};
console.log(myFunc.prototype); //Object
Object.getPrototypeOf(myFunc); //function(){}

为了使事情变得更糟,this MDN article中的一个例子似乎改变了函数原型的构造函数。

  

secondConstructor.prototype.constructor = secondConstructor;

有人可以解释一下这种行为吗?

2 个答案:

答案 0 :(得分:4)

导致共同混淆的是,作为对象的函数具有.__proto__属性,并且作为函数具有.prototype属性。它们有不同的含义。

大多数JavaScript个对象都有一个原型对象,可以使用Object.getPrototypeOf()方法或.__proto__属性进行访问。这是用于重用代码的对象,当属性访问者无法在对象上找到请求的属性时,可以查询该对象,然后查找其原型。这就是函数中常见的.apply方法。 这是您在示例中访问此对象的方式:

Object.getPrototypeOf(myFunc); //function(){}

只有函数具有.prototype属性,new运算符在使用该函数创建新对象时使用该属性。当使用new运算符调用函数并创建新对象时,JS会检查函数的.prototype属性。如果它指向一个对象,JS会将此对象设置为新创建的对象的原型。这就是为什么示例中对象的.prototypeundefined的原因:

a = {};
console.log(a.prototype); // undefined
  

有人可以解释一下这种行为吗?

     

secondConstructor.prototype.constructor = secondConstructor;

对象的constructor属性通常指向用于创建对象的函数。声明函数时,将在函数的.prototype属性所指向的对象上自动创建此属性。

function c() {}
c.prototype.constructor === c; // true
var o = new c();
o.constructor === c; // true

但是,可以轻松更改此属性:

c.prototype = {constructor: function notCAnymore() {}}
var o = new c();
o.constructor === c; // false

现在我们不再引用正确的功能了。因此,在更改原型后,我们可能需要恢复.constructor属性:

c.prototype = {constructor: function notCAnymore() {}}
c.prototype.constructor = c; // restoring the correct constructor
var o = new c();
o.constructor === c; // true

这正是示例中所做的。原型改变了:

secondConstructor.prototype = new firstConstructor;

如果现在创建了对象,则指向正确构造函数的指针将丢失:

var o = new secondConstructor();
o.constructor === secondConstructor; // false

这就是为什么他们使用此代码来恢复它:

secondConstructor.prototype.constructor = secondConstructor;
var o = new secondConstructor();
o.constructor === secondConstructor; // true

答案 1 :(得分:1)

您的第一个陈述



var a = {};
console.log(typeof(a));
console.log(Object.getPrototypeOf(a));




这里a,只是一个对象,当你检查它的类型时它只返回对象而你无法访问它的原型

所有JavaScript对象都从其原型继承属性和方法。

使用对象文字或新Object()创建的对象继承自名为Object.prototype的原型

在第一种情况下,a只是对象文字,所以它的原型是空的。

在第二种情况下,myFunc是一个定义,可以通过new创建对象,但它也是一个对象,因此原型是对象的原因

Object.getPrototypeOf()方法返回指定对象的原型(即内部[[Prototype]]属性的值)。

对于MyFunc,原型是函数,因为它已被定义为函数



function myFunc() {};
console.log(myFunc.prototype); //Object
console.log(Object.getPrototypeOf(myFunc));




在第三个片段中,是继承的情况



function parent(name){
this.name=name;
}

function child(childname){
this.childname=childname;
}

child.prototype=Object.create(parent.prototype);

console.log(parent.prototype);
console.log(parent.prototype.constructor);
console.log(child.prototype);
console.log(child.prototype.constructor);




当child是inherting parent时,它的原型和构造函数是parent,为了将构造函数改为MDN所提到的那样

child.prototype.constructor=parent;

希望有所帮助