Js | 原型链

先插播一段代码:怎样去判断是数组?

 // 判断数组
        let  num  = []
        console.log(typeof num); //Object typeof 无法判断数组
        console.log(num instanceof Array); //true

instanceof

// 创建对象的方式主要有以下几种:
        // 第一种: 字面量
        var Obj1 = {
            name: 'o1'
        };
        var Obj2 = new Object({
            name: 'o2'
        });

        // 第二种: 构造函数
        var M = function (name) {
            this.name = name
        };
        var Obj3 = new M('o3');

        // 第三种: Object.create
        var p = {
            name: 'o4'
        }
        var Obj4 = Object.create(p);


        console.log(Obj1)
        console.log(Obj2)
        console.log(Obj3)
        console.log(Obj4)

Js | 原型链

注意第四个( _proto _ )!!!

Js | 原型链
原型链是实现继承的主要方法,要理解就要明白原型对象、构造函数、实例,三者之间的关系!!!
构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实力也有一个指向原型对象的内部指针。
当这个原型对象是另一个类型的实例,那么这个原型对象就有一个内部指针指向另一个原型,以此类推就构成了一条原型链。原型链的根就是Object.prototype

Js | 原型链
//图片来自网络

Js | 原型链

在来一段简单的代码吧!!!

如上面列举的创建对象方式的第二种方式,M 就是一个构造函数,那么 M 就应该有一个 原型对象,可以通过 prototype 找到!而 M 的原型对象存在 constructor,按照上图所示, M 的 原型对象的 constructor 指向的就是 M 本身;实践看结果:

	var Function_eat = function (name, age) {
            this.name = name;
            this.age = age;
        }

        Function_eat.prototype.eat = function () {
            console.log('看看我这一行代码,它能让我成为最帅的人');
        }

        var Xiaochen = new Function_eat('小陈', 20)
        Xiaochen.eat() //看看我这一行代码,它能让我成为最帅的人

        //构造函数的隐式原型指向谁?
        console.log(Xiaochen.__proto__ == Function_eat.prototype); //true
        console.log(Function_eat.prototype.constructor == Function_eat); //true
        console.log(Function_eat.prototype.__proto__ == Object.prototype); //true
        //注意
        console.log(Object.prototype.__proto__); //null
        //扩展
        console.log(Function_eat.prototype.__proto__);
        console.log(Function_eat.prototype.constructor);
        console.log(Xiaochen.__proto__);

Js | 原型链
关于上面推荐大家看下面一篇文章《JavaScript原生链》

从一个实例对象向上找有一个构造实例的原型对象,这个原型对象又有构造它的上一级原型对象,如此一级一级的关系链,就构成了原型链。原型链的最顶端就是Object.prototype ;

原型链最重要的作用就是继承,实例来继承上一级的属性或方法。此外,如果有多个实例,而多个实例存在共同方法,或共同属性,我们不想每一个实例都创建一份这些属性或方法,就可以将这些属性存在原型对象上,实例一样可以使用这些属性或方法;

类似于作用域链,实例在调用方法时,如果在本身没有找到,就会在原型对象上查找,如果也没有找到,就会再向上一级原型对象查找,一直找到Object.prototype ;如果中间找到会停止查找返回该方法。如果一直没找到会返回未定义;