说原型之前,我得把其他东西先理清,所有用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用这种方式实现数据的继承

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

 

posted on 2018-04-26 23:18  会搔耳朵的猫  阅读(247)  评论(0编辑  收藏  举报