js 의 prototype 과 구조 함수
Vjeux 가 쓴 이 글 은 js 의 원형 작업 방식 을 잘 이해 하 는 데 도움 이 될 것 입 니 다.http://blog.vjeux.com/2011/javascript/how-prototypal-inheritance-really-works.html
Everywhere on the web we read that Javascript has prototypal inheritance. However Javascript only provides by default a specific case of prototypal inheritance with the new operator. Therefore, most of the explanations are really confusing to read. This article aims to clarify what is prototypal inheritance and how to really use it on Javascript.
Prototypal Inheritance Definition
When you read about Javascript prototypal inheritance, you often see a definition like this:
When accessing the properties of an object, JavaScript will traverse the prototype chain upwards until it finds a property with the requested name. Javascript Garden
Most Javascript implementations use __proto__ property to represent the next object in the prototype chain. We will see along this article what is the difference between __proto__ and prototype.
Note: __proto__ is non-standard and should not be used in your code. It is used in the article to explain how Javascript inheritance works.
The following code shows how the Javascript engine retrieves a property (for reading).
function getProperty(obj, prop) { if (obj.hasOwnProperty(prop)) return obj[prop] else if (obj.__proto__ !== null) return getProperty(obj.__proto__, prop) else return undefined }
Let's take the usual class example: a 2D Point. A Point has two coordinates x, y and a method print.
Using the definition of the prototypal inheritance written before, we will make an object Point with three properties: x, y and print. In order to create a new point, we just make a new object with __proto__ set toPoint.
var Point = { x: 0, y: 0, print: function () { console.log(this.x, this.y); } }; var p = {x: 10, y: 20, __proto__: Point}; p.print(); // 10 20
Javascript Weird Prototypal Inheritance
What is confusing is that everyone teaches Javascript prototypal inheritance with this definition but does not give this code. Instead they give something like this:
function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { print: function () { console.log(this.x, this.y); } }; var p = new Point(10, 20); p.print(); // 10 20
This is completely different from the code given above. Point is now a function, we use a prototype property, the new operator. What the hell!?
How new works
Brendan Eich wanted Javascript to look like traditional Object Oriented programming languages such as Java and C++. In those, we use the new operator to make a new instance of a class. So he wrote a new operator for Javascript.
The new operator takes a function F and arguments: new F(arguments...). It does three easy steps:
Now that we understand what the new operator does, we can implement it in Javascript.
function New (f) { /*1*/ var n = { '__proto__': f.prototype }; return function () { /*2*/ f.apply(n, arguments); /*3*/ return n; }; }
And just a small test to see that it works.
function Point(x, y) { this.x = x; this.y = y; } Point.prototype = { print: function () { console.log(this.x, this.y); } }; var p1 = new Point(10, 20); p1.print(); // 10 20 console.log(p1 instanceof Point); // true var p2 = New (Point)(10, 20); p2.print(); // 10 20 console.log(p2 instanceof Point); // true
Real Prototypal Inheritance in Javascript
The Javascript specifications only gives us the new operator to work with. However, Douglas Crockford found a way to exploit the new operator to do real Prototypal Inheritance! He wrote the Object.create function.
Object.create = function (parent) { function F() {} F.prototype = parent; return new F(); };
This looks really strange but what it does is really simple. It just creates a new object with its prototype set to whatever you want. It could be written as this if we allow the use of __proto__:
Object.create = function (parent) { return { '__proto__': parent }; };
The following code is our Point example with the use of real prototypal inheritance.
var Point = { x: 0, y: 0, print: function () { console.log(this.x, this.y); } }; var p = Object.create(Point); p.x = 10; p.y = 20; p.print(); // 10 20
Conclusion
We have seen what prototypal inheritance is and how Javascript implements only a specific way to do it.
However, the use of real prototypal inheritance (Object.create and __proto__) has some downsides:
Some further reading:
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[2022.04.19] 자바스크립트 this - 생성자 함수와 이벤트리스너에서의 this18일에 this에 대해 공부하면서 적었던 일반적인 함수나 객체에서의 this가 아닌 오늘은 이벤트리스너와 생성자 함수 안에서의 this를 살펴보기로 했다. new 키워드를 붙여 함수를 생성자로 사용할 때 this는...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.