我们通过原型方式,解决了多个实例的方法共享问题,接下来,我们就来搞清楚原型(prototype),原型链的来龙去脉。
function createobj(uname) { this.username = uname; } createobj.prototype.showusername = function(){ return this.username; } var obj1 = new createobj('ghostwu'); var obj2 = new createobj('卫庄');
1,每个函数都有一个原型属性(prototype) , 这个属性是一个指针,指向构造函数的原型对象( createobj.prototype), 如上图中的第1根绿色的线
2,在默认情况下,所有原型对象都会自动获得一个constructor属性,该属性的作用上文已经解释过,该属性包含一个指向prototype属性所在的函数,如上图的第2根绿色的线
3,所有的实例( 通过构造函数new出来的, 原型对象[ 如createobj.prototype, 上图我还没有画出来]等 )都包含一个隐式原型(proto),该指针指向实例的构造函数的原型对象,
如上图中的第3根线和第4根线. obj1的构造函数是createobj, createobj的原型对象是createobj.prototype, obj2同理,所以:
obj1.proto === createobj.prototype //true
obj2.proto === createobj.prototype //true
4,写在构造函数中, 为this赋值的属性和方法, 在画图的过程中,把他们画在对象上面,如username这个是给对象赋值的属性,所以在obj1和obj2这两个对象上都会存在一个属性username
5,写在原型对象上的方法或者属性,应该把他们画在原型对象上,如
createobj.prototype.showusername = function(){ return this.username; }
showusername这个方法就要画在图中createobj.prototype上面
6,当一个对象访问属性和方法的时候,他的访问规则叫(就近原则), 规则如下:
当实例上面,存在属性或者方法时,直接用实例上面的,
如果实例上面不存在属性和方法,就会沿着实例的proto指针指向的原型对象继续往上查找,如果找不到,值就是undefined.
console.log( obj1.showusername() ); //ghostwu console.log( obj2.showusername() ); //卫庄
在obj1,obj2上面是不存在showusername这个方法的,所以会顺着proto查找到createobj.prototype原型对象上的showusername方法
如果,把createobj.prototype原型对象上的showusername注释掉,那么obj1.showusername和obj2.showusername就会报错
// createobj.prototype.showusername = function(){ // return this.username; // }
function createobj(uname) { this.username = uname; this.showusername = function(){ return '100'; } } createobj.prototype.showusername = function(){ return this.username; } var obj1 = new createobj('ghostwu'); var obj2 = new createobj('卫庄'); console.log( obj1.showusername() ); //100 console.log( obj2.showusername() ); //100
如果在构造函数中为this添加一个showusername方法, 那么obj1和obj2就会直接调用this上面的,因为这两个方法会被画在图中的实例上,所以:
console.log( obj1.showusername === obj2.showusername ); //false
现在,你应该能明白,把属性和方法写在构造函数的原型对象(prototype)上之后,能实现多个实例属性和方法的共享的原理了吧
什么是原型链?
在前面,我有说过,所有的实例(包括原型对象)都有一个隐式原型proto,那么createobj.prototype这个原型对象,他的proto指向谁呢?
function createobj(uname) { this.username = uname; this.showusername = function () { return '100'; } } createobj.prototype.showusername = function () { return this.username; } console.log( createobj.prototype.proto ); //指向object.prototype console.log( createobj.prototype.proto === object.prototype ); //true
createobj.prototype.proto指向的是object.prototype, 通过 全等运算符 (===) 测试之后为true
object.prototype.proto 指向的是null
这就是原型链,通过隐式原型把一些构造函数层层的串起来,通过上面这个图,就知道,为什么自定义的对象能调用tostring, valueof,等方法了吧?
因为所有的对象都是继承自object.
相信看了本文案例你已经掌握了方法,更多精彩请关注其它相关文章!
推荐阅读:
react-router4.0实现重定向与404功能
js设置元素样式步奏详解
js实现排序方法总结
以上就是jsprototype对象使用教学的详细内容。