__proto__ VS. prototype in JavaScript

后端 未结 30 1945
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-21 06:14

This figure again shows that every object has a prototype. Constructor function Foo also has its own __proto__ which is Function.prototype, a

相关标签:
30条回答
  • 2020-11-21 06:55

    DEFINITIONS

    (number inside the parenthesis () is a 'link' to the code that is written below)

    prototype - an object that consists of:
    => functions (3) of this particular ConstructorFunction.prototype(5) that are accessible by each object (4) created or to-be-created through this constructor function (1)
    => the constructor function itself (1)
    => __proto__ of this particular object (prototype object)

    __proto__ (dandor proto?) - a link BETWEEN any object (2) created through a particular constructor function (1), AND the prototype object's properties (5) of that constructor THAT allows each created object (2) to have access to the prototype's functions and methods (4) (__proto__ is by default included in every single object in JS)

    CODE CLARIFICATION

    1.

        function Person (name, age) {
            this.name = name;
            this.age = age;  

        } 
    

    2.

        var John = new Person(‘John’, 37);
        // John is an object
    

    3.

        Person.prototype.getOlder = function() {
            this.age++;
        }
        // getOlder is a key that has a value of the function
    

    4.

        John.getOlder();
    

    5.

        Person.prototype;
    
    0 讨论(0)
  • 2020-11-21 06:55

    There is only one object that is used for protypal chaining. This object obviously has a name and a value: __proto__ is its name, and prototype is its value. That's all.

    to make it even easier to grasp, look at the diagram on the top of this post (Diagram by dmitry soshnikov), you'll never find __proto__ points to something else other than prototype as its value.

    The gist is this: __proto__ is the name that references the prototypal object, and prototype is the actual prototypal object.

    It's like saying:

    let x = {name: 'john'};
    

    x is the object name (pointer), and {name: 'john'} is the actual object (data value).

    NOTE: this just a massively simplified hint on how they are related on a high level.

    Update: Here is a simple concrete javascript example for better illustration:

    let x = new String("testing") // Or any other javascript object you want to create
    
    Object.getPrototypeOf(x) === x.__proto__; // true
    

    This means that when Object.getPrototypeOf(x) gets us the actual value of x (which is its prototype), is exactly what the __proto__ of x is pointing to. Therefore __proto__ is indeed pointing to the prototype of x. Thus __proto__ references x (pointer of x), and prototype is the value of x (its prototype).

    I hope it's a bit clear now.

    0 讨论(0)
  • 2020-11-21 06:56

    A nice way to think of it is...

    prototype is used by constructor() functions. It should've really been called something like, "prototypeToInstall", since that's what it is.

    and __proto__ is that "installed prototype" on an object (that was created/installed upon the object from said constructor() function)

    0 讨论(0)
  • 2020-11-21 06:58

    To put it simply:

    > var a = 1
    undefined
    > a.__proto__
    [Number: 0]
    > Number.prototype
    [Number: 0]
    > Number.prototype === a.__proto__
    true
    

    This allows you to attach properties to X.prototype AFTER objects of type X has been instantiated, and they will still get access to those new properties through the __proto__ reference which the Javascript-engine uses to walk up the prototype chain.

    0 讨论(0)
  • 2020-11-21 06:59

    In JavaScript, a function can be used as a constructor. That means we can create objects out of them using the new keyword. Every constructor function comes with a built-in object chained with them. This built-in object is called a prototype. Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

    1. First we created a constructor: function Foo(){}. To be clear, Foo is just another function. But we can create an object from it with the new keyword. That's why we call it the constructor function

    2. Every function has a unique property which is called the prototype property. So, Constructor function Foo has a prototype property which points to its prototype, which is Foo.prototype (see image).

    3. Constructor functions are themselves a function which is an instance of a system constructor called the [[Function]] constructor. So we can say that function Foo is constructed by a [[Function]] constructor. So, __proto__ of our Foo function will point to the prototype of its constructor, which is Function.prototype.

    4. Function.prototype is itself is nothing but an object which is constructed from another system constructor called [[Object]]. So, [[Object]] is the constructor of Function.prototype. So, we can say Function.prototype is an instance of [[Object]]. So __proto__ of Function.prototype points to Object.prototype.

    5. Object.prototype is the last man standing in the prototype chain. I mean it has not been constructed. It's already there in the system. So its __proto__ points to null.

    6. Now we come to instances of Foo. When we create an instance using new Foo(), it creates a new object which is an instance of Foo. That means Foo is the constructor of these instances. Here we created two instances (x and y). __proto__ of x and y thus points to Foo.prototype.

    0 讨论(0)
  • 2020-11-21 06:59

    I've made for myself a small drawing that represents the following code snippet:

    var Cat = function() {}
    var tom = new Cat()
    

    I have a classical OO background, so it was helpful to represent the hierarchy in this manner. To help you read this diagram, treat the rectangles in the image as JavaScript objects. And yes, functions are also objects. ;)

    Objects in JavaScript have properties and __proto__ is just one of them.

    The idea behind this property is to point to the ancestor object in the (inheritance) hierarchy.

    The root object in JavaScript is Object.prototype and all other objects are descendants of this one. The __proto__ property of the root object is null, which represents the end of inheritance chain.

    You'll notice that prototype is a property of functions. Cat is a function, but also Function and Object are (native) functions. tom is not a function, thus it does not have this property.

    The idea behind this property is to point to an object which will be used in the construction, i.e. when you call the new operator on that function.

    Note that prototype objects (yellow rectangles) have another property called constructor which points back to the respective function object. For brevity reasons this was not depicted.

    Indeed, when we create the tom object with new Cat(), the created object will have the __proto__ property set to the prototype object of the constructor function.

    In the end, let us play with this diagram a bit. The following statements are true:

    • tom.__proto__ property points to the same object as Cat.prototype.

    • Cat.__proto__ points to the Function.prototype object, just like Function.__proto__ and Object.__proto__ do.

    • Cat.prototype.__proto__ and tom.__proto__.__proto__ point to the same object and that is Object.prototype.

    Cheers!

    0 讨论(0)
提交回复
热议问题