• JavaScript 原型、原型链的深入理解


    在 JavaScript 中,大部分东西都是对象,数组是对象,函数也是对象,对象更加是对象。不管我们给数组和函数定义什么内容,它们总是有一些相同的方法和属性。比如说hasOwnProperty(),toString()等。

    这说明一个对象所拥有的属性不仅仅是它本身拥有的属性,它还会从其他对象中继承一些属性。当 JavaScript 在一个对象中找不到需要的属性时,它会到这个对象的父对象上去找,以此类推,这就构成了对象的原型链。理解js的原型链对使用 JavaScript 的对象非常有帮助。

    让我们通过一个例子由浅到深地理解原型链:

    function Foo(_name) {
      this.name = _name;
    }
    Foo.prototype.show = function() {
      console.log('I am ', this.name);
    };
    var f1 = new Foo('obj1');
    var f2 = new Foo('obj2');
    
    f1.show();  //  I am obj1
    f2.show();  //  I am obj2
    

    这是我们经常使用的创建对象的方式,将共同的方法放到 Foo.prototype 中,所有实例都共有这个方法了。
    这是怎么实现的呢?我们看下面这张图:

    我们先只用看第一行

    我们定义的show函数在Foo.prototype中,当我们执行f1.show()时,JavaScript 发现f1本身没有show这个属性,所以它就到f1的原型(也就是__proto__指向的对象)去找,找到了就可以调用。

    注:每个对象都有一个方法 hasOwnProperty() 来检查对象本身是否有某个属性,如果有则返回 true ;如果这个属性在它的原型链上或原型链上都没有,则返回 false ;

    图片第一行告诉了我们4点:

    • 所有函数都有一个prototype指针,指向原型对象,如图中的Fooprototype指针。prototype指针的意义是,当我们使用这个构造函数new出新对象的时候,新对象的原型是谁。
    • 构造函数的prototype所指向的原型对象有一个constructor指针,指回构造函数。如图中Foo.prototypeconstructor指针指向Fooconstructor指针有助于我们找到一个对象的构造函数是谁。
    • __proto__每个对象都有,JavaScript 在new一个对象的时候,会将它的__proto__指向构造函数的prototype指向的那个对象。在上图中,f1f2这些实例对象的__proto__都指向了Foo.prototype
    • 如果一个对象的__proto__指向了另一个对象,那么前者就继承了后者的所有属性。

    注:__proto__ 与 prototype 的区别!__proto__ 才是真正连接原型链的东西,而 prototype 只是构造函数的一个指针属性而已。

    图片后面展示了 JavaScript 原生对象的继承关系

    先看Foo的原型。Foo是一个函数,它的构造函数是 JavaScript 内部的function Function()Functionprototype指向了一个对象Function.prototype,因此Foo__proto__就指向了Function.prototype

    注:所有的函数都以 function Function() 为构造函数,因此,所有函数(包括 function Function() 和 function Object() )的 __proto__ 都指向 Function.prototype 这个对象,这个对象中定义了所有函数都共有的方法,比如 call() 、 apply() 等。

    Function.prototype这个对象,是一个普通的对象,它的构造函数是 JavaScript 内置的function Object()function Object()prototype指向Object.prototype,因此Function.prototype.__proto__就指向Object.prototype,这个对象中定义了所有对象共有的属性,比如我们之前说的hasOwnProperty()toString()

    注:同理,Foo.prototype 和其他自定义的对象也是 __proto__ 指向 Object.prototype 对象,就不需要说明了。

    Object.prototype就是原型链的终点了,它的__proto__null,JavaScript 查找属性时,如果到这里还没有找到,那就是undefined了。

    注:到这里就不难理解为什么我们说在 JavaScript 中,函数也是对象了,它就是继承自对象的。

    转载:https://www.jianshu.com/p/116ea3be6ef5

  • 相关阅读:
    Unix Programming :文件IO
    Git 小记
    Effective C++ Placement new
    Effective C++ 避免数组多态
    系列文章:云原生Kubernetes日志落地方案
    阿里巴巴大数据产品最新特性介绍--机器学习PAI
    Apache Flink 1.9.0版本新功能介绍
    Flink Checkpoint 问题排查实用指南
    进击的 Java ,云原生时代的蜕变
    8 分钟入门 K8s | 详解容器基本概念
  • 原文地址:https://www.cnblogs.com/lqqgis/p/14889196.html
Copyright © 2020-2023  润新知