prototype, __proto__和constructor

介绍

示例代码:

var Student = function(name){this.name = name;}

Student.prototype.speak = function(){console.log("Hello, I'm "+ this.name + ". ")}

var tom = new Student("Tom");
tom.speak();

tom.constructor === Student   //true

Student.prototype.constructor === Student  //true

tom.speak == Student.prototype.speak  //true

tom.__proto__ === Student.prototype  //true

//从上面的代码中得到启发,我们可以这样给Student.prototype添加方法:
tom.__proto__.sayHello = function(){console.log("Hello")};

//现在Student的任何一个对象都会有sayHello方法:
tom.sayHello();

结论: __proto__ 就相当于一个对象的原型,根据js调用规则,当一个对象调用一个方法时,如果对象本身不含有这个方法,就会从它的原型 __proto__ 中找,如果存在,直接调用;如果不存在,就会从 __proto____proto__ 中找…

接下来看一个复杂一点的。

TypeScript中的extends 语法

在TypeScript中有 extends关键字,用来声明类的继承关系:

class Animal {
   name: string;
   speak(){console.log("Animal speak")}
}
class Dog extends Animal {
 breed: string;
}

先看翻译成js之后的 Animal

var Animal = (function () {
    function Animal() {
    }
    Animal.prototype.speak = function () { console.log("Animal speak"); };
    return Animal;
}());

从代码中可以看出 Animal 仅仅是一个普通的 function

下面是 Dog 的代码:

var Dog = (function (_super) {
        __extends(Dog, _super);
        function Dog() {
            _super.apply(this, arguments);
        }
        return Dog;
}(Animal));

在定义 Dog 之前调用了 __extends 方法;同时 Dog 在构造时会调用 Animal 方法。

重点看看 __extends 的实现:

var __extends = (this && this.__extends) || function (d, b) {

    //继承TypeScript中用static声明的方法,类似于js: Animal.func会继承到Dog.func
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];

    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};

__extends 方法对 Dogprototype 进行重新赋值,它是用’__’new出来的一个对象,它的 constructorDog

Dog.prototype.constructor === Dog    //true

最后,来看看 Dog 对象是怎么调用 Animial 中的 speak 方法

var dog = new Dog();
dog.speak();

dog 本身并不含 speak 方法,于是runtime就会从 dog.__proto__(Dog.prototype) 中找, 也就是这个new 出来的’__’对象,它本身也不含有 speak 方法,接着又从它的 __proto__( __.prototype) 中找, 而 __.prototype 就是 Animal.prototype ,这里面就定义了 speak 方法,从而调用成功。

从上面的分析中可以知道,Animial.prototype 中的方法都被继承到 Dog 对象中了。

    原文作者:Placid_
    原文地址: https://www.jianshu.com/p/f9b108d9b311
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞