深入理解原型链

76 阅读3分钟

深入理解原型链

原型链和原型对象是js的核心,js以原型链的形式,保证函数或对象中的方法、属性可以向下传递,按照面向对象的说法,这就是继承。而js通过原型链才得以实现函数或对象的继承,那么下面我们就来聊一聊js中的原型链。👇

函数的prototype

1)函数的prototype属性

  • 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象)

    注意:这里的空对象是指:没有我们指定的属性和方法

  • 原型对象中有一个属性constructor,它指向函数对象

2)给原型对象添加属性(一般都是方法)

  • 作用:函数的所有实例对象自动拥有原型中的属性(方法)

image.png

 <script>
        //  每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象)
        console.log(Date.prototype,typeof Date.prototype );
       //自己定义一个函数
       function Fun() {
 ​
       }  
       console.log(Fun.prototype); //默认指向一个Object空对象(没有我们的属性)
       
     //   原型对象中有一个属性constructor,它指向函数对象
     console.log(Date.prototype.constructor===Date);
     console.log(Fun.prototype.constructor===Fun);
 ​
     // 给原型对象添加属性(一般是方法)===> 实例对象恺英访问
     Fun.prototype.test = function () {
         console.log('test()');
     }
     
     // 创建实例对象
     var fun = new Fun()
     fun.test()
     </script>

image.png

显式原型和隐式原型

  1. 每个函数function都有一个prototype,即显示原型;

  2. 每个实例对象都有一个__proto__,可称为隐式原型;

每个对象都有__proto__,它是隐式原型属性,指向了创建该对象的构造函数原型。由于js中是没有类的概念,而为了实现继承,通过 __proto__ 将对象和原型联系起来组成原型链,就可以让对象访问到不属于自己的属性。

  1. 对象的隐式原型的值为其对应构造函数的显式原型的值;
<!---->

     <script>
         // 定义构造函数
         function Fn(){
             // 内部语句:this.prototype = {}
         }
     ​
         // 1.每个函数function都有一个prototype,即显示原型属性,默认指向,一个空对象Object
         console.log(Fn.prototype);
     ​
         // 2.每个实例对象都有一个__proto__,可称为隐式原型
         // 创建实例对象
         var fn = new Fn() // 内部语句:this.__proto__ = Fn.prototype
         console.log(fn.__proto__);
     ​
         // 3.对象的隐式原型的值为其对应构造函数的显示原型的值
         console.log(Fn.prototype===fn.__proto__);
     ​
         // 给原型添加方法
         Fn.prototype.test = function(){
             console.log('test()');
         }
         // 通过实例调用原型的方法
         fn.test()
     </script>

image.png

  1. 内存结构图:

image.png

5)总结:

  • 函数的prototype属性:在定义函数时自动添加的,默认值是一个空Object对象;
  • 对象的__proto__属性: 在创建对象时自动添加的,默认值为构造函数的prototype属性值
  • 程序员的直接操作显示原型,但不能直接操作隐式原型(ES6之前)

原型链

1)原型链

  • 访问一个对象属性时,先在自身属性中查找,找到就返回
  • 如果没有,再沿着__proto__这条链向上查找,找到就返回
  • 如果最终没有找到,就返回undefined
  • 别名:隐式原型链
  • 作用:查找对象的属性(方法)

     <script>
       function Fn(){
         this.test1 = function(){
             console.log('test1');
         }
       }
     ​
       console.log(Fn.prototype);
     ​
       Fn.prototype.test2 = function(){
         console.log('test2()');
       }
     ​
       var fn = new Fn()
       fn.test1()
       fn.test2()
       console.log(fn.toString());
       console.log(fn.test3);
       fn.test3()
     </script>

image.png

2)构造函数/原型/实体对象的关系(图解)

image.png

3)构造函数/原型/实体对象的关系2(图解)

image.png  

// 1.函数的显示原型指向的对象默认时Object实例对象(但object不满足)
     console.log(Fn.prototype instanceof Object);//true
     console.log(Object.prototype instanceof Object); //false
     console.log(Function.prototype instanceof Object);//true
     // 2.所有函数都是Function的实例(包含Function)
     console.log(Function.__proto__===Function.prototype);//true
     // 3.Object的原型对象是原型链的尽头
     console.log(Object.prototype.__proto__);//null

再次理解

image.png

image.png

image.png

详谈JavaScript原型链 - 程序猿的程 - 博客园 (cnblogs.com)