js原型和原型链的理解

131 阅读2分钟

js被描述为基于原型的语言
原型:在 javascript 中,函数可以有属性。每个函数默认都有一个特殊的属性叫作原型(prototype),每个对象创建之后默认都拥有一个原型对象,对象以原型为模板,从原型中继承方法和属性,具体的继承方式为将函数(Foobar())的一个特殊属性prototype整个赋值给了对象(new Foobar())的__proto__,其中__proto__即为对象原型,也就是(new Foobar()).__proto__=Foobar.prototype,也可以认为new Foobar().getPrototypeOf(new Foobar())=Foobar.prototype,(其中getPrototypeOf()为ES5的方法),所以构造函数的prototype中一般都存放用于继承的属性和方法。

原型=原型对象=对象原型,三者指向的其实是同一个东西

原型链:原型对象也可能拥有原型,并从中继承方法和属性,一层一层,以此类推,这种关系被称为原型链。

能被继承的属性和方法 都被定义在对象的构造器函数的prototype属性上,而非对象实例本身。

理解对象的原型(可以通过Object.getPrototypeOf(obj)或者已被弃用的__proto__属性获得)与构造函数的prototype属性之间的区别是很重要的。前者是每个实例上都有的属性,后者是构造函数的属性。也就是说,Object.getPrototypeOf(new Foobar())和Foobar.prototype指向着同一个对象 6dd93a52fab8e7107edaaa1ff52b89e.jpg

构造函数constrctor
实例化的对象会自动获取一个构造函数属性(person.constructor),此属性指向构造函数原型的构造函数(Person.prototype.constructor),当获取person.constructor时,其实person中并没有constructor属性,当不能读取到constructor属性时,会从person的原型(也就是Person.prototype)中读取,正好person的原型中有该属性,就会返回此属性值((Person.prototype.constructor),这个查找的过程所反映出来的关系就是原型链

    function Person(name, age){
        this.name = name;
        this.age = age;
    }
    var person1 = new Person('Echo', 19);
    //person1的构造函数是Person
    person1.constructor = Person
    // Person.prototype的构造函数也是Person
    Person.prototype.constructor = Person
    说明Person.prototype也是Person的一个实例

原型对象(Person.prototype)是构造函数(Person)的一个实例

developer.mozilla.org/zh-CN/docs/…