对 原型 及 原型链 的理解

首先说一下什么是原型?
原型是一个可以被复制(或者叫克隆)的一个类,通过复制原型可以创建一个一模一样的新对象。通俗的说,原型就是一个模板,在设计语言中更准确的说是一个对象模板。
1、原型(Person)定义了一些公用的属性和方法;利用原型(Person)创建出来的新对象实例(joe和john对象)会共享原型(Person)的所有属性和方法。

var Person = function(name){
this.name = name;
}
Person.prototype.sayHi = function(){
console.log("Hello! I am " + this.name + “.”);
}
var joe = new Person(“joe”);
var john = new Person(“john”);
joe.sayHi(); //Hello! I am joe.
john.sayHi(); //Hello! I am john.

2、原型(Person)的属性和方法总是被原型实例所共享。
3、通过原型创建的新对象实例是相互独立的。
正是因为这样对象的使用才能更加灵活、更加易于扩展。

什么是原型链?
在javascript中,所有的对象都拥有一个__proto__属性指向该对象的原型(prototype)。
原型链就是沿着 __proto__这条线一直往下找的一个链条。
隐式原型 proto (对象才有) ; 显式原型 prototype(函数才有)
对 原型 及 原型链 的理解_第1张图片

自我理解(对原型链图的理解):
整个原型链条中一共用三个function,第一个function Foo()就是自定义的一个构造函数,第二个function Object()就是系统提供的一个专门创建对象的构造函数,第三个function Function()就是系统提供的一个专门创建函数的构造函数。
接下来首先通过自定义函数 new出f1,f2两个新对象,这两个对象沿着__proto__这条线指向了构造函数的Foo.prototype原型对象。
所谓的原型链就是通过自定义函数function Foo()新生成的对象想要访问对象里的属性和方法时,先在这个对象的本身的成员属性里进行查找,如果说找不到对应的属性和方法,就沿着__proto__这个链条一层一层地找到它的原型,要么找到,要么找不到。如果找到了就返回,如果找不到就继续沿着__proto__这个链条找一直找下去,一直找到object.prototype的__proto__原型指向null的时候,就是没有找到的情况结束。这是最普通的一条线路。
另外每个原型对象都有一个constructor属性,代表构造函数,指向构造函数本身,为了遵循面向对象的规则,以免造成原型混乱。
function Object()是创建对象(new Object())的一个内部类,假如创建出两个新对象o1,o2,同样这两个对象会沿着__proto__这条线指向了Object()的Object.prototype原型对象。思考:js里面的对象要么是通过自定义构造函数生成,要么是通过Object()这个对象生成,原型对象(Foo.prototype)的话就硬生生的会出现,就是通过new Object()进行对象的创建,因此它的__proto__就指向了object.prototype原型对象,object.prototype的__proto__在js中规定强行指向null,不能无穷无尽找下去,得有一个终点。
function Function()是创建函数(newFunction())的一个内部类,函数在面向对象的编程中,充当了两个角色,既充当了对象的角色(功能),又充当了函数的角色(功能)。每一个普通的函数都有prototype这个属性,也有__proto__这个属性。
就是说,自定义构造函数function Foo()的__proto__指向了构建它(new Function())的function Function()的原型对象Function.prototype,这个原型对象是由function Object()创建出来的,因为它没有自己的构造函数,所以Function.prototype的__proto__又指向了object.prototyped的原型对象,最终它的__proto__指向null。

	因此无论沿着__proto__这条原型链怎么找,要么找到返回,要么指向null。那么这就是万物的定律,这就是原型链。

总结起来就是以下几点(借鉴别人的哈):
Object是所有对象的爸爸,所有对象都可以通过__proto__找到它
Function是所有函数的爸爸,所有函数都可以通过__proto__找到它
函数的prototype是一个对象
对象的__proto__属性指向原型,__proto__将对象和原型连接起来组成了原型链

这也就是为什么,我们在构造函数原型属性上的写的方法和属性我们在实例化对象之后是可以访问到的原因,就是这个__proto__起了很大的一个作用。
实例化对象的__prpto__属性=构造函数的prototype原型

其中的两个方法:
hasOwnProperty 函数可以用来检查对象自身是否含有某个属性,返回值是布尔值,当属性不存在时不会向上查找对象原型链。
getOwnPropertyNames 函数可以获取对象所有的自身属性,返回值是由对象自身属性名称组成的数组,同样不会向上查找对象原型链。

你可能感兴趣的:(对 原型 及 原型链 的理解)