本篇尚未写完,初步排版
作为所有的对象都具有的属性之一,它叫做原型。初始指向一个叫做Prototype的对象(它一开始什么都没有)
作用主要是实现类似“继承”的形式、创建多个对象的实例方便。
对象的prototype属性指向一个对应的Prototype对象,初始值为undefined
var a = new Object();
alert(a.prototype);//undefined
该属性被赋予一些属性或者方法的时候,这些属性和方法实际是加到了Prototype对象中作为Prototype对象的属性和方法,
该属性被赋予一个对象时,那就不同了,此时的prototype克隆了该对象所有的属性和方法,可以把prototype看做是一个“小容器”,所以具有prototype属性的该对象继承了被克隆对象。如果被克隆对象的prototype属性指向另一个被克隆对象时,此时就成了原型链,它的作用就相当于继承的概念,当调用方法的时候,如果对象本身没有找到,就会上溯这个原型链直到被找到或者到达顶端Object对象的prototype属性的null值。
如果先被赋值一些属性和方法然后被赋值一个对象,那么该对象就会覆盖之前赋值的所有内容,因为Prototype对象
普通对象和Function对象对于Prototype好像不同
vara = new Object();
console.log(a.prototype);//undefined
vara = new String();
console.log(a.prototype);//undefined
vara = new Array();
console.log(a.prototype);//undefined
******************************************************************
varb = new Function();
console.log(b.prototype);// Object { , 等 1 项… }
console.log( typeof b.prototype ); //object
console.log( b.prototype instanceof(Object));//true
console.log( b.prototypeinstanceof(Function) );//false
说明:Function对象的prototype属性为Object对象,而不是Function对象。
var b = new Function();
b.prototype.myname= "myname";
b.prototype.func=function(){alert("我是func方法")};
console.log(b.prototype);// Object { name:"myname", func: a.prototype.func(), 等 1 项… }
console.log(typeof b.prototype);//object
console.log(b.prototypeinstanceof(Object))//true
alert(b.prototype.myname)//myname
b.prototype.func();//我是func方法
说明:name属性和func方法都被加到prototype属性指向的Object对象中去了。
var b = new Function();
b.prototype.myname= "myname";
b.prototype.func=function(){alert("我是func方法")};
b.prototype=function(){alert("我是func对象")};
b.prototype.myname1="myname1";
b.prototype.func1=function(){alert("我是func方法1")};
console.log(b.prototype);//functionb.prototype()
console.log(typeof b.prototype);//function
console.log(b.prototypeinstanceof(Object));//true
console.log(b.prototypeinstanceof(Function));//true
alert(b.prototype.myname);//undefined
b.prototype.func();//TypeError:b.prototype.func is not a function
console.log(b.prototype.myname1);//myname1
b.prototype.func1()//我是func方法1
b.prototype()//我是func对象à把Function对象看做一般方法使用
说明:当给prototype赋值一个新对象的时候,那么prototype属性指向的对象就不是Object而是新对象了,之前赋给Object的所有的属性和方法全部丢失!同样可以添加方法和属性到这个新对象。
var b =new Function();
b.newname="newname"
b.newfunc=function(){alert("我是newfunc方法")};
b.prototype=function(){alert("我是func对象")};
b.prototype.newname="pnewname"
b.prototype.newfunc=function(){alert("我是pnewfunc方法")};
alert(b.newname)//newname
b.newfunc()//我是newfunc方法
alert(b.prototype.newname);//pnewname
b.prototype.newfunc();//我是pnewfunc方法
说明:b对象的内容和b的prototype属性储存的内容没有任何关系!属性和方法一样也不会覆盖。b.prototype储存的Function对象的属性和方法不属于b对象, b对象不可以直接使用b.prototype属性储存的对象中的属性和方法
var b = newFunction();
b.newname="bnewname"
b.newfunc=function(){alert("我是bnewfunc方法")};
b.prototype=function(){alert("我是b的储存对象")};
b.prototype.newname="pbnewname"
b.prototype.newfunc=function(){alert("我是pbnewfunc方法")};
var c = newFunction();
c.newname="cnewname"
c.newfunc=function(){alert("我是cnewfunc方法")};
c.prototype=b;//注意这里不是b(),因为b已经是对象了。写b()就会使其变为第一个Function对象
alert(c.newname)//cnewname
c.newfunc()//我是cnewfunc方法
alert(c.prototype.newname);//bnewname
c.prototype.newfunc();//我是bnewfunc方法
alert(c.prototype.prototype.newname)//pbnewname
c.prototype.prototype.newfunc()//我是pbnewfunc方法
说明:以上代码探究了“继承的情况”,发现,c对象可以正常调用prototype属性储存的b克隆对象的属性和方法,更是可以调用prototype属性储存的b克隆对象的prototype属性储存的Function克隆对象的属性和方法,即便这三者都重名,也没有发生所谓的覆盖或者“重写”现象,所以本质上和java的继承完全不同。
探究原型链:
var uw3c=newFunction()//创建Function对象
uw3c.prototype.prop = "b";
var test = new uw3c();//创建Function对象uw3c的一个实例
console.log(uw3c.prop);//undefined
console.log(test.prop);//b
console.log(test.prototype);//undefined
结论:对象拥有prototype属性,对象本身却不可以直接访问该属性里的内容,对象的实例是Object对象,和对象类型没有关系,也就是丢失了对象的所有的内容,对象的实例没有prototype属性,但是对象的实例直接拥有了对象的prototype属性里的内容。查阅资料从而知道:test.__proto__ =uw3c.prototype,test对象的__proto__属性内的内容可以被test对象直接访问。
var uw3c=newFunction()
var test = newuw3c();
var test2 = newuw3c();
console.log(test)
console.log(test.__proto__ == uw3c.prototype)//true
console.log(test2.__proto__ == uw3c.prototype)//true
console.log(uw3c.__proto__ == Function.prototype)//true
console.log(Function.__proto__ == Function.prototype)//true
console.log(Function.prototype)//function(){}
结论:Function对象的多个实例互不干扰。
test.__proto__ ==uw3c.prototype
uw3c.__proto__ ==Function.prototype
Function.__proto__== Function.prototype
Function.prototype为:function(){}
这就是原型链:实例的__proto__指向对象的prototype,对象的__proto__指向其对应的内置对象的prototype,所有的内置对象(Object、Array)的__proto__指向Function对象的prototype,它的值就是function(){}。
console.log(Object.__proto__)//function(){}
console.log(Array.__proto__)//function(){}
console.log(String.__proto__)//function(){}
可通过prototype属性指定继承对象,而引擎自动通过__proto__属性实现继承效果。
总结:
1. 普通对象(包括Object对象)的prototype属性初始为undefined类型,但是Function对象则为Object对象。并不存在所谓的Prototype对象!
2.
1) 针对于一般对象,若是直接赋值属性或者方法,则会报错,因为prototype属性默认为undefined类型,并非一个对象,自然不可以添加属性和方法。
2) 针对于Function对象:prototype属性相当于一个独立的空间、默认存放Object克隆对象。若是直接赋值属性或者方法,这些属性或者方法则加到了默认的Object对象中。
3) 针对于所有对象:若是直接赋值一个对象,则prototype属性这个空间储存该对象的克隆,undefined和默认的Object对象被丢弃。可以对该克隆对象添加属性和方法。拥有prototype属性的对象作为大空间,并不意味着可以直接调用prototype属性空间内储存的克隆对象的属性和方法,必须通过prototype属性找到克隆对象,然后由克隆对象调用。大空间里的属性和方法与prototype属性空间里的属性和方法没任何关系,同名也无所谓,不会产生覆盖。
3. 通过prototype属性达到“继承”效果,就是给C对象的prototype属性赋值B对象,B对象的prototype属性赋值A对象,在效果上形成了继承,即B对象可以“拥有”A克隆对象的内容,C对象可以“拥有”B克隆对象的内容,也“拥有”了A克隆对象内容。
但是需要注意的是:根据结论2,C对象的属性和方法和prototype属性空间储存的B克隆对象的属性和方法毫不相干,B对象的属性和方法和prototype属性空间储存的A克隆对象的属性和方法毫不相干,也就是说,不会产生类似java中继承的重写效果。即便三个对象拥有同名的属性和方法,也不会相互覆盖掉!
4. 因为结论3的“继承”效果,产生了原型链。
varuw3c=new Function()//创建Function对象
uw3c.prototype.prop = "b";
var test = new uw3c();//创建Function对象uw3c的一个实例
console.log(uw3c.prop);//undefined
console.log(test.prop);//b
console.log(test.prototype);//undefined
结论:对象拥有prototype属性,对象本身却不可以直接访问该属性里的内容,对象的实例是Object对象,和对象类型没有关系,也就是丢失了对象的所有的内容(除了prototype属性储存的内容),对象的实例没有prototype属性,但是对象的实例直接拥有了对象的prototype属性里的内容。查阅资料从而知道:test.__proto__ =uw3c.prototype
Function对象的实例.__proto__== Function对象.prototype==Object对象(默认。可被指定修改)
Function对象.__proto__==Function内置对象.prototype== Function内置对象.__proto__== Object对象
Object对象.__proto__==Object对象.prototype(作为Function对象)==特殊的Object对象(它的__proto__==null)
Object内置对象.prototype==特殊的Object对象(它的__proto__==null)
Object内置对象.__proto__==??.prototype==Object对象
其他对象.__proto__==Function对象.__proto__==Function内置对象.prototype== Function内置对象.__proto__== Object对象
其他内置对象.
一个对象的__proto__属性的内容可以被对象直接访问!
注:图片来源于网络,自己花了半天发现还是画错了,最后决定用这张图