跟我学习javascript的prototype原型和原型链(2)

function f1(){}; console.log(f1.prototype) //f1{} console.log(typeof f1.prototype) //Object console.log(typeof Function.prototype) // Function,这个特殊 console.log(typeof Object.prototype) // Object console.log(typeof Function.prototype.prototype) //undefined

从这句console.log(f1.prototype) //f1 {} 的输出就结果可以看出,f1.prototype就是f1的一个实例对象(这里就是f1的原型对象)。就是在f1创建的时候,创建了一个它的实例对象并赋值给它的prototype,基本过程如下:

var temp = new f1(); f1. prototype = temp;

所以,Function.prototype为什么是函数对象就迎刃而解了,上文提到凡是new Function ()产生的对象都是函数对象,所以temp1是函数对象。

var temp1 = new Function (); Function.prototype = temp1;

那原型对象是用来做什么的呢?主要作用是用于继承。举了例子:

var person = function(name){ this.name = name }; person.prototype.getName = function(){ return this.name; // 这里this指向原型对象person ==>person.name } var xpg = new person(‘xiaopingguo'); xpg.getName(); //xiaopingguo

从这个例子可以看出,通过给person.prototype设置了一个函数对象的属性,那有person实例(例中:xpg)出来的普通对象就继承了这个属性。具体是怎么实现的继承,就要讲到下面的原型链了。

在深入的讲一遍:无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性(同时它也是一个对象),默认情况下prototype属性(对象)会默认获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针,有些绕了啊,写代码、上图!

function Person(){ }

跟我学习javascript的prototype原型和原型链

根据上图可以看出Person对象会自动获得prototyp属性,而prototype也是一个对象,会自动获得一个constructor属性,该属性正是指向Person对象。

当调用构造函数创建一个实例的时候,实例内部将包含一个内部指针(很多浏览器这个指针名字为_ proto _ )指向构造函数的prototype,这个连接存在于实例和构造函数的prototype之间,而不是实例与构造函数之间。

function Person(name){ this.name=name; } Person.prototype.printName=function(){ alert(this.name); } var person1=new Person('Byron'); var person2=new Person('Frank');

跟我学习javascript的prototype原型和原型链

Person的实例person1中包含了name属性,同时自动生成一个_ proto _属性,该属性指向Person的prototype,可以访问到prototype内定义的printName方法,大概就是这个样子的:

跟我学习javascript的prototype原型和原型链

写段程序测试一下看看prototype内属性、方法是能够共享

function Person(name){ this.name=name; } Person.prototype.share=[]; Person.prototype.printName=function(){ alert(this.name); } var person1=new Person('Byron'); var person2=new Person('Frank'); person1.share.push(1); person2.share.push(2); console.log(person2.share); //[1,2]

果不其然!实际上当代码读取某个对象的某个属性的时候,都会执行一遍搜索,目标是具有给定名字的属性,搜索首先从对象实例开始,如果在实例中找到该属性则返回,如果没有则查找prototype,如果还是没有找到则继续递归prototype的prototype对象,直到找到为止,如果递归到object仍然没有则返回错误。同样道理如果在实例中定义如prototype同名的属性或函数,则会覆盖prototype的属性或函数。—-这就是Javascript的原型链。

function Person(name){ this.name=name; } Person.prototype.share=[]; var person=new Person('Byron'); person.share=0; console.log(person.share); //0;而不是prototype中的[]

6.原型链

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做_ proto _的内置属性,用于指向创建它的函数对象的原型对象prototype。以上面的例子

复制代码 代码如下:

console.log(xpg.__ proto __ === person.prototype) //true

同样,person.prototype对象也有_ proto _属性,它指向创建它的函数对象(Object)的prototype

复制代码 代码如下:

console.log(person.prototype.__ proto __=== Object.prototype) //true

继续,Object.prototype对象也有_ proto _属性,但它比较特殊,为null

复制代码 代码如下:

console.log(Object.prototype.__ proto __) //null

这个有_ proto _ 串起来的直到Object.prototype._ proto _为null的链叫做原型链。如下图:

跟我学习javascript的prototype原型和原型链

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgzjpf.html