javascript
javascript原型_JavaScript的原型:古怪,但这是它的工作原理
javascript原型
by Pranav Jindal
通過普拉納夫·金達爾
JavaScript的原型:古怪,但這是它的工作原理 (Prototype in JavaScript: it’s quirky, but here’s how it works)
The following four lines are enough to confuse most JavaScript developers:
以下四行足以使大多數JavaScript開發人員感到困惑:
Object instanceof Function//trueObject instanceof Object//trueFunction instanceof Object//trueFunction instanceof Function//truePrototype in JavaScript is one of the most mind-boggling concepts, but you can’t avoid it. No matter how much you ignore it, you will encounter the prototype puzzle during your JavaScript life.
JavaScript中的原型是最令人難以置信的概念之一,但您無法避免。 無論您多么忽略它,您在JavaScript的生活中都會遇到原型難題。
So let’s face it head-on.
因此,讓我們面對現實吧。
Starting with basics, there are following data types in JavaScript:
從基礎開始,JavaScript中包含以下數據類型:
First five are primitive data types. These store a value of their type such as a boolean, and can be true or false.
前五個是原始數據類型。 它們存儲其類型的值(例如boolean),并且可以為true或false 。
The last “object” is a reference type which we can describe as a collection of key-value pairs (but it is much more).
最后一個“對象”是一種引用類型,我們可以將其描述為鍵-值對的集合(但要多得多)。
In JavaScript, new objects are made using Object constructor function (or object literal {}) which provides generic methods like toString() and valueOf().
在JavaScript中,使用對象構造 函數 (或對象常量{} ) 創建了新對象,該函數提供了諸如toString()和valueOf()類的通用方法。
Functions in JavaScript are special objects which can be “called”. We make them and by using the Function constructor function (or function literal). The fact that these constructors are objects as well as function has always confused me, much in the same way the chicken-egg riddle confuses everyone.
JavaScript中的函數是可以“ 調用”的特殊對象。 我們通過使用Function構造函數 (或函數文字)來制作它們。 這些構造函數既是對象又是函數,這一事實始終使我感到困惑,就像雞肉蛋之謎使所有人困惑一樣。
Before starting with Prototypes, I want to clarify that there are two prototypes in JavaScript:
在開始原型之前,我想澄清一下JavaScript中有兩個原型:
prototype: This is a special object which is assigned as property of any function you make in JavaScript. Let me be clear here, it is already present for any function you make, but not mandatory for internal functions provided by JavaScript (and function returned by bind). This prototype is the same object that is pointed to by the [[Prototype]](see below) of the a newly created object from that function (using new keyword).
prototype :這是一個特殊的對象,它被分配為您在JavaScript中所做的任何函數的屬性。 在這里讓我清楚一點,它對您創建的任何函數都已經存在,但對于JavaScript提供的內部函數(以及bind返回的函數)不是必需的。 該prototype與對象所指向的對象相同。 該函數中新創建的對象的[[Prototype]] (請參見下文)(使用new關鍵字)。
[[Prototype]]: This is a somehow-hidden property on every object which is accessed by the running context if some property which is being read on the object is not available. This property simply is a reference to the prototype of the function from which the object was made. It can be accessed in script using special getter-setter (topic for another day) called __proto__. There are other new ways to access this prototype, but for sake of brevity, I will be referring to [[Prototype]] using __proto__.
[[Prototype]]:這是每個對象的某種隱藏屬性,如果正在對象上讀取的某些屬性不可用,則運行上下文可以訪問該對象。 該屬性只是對prototype的引用 制成對象的功能。 可以使用名為__proto__特殊getter-setter (另一天的主題)以腳本的方式進行訪問。 還有其他訪問此原型的新方法,但是為了簡潔起見,我將參考[[Prototype]] 使用__proto__ 。
The above two statements are equal statements when used to make a new object, but a lot happens when we execute any of these statements.
上面的兩個語句在用于創建新對象時是相等的語句,但是當我們執行其中的任何一條語句時,都會發生很多事情。
When I make a new object, it is empty. Actually it is not empty because it is an instance of the Object constructor, and it inherently gets a reference of prototype of Object, which is pointed to by the __proto__ of the newly created object.
當我制作一個新對象時,它是空的。 實際上,它不是空的,因為它是 Object 構造函數,并且固有地獲取prototype的引用 的Object, __proto__指向的 新創建的對象。
If we look at the prototype of Object constructor function, it looks the same as the __proto__ of obj. In fact, they are two pointers referring to the same object.
如果我們看一下Object構造函數的prototype ,它看起來與obj.的__proto__相同obj. 實際上,它們是指向同一對象的兩個指針。
obj.__proto__ === Object.prototype//trueEvery prototype of a function has an inherent property called constructor which is a pointer to the function itself. In the case of Object function, the prototype has constructor which points back to Object.
每個prototype 功能的 具有一個稱為constructor的固有屬性,該屬性是指向函數本身的指針。 對于Object函數, prototype具有constructor 指向Object 。
Object.prototype.constructor === Object//trueIn the picture above, the left side is the expanded view of the Objectconstructor. You must be wondering what are all these other functions over it. Well, functions are objects, so they can have properties over them as other objects can.
在上圖中,左側是Object構造函數的展開圖。 您一定想知道它上面的所有其他功能是什么。 函數是對象 ,因此它們可以像其他對象一樣具有屬性。
If you look closely, the Object (on left) itself has a __proto__ which means that Object must have been made from some other constructor which has a prototype. As Object is a function object, it must have been made using Function constructor.
如果仔細觀察, Object (左側)本身具有__proto__ 這意味著該Object 必須由其他具有prototype.構造函數制成prototype. 作為Object 是一個功能對象,它必須是使用Function制成的 構造函數。
__proto__ of Object looks same as prototype of Function.When I check the equality of both, they turn out to be the same objects.
__proto__ Object 看起來和Function prototype一樣。 當我檢查兩者的相等性時,它們原來是相同的對象。
Object.__proto__ === Function.prototype//trueIf you look closely, you will see the Function itself has a __proto__ which means that Function constructor function must have been made from some constructor function which has a prototype. As Function itself is a function, it must have been made using Function constructor, that is, itself. I know that sounds weird but when you check it, it turns out to be true.
如果仔細觀察,您會看到Function 本身有一個__proto__ 這意味著Function 構造函數 必須由具有prototype某些構造函數制成。 作為Function 本身是一個函數 ,它必須是使用Function制成的 構造函數,即本身。 我知道這聽起來很怪異,但是當您檢查它時,事實證明它是真實的。
The __proto__ of Function and prototype of Function are in fact two pointers referring to the same object.
__proto__ Function和prototype Function 是 實際上,兩個指針指向同一個對象。
Function.prototype === Function.__proto__\\trueAs mentioned earlier, the constructor of any prototype should point to the function that owns that prototype. The constructor of prototype of Function points back to Function itself.
如前所述,任何prototype的constructor 應該指向擁有該prototype.的函數prototype. constructor prototype Function 指向Function本身。
Function.prototype.constructor === Function\\trueAgain, the prototype of Function has a __proto__ .Well, that’s no surprise… prototype is an object, it can have one. But notice also that it points to the prototype of Object.
再次, prototype Function 有一個__proto__ 嗯,這并不奇怪…… prototype是一個對象,它可以有一個。 但還要注意,它指向prototype Object 。
Function.prototype.__proto__ == Object.prototype\\trueSo we can have a master map here:
所以我們可以在這里有一個主地圖:
instanceof Operatora instanceof bThe instanceof operator looks for the object b pointed to by any of the constructor(s) of chained __proto__ on a. Read that again! If it finds any such reference it returns true else false.
的 instanceof 運算符尋找對象b 指向 任何的constructor (多個) 的鏈式__proto__ 上a 。 再讀一遍! 如果找到任何此類引用,則返回true 否則為false 。
Now we come back to our first four instanceof statements. I have written corresponding statements that make instanceof return true for the following:
現在我們回到我們的前四個instanceof 陳述。 我寫了相應的語句,使instanceof 返回true 對于以下內容:
Object instanceof FunctionObject.__proto__.constructor === FunctionObject instanceof ObjectObject.__proto__.__proto__.constructor === ObjectFunction instanceof FunctionFunction.__proto__.constructor === FunctionFunction instanceof ObjectFunction.__proto__.__proto__.constructor === ObjectPhew!! Even spaghetti is less tangled, but I hope things are clearer now.
ew! 即使是意大利面也不會那么糾結,但我希望現在情況會更加清楚。
Here I have something that I did not pointed out earlier that prototype of Object doesn’t have a __proto__.
這里有一些我之前沒有指出的Object prototype 沒有__proto__ 。
Actually it has a __proto__ but that is equal to null. The chain had to end somewhere and it ends here.
實際上它有一個__proto__ 但這等于null 。 鏈條必須在某處結束,并在此處結束。
Object.prototype.__proto__\\nullOur Object, Function, Object.prototypeand Function.prototype also have properties which are functions, such as Object.assign, Object.prototype.hasOwnPropertyand Function.prototype.call. These are internal functions which do not have prototype and are also instances of Function and have a __proto__ which is a pointer to Function.prototype.
我們的Object , Function , Object.prototype和 Function.prototype 也具有作為函數的屬性,例如Object.assign , Object.prototype.hasOwnProperty和 Function.prototype.call 。 這些是內部函數,沒有prototype ,也是Function實例,具有__proto__ 這是指向Function.prototype的指針。
Object.create.__proto__ === Function.prototype\\trueYou can explore other constructor functions like Arrayand Date, or take their objects and look for the prototype and __proto__. I’m sure you will be able to make out how everything is connected.
您可以探索其他構造函數,例如Array和 Date ,或者拿走他們的東西并尋找prototype 和 __proto__ 。 我相信您將能夠弄清一切之間的聯系。
額外查詢: (Extra queries:)
There’s one more question that bugged me for a while: Why is it that prototype of Object is object and prototype of Function is function object?
有一個更多的竊聽我的問題了一會兒:為什么是它prototype的Object是對象和prototype的Function是函數對象 ?
Here is a good explanation for it if you were thinking the same.
這里 如果您也這么想的話,這是一個很好的解釋。
Another question that might be a mystery for you until now is: How do primitive data types get functions like toString(), substr() and toFixed()? This is well explained here.
到目前為止,您可能還不清楚的另一個問題是:原始數據類型如何獲取諸如toString() , substr()和toFixed()類的函數? 這很好地解釋了這里 。
Using prototype, we can make inheritance work with our custom objects in JavaScript. But that is a topic for another day.
使用prototype ,我們可以使繼承與JavaScript中的自定義對象一起使用。 但這是另一天的話題。
Thanks for reading!
謝謝閱讀!
翻譯自: https://www.freecodecamp.org/news/prototype-in-js-busted-5547ec68872/
javascript原型
總結
以上是生活随笔為你收集整理的javascript原型_JavaScript的原型:古怪,但这是它的工作原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到人吃蛇是什么意思
- 下一篇: 亚马逊面试有几轮_经过几个月的Googl