2016-11-24 56 views
0

在JS函數中被認爲是對象。現在,當函數針對對象進行測試時,它們的行爲有所不同。Object.prototype和Function.prototype

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

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

使事情最糟糕的,在this MDN article的例子似乎改變函數原型的構造函數。

secondConstructor.prototype.constructor = secondConstructor;

有人可以解釋這種行爲嗎?

+0

您好,我無法解釋該行爲,但我可以告訴你改用typeof myFunc ===「function」。另一方面typeof {} ===「object」 –

+0

_「有人可以解釋這種行爲嗎?」_你究竟想向我們展示什麼?普通對象沒有'.prototype'屬性。這並不意味着功能不是對象。 – JLRishe

+0

@JLRishe我沒有試圖展示任何東西 - 而是等待有人向我展示如何在JS中實現上述對象的不一致。請查看Maximus的答案以獲取更多信息。 –

回答

3

什麼導致一個共同的困惑是作爲一個對象的功能具有.__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 
+0

謝謝。它解釋了這個謎團。也可以請你介紹一下關於MDN文章設置構造函數的背景嗎? –

+0

@CharlieH,請參閱我的更新 –

+0

非常感謝。很好解釋。 –

1

爲您的第一條語句

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

這裏一個,僅僅是一個對象,當你檢查它的類型,它只是返回的對象,你不能訪問它的原型

所有的JavaScript對象繼承其原型的屬性和方法。

對象使用對象文本創建的,或者用新對象()中,從一個叫的Object.prototype

在這裏,在第一種情況下原型繼承,一個只是對象常量所以它的原型是空的。

在第二種情況下,myFunc的是哪些對象可以通過新創建的定義,但它還有一個目的,這就是這樣的理由是原型對象這裏

的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);
的情況下

當孩子inherting父,它的原型和構造的父母,爲了改變構造是相同的MDN已經提到它作爲

child.prototype.constructor=parent; 

希望它可以幫助

+0

//在第一種情況下,a只是對象字面值,所以它的原型是空的。這是錯誤的。解釋這個問題的正確方法是你不能通過「prototype」屬性訪問大多數JS對象的原型。 –

+0

好吧會糾正它 – Geeky

相關問題