原型链的创建与继承

JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。

万物皆对象

对象都具有属性__proto__

在JS里,万物皆对象。方法(Function)是对象,方法的原型(Function.prototype)是对象。因此,它们都会具有对象共有的特点。即:对象具有属性__proto__,可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型,这也保证了实例能够访问在构造函数原型中定义的属性和方法

一切对象都可看作是用构造函数生成,
如果一个对象没有构造函数,那么他的构造函数就是:
Function Object(){}

Function对象

方法对象同时具有(_proto_ 和 prototype)

方法这个特殊的对象,除了和其他对象一样有上述_proto_属性之外,还有自己特有的属性——原型属性(prototype),这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象)。原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。

instanceof

instanceof 操作符的内部实现机制和隐式原型、显式原型有直接的关系。instanceof的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例

对象值访问

JavaScript对每个创建的对象都会设置一个原型(_proto_),指向它的原型对象_proto_ = {}。
当我们用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined。

创建原型继承

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    1.改变_proto_指向
    var Student = {
    name: 'Robot',
    height: 1.2,
    run: function () {
    console.log(this.name + ' is running...');
    }
    };

    var xiaoming = {
    name: '小明'
    };

    xiaoming.__proto__ = Student;
    1
    2
    xiaoming.name; // '小明'
    xiaoming.run(); // 小明 is running...

    请注意,上述代码仅用于演示目的。在编写JavaScript代码时,不要直接用obj.__proto__去改变一个对象的原型,并且,低版本的IE也无法使用__proto__Object.create()方法可以传入一个原型对象,并创建一个基于该原型的新对象(原对象属性不会继承)

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 原型对象:
    var Student = {
    name: 'Robot',
    height: 1.2,
    run: function () {
    console.log(this.name + ' is running...');
    }
    };

    function createStudent(name) {
    // 基于Student原型创建一个新对象:
    var s = Object.create(Student);
    // 初始化新对象:
    s.name = name;
    return s;
    }

    var xiaoming = createStudent('小明');
    xiaoming.run(); // 小明 is running...
    xiaoming.__proto__ === Student; // true ******* *******