欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

原型链

程序员文章站 2022-04-24 13:19:14
说原型之前,我得把其他东西先理清,所有用function创建出来的对象都有一个prototype对象,比如: JavaScript提供的所有内置对象,Object,Array,Function,RegExp这些构造函数类型都是 function ,都属于函数对象 但是这其中还有区别,以Array为例 ......

  说原型之前,我得把其他东西先理清,所有用function创建出来的对象都有一个prototype对象,比如:

1 function Person() {};
2 var Person = new function () {};

  JavaScript提供的所有内置对象,Object,Array,Function,RegExp这些构造函数类型都是 function ,都属于函数对象

  但是这其中还有区别,以Array为例,用以下三种方法创建变量:

1 var a1 = [1,2,3];
2 var a2 = new Array(1,2,3);
3 var a3 = Array(1,2,3);

  这三者之间,互不相等,但都是Object类型,只是引用的地址值不同,是三个不同的对象  同样的还有Object和Function

1 console.log(a1 == a2);//false
2 console.log(a1 == a3);//false
3 console.log(a2 == a3);//false

  但String,Number,Boolean三种与其他不同,以String类型为例,用三种方式创建变量

var a1 = "123";
var a2 = new String(123);
var a3 = String(123);

  这三种当中,值全部互相相等,但是a1和a3是String类型,a2是Object类型,所以比较全等(===)的时候,只有a1和a3全等

1 console.log(a1 === a2);//false
2 console.log(a1 === a3);//true
3 console.log(a2 === a3);//false

  Number,Boolean同理

总结:所有构造函数,只要用new方式实例化,那他的实例是Object类型。如果用其他方式的话,String,Number,Boolean是自己自身的类型,其他均为Object类型。

一、对象的原型

  原型就是在自定义构造函数创建的时候,系统默认添加的一个名为prototype的对象,这个对象中默认有一个costructor的属性,可以返回创建这个对象的构造函数的引用,还有一个没有被w3c认可的__proto__属性,他可以返回原型对象的原始对象,说着我都觉得绕...明明没这么难理解的...差不多就是这么个图

原型链

 

  所有函数对象的原型对象都继承自他的原始对象,也就是说Person.prototype.__proto__指向的是他的上一级的原型,在chrom中的显示如下图:

原型链

  可以看出它的上一季的原型是Object函数的原型Object.prototype。而实际上Object.prototype是所有对象的原始对象,这个原始对象他的__proto__属性是null,算得上是原型里的万物起源了,一般用Object.prototype表示原始对象

1 console.log(Person.prototype.__proto__ == Object.prototype);//true
2 console.log(Array.prototype.__proto__ == Object.prototype);//true
3 console.log(String.prototype.__proto__ == Object.prototype);//true
4 console.log(Function.prototype.__proto__ == Object.prototype);//true
5 console.log(Object.prototype.__proto__ == Object.prototype);//false
6 console.log(Object.prototype.__proto__);//null

  Object和Function之间的关系比较复杂,借用知乎上的一张图,可以很好地理清这里边的关系

原型链

  由于函数对象Function的特殊性,会有这样的关系:

1 console.log(Function.prototype === Object.__proto__);//true
2 console.log(Function.prototype === Function.__proto__);//true
3 console.log(Function.prototype.__proto__ === Object.prototype);//true

  所有的构造函数都是Function对象的实例,Object是Function的一个实例,并且Function.prototype是Object对象的一个实例的原型对象,实例对象的原型会指向其构造函数原型的prototype属性, 所以就有了 Object.__proto__ === Function.prototype, Function.__proto__ === Function.prototype, Function.prototype.__proto__ === Object.prototype,觉得绕的话还是看图,记住就行了,记不住就翻出来看看

二、原型链

  使用new得到的对象的实例,他的__proto__属性会指向被实例化的对象的原型对象,而函数对象的原型对象又继承自原始对象

 

function Person() {

    }
var p = new Person();
console.log(p.__proto__);//Person.prototype
console.log(p.__proto__.__proto__);//Object.prototype
console.log(p.__proto__.__proto__.__proto__);//Object.prototype.__proto__ null

 

  原型链其实想一个金字塔,越往上,原型方法越少,越往下,原型方法被扩充的越多。这种用__proto__链接,最终指向Object.prototype.__proto__的逻辑链,就是原型链,JavaScript用这种方式实现数据的继承

理解可能比较片面,如有不当,还请指正

 

原型链