自己对js对原型链的理解

js对象分为2种

 函数对象和普通对象

函数对象 比如

function Show(){}
var x=function Show2(){}
var b=new Function("show3","alert('bb')")

show、x、b都是函数对象 是可执行的 并且构造出普通对象

普通对象

var showobje=new Show()
var xobj=new x();
var bobj=new b();
var c={}

这些对象 都是普通对象

函数对象有个属性prototype,作用就是实现继承,他们指向一个自己构造的对象  比如 第一个function Show(){}的protoype就是: Show.prototype=new Show();

通过构造器构造的普通对象都有个一隐藏属性__proto__  这个属性指向他构造器prototype(普通对象是没有prototype)

以下面这个代码为例 来解释是怎么实现继承的

 function Person(name, age) {

            this.name = name;
            this.age = age;
        }
        Person.prototype.eat=function() {
            console.log(this.name + "正在吃饭");
        }

        function Student(name, age, className) {
            this.className = className;
            Person.call(this,[name,age]);//实现继承属性
        }
        //学生继承人的特性
        Student.prototype = Object.create(Person.prototype);
        //实现子类自定义扩展方法
         Student.prototype.doHomework=function() {
             console.log(this.name + "正在做作业");
         }
       window.onload=function() {
           //创建一个人
           var person = new Person("小明", 12);
           person.eat();//人正在吃饭

           //创建一个学生
           var stu = new Student("小胖", 12, "一年级");
           stu.eat();
           stu.doHomework();
       }

输出一下 我们可以看到 学生通过原型继承了人吃饭的特性

function Person(name, age) {

this.name = name;
this.age = age;
}
我们知道Person也是一个对象(函数对象),并且这个对象拥有一个prototype属性 并且这个属性等于new person();一个空对象(这个构造的空对象的_proto_并没有_proto_ 所以当找到这一级 就到了原型链顶端 )
后来我们在这个空对象上添加了一个eat函数
Person.prototype.eat=function(){...}
为什么通过new Person()构造的对象能使用这个函数呢
因为我们通过函数构造一个对象 这个对象的_proto_属性就指向了构造他函数的prototype对象
类似
var obje=new Person()
obje._proto_=Person.prototype;
当我们使用obje.eat()调用函数的时候 会在当前对象的成员里面找 很遗憾 没有找到
那么通过对象的_proto_原型链条 向上找 这个时候我们在prototype找到eat方法 那么就eat.call(this)调用
如果没有找到 在通过prototype对象的_proto向上找 最终找到_proto_=new Object();在Obje对象 找eat方法 没有找到 那么再向下Object的 发现_proto_为null 还没有找到则报错

 如下图

原文地址:https://www.cnblogs.com/LQBlog/p/6077815.html