javascript自学之路(四)————js对象类型之prototype属性的探索

本篇尚未写完,初步排版

作为所有的对象都具有的属性之一,它叫做原型。初始指向一个叫做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对象的内容和bprototype属性储存的内容没有任何关系!属性和方法一样也不会覆盖。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.prototypetest对象的__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,所有的内置对象(ObjectArray)的__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克隆对象内容。

但是需要注意的是:根据结论2C对象的属性和方法和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__属性的内容可以被对象直接访问!


注:图片来源于网络,自己花了半天发现还是画错了,最后决定用这张图

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值