why prototype is undefined

后端 未结 2 621
一个人的身影
一个人的身影 2021-02-02 17:04

I known this has been asked hundreds of times, however, I can\'t seem to grasp the concept of prototype

Here\'s my sample script

var config          


        
相关标签:
2条回答
  • 2021-02-02 17:32

    The prototype property only exists on functions, and person is not a function. It's an object.

    Here's what's happening:

    var man = Object.create(null);         // man (object) -> null
    man.sex = "male";
    
    var person = Object.create(man);       // person (object) -> man (object) -> null
    person.greet = function () { ... };
    
    var p = Object.getPrototypeOf(person); // man (object) -> null
    alert(p.sex);                          // p is the same object as man
    
    person.prototype.age = 13;             // person doesn't have a prototype
    
    var child = function () {};            // child (function) -> Function.prototype
                                           // -> Object.prototype -> null
    child.prototype.color = "red";         // child has a prototype
    
    var ch = Object.getPrototypeOf(child); // Function.prototype
    
    alert(ch.color);                       // ch is not the same as color.prototype
                                           // ch is Function.prototype
    

    For more information I suggest you read this answer: https://stackoverflow.com/a/8096017/783743

    Edit: To explain what's happening in as few words as possible:

    1. Everything in JavaScript is an object except primitive values (booleans, numbers and strings), and null and undefined.

    2. All objects have a property called [[proto]] which is not accessible to the programmer. However most engines make this property accessible as __proto__.

    3. When you create an object like var o = { a: false, b: "something", ... } then o.__proto__ is Object.prototype.

    4. When you create an object like var o = Object.create(something) then o.__proto__ is something.

    5. When you create an object like var o = new f(a, b, ...) then o.__proto__ is f.prototype.

    6. When JavaScript can't find a property on o it searches for the property on o.__proto__ and then o.__proto__.__proto__ etc until it either finds the property or the proto chain ends in null (in which case the property is undefined).

    7. Finally, Object.getPrototypeOf(o) returns o.__proto__ and not o.prototype - __proto__ exists on all objects including functions but prototype only exists on functions.

    0 讨论(0)
  • 2021-02-02 17:53

    I think you might be mixing concepts. Try grasping the concept of prototypes with classic prototype inheritance first, then you can get into all the new Object stuff.

    In JavaScript, every object (numbers, strings, objects, functions, arrays, regex, dates...) has a prototype which you can think of as a collection of methods (functions) that are common to all current and future instances of that object.

    To create a prototype chain you have to create a function and then call it with the new keyword to specify that it is a constructor. You can think of constructors as the main function that takes the parameters necessary to build new instances of your object.

    Having this in mind, you can extend native objects or create your own new prototype chains. This is similar to the concept of classes but much more powerful in practice.

    Similar to your example, you could write a prototype chain like this:

    // Very basic helper to extend prototypes of objects
    // I'm attaching this method to the Function prototype
    // so it'll be available for every function
    Function.prototype.inherits = function(parent) {
      this.prototype = Object.create(parent.prototype);
    }
    
    // Person constructor
    function Person(name, age, sex) {
      // Common to all Persons
      this.name = name;
      this.age = age;
      this.sex = sex;
    }
    
    Person.prototype = {
      // common to all Persons
      say: function(words) {
        return this.name +'says: '+ words;
      }
    };
    
    // Student constructor   
    function Student(name, age, sex, school) {
      // Set the variables on the parent object Person
      // using Student as a context.
      // This is similar to what other laguanges call 'super'
      Person.call(this, name, age, sex);
      this.school = school; // unique to Student
    }
    
    Student.inherits(Person); // inherit the prototype of Person
    
    var mike = new Student('Mike', 25, 'male', 'Downtown'); // create new student
    
    console.log(mike.say('hello world')); //=> "Mike says: hello world"
    

    In newer version of JavaScript (read EcmaScript) they added new ways to deal with objects and extend them. But the concept it's a bit different from classical prototype inheritance, it seems more complicated, and some more knowledge of how JS works underneath would help to really understand how it works, plus it doesn't work in older browsers. That's why I suggest you start with the classical pattern for which you'll find accurate and abundant information on the internet.

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