javascript----------prototype 女爷i 2022-08-23 09:57 167阅读 0赞 下面都是个人理解以及查找的网上的资料,如有不对的地方请指正 prototype prototype在这里是原型的意思,不是指那个框架... 如果有一个function test()\{\} 它会有一个name属性,值为函数名test 即test.name=="test" //在 firefox下测试......... test还有一个constructor属性,他是指向他的构造函数的.... 即test.constructor 指向 Function test还有一个\_\_proto\_\_属性,他指向他的构造函数的原型 即test.\_\_proto\_\_===Function.prototype ps: Function.\_\_proto.\_\_,Object.\_\_proto\_\_都是function()\{\} 不指向任何构造函数 它还有一个prototype属性 ; 即test.prototype=\{\} 然后 prototype会自动添加一个test.prototype.constructor =test 它是指想函数本身的 /----------------------------个人觉得这个东西理解起来还是不容易(我也不能保证一定理解就是对)------- prototype还会自动添加一个属性,那就是\_\_proto\_\_ ; 它指向对象的父原型链 (ps不是父原型) 可以修改这个属性,修改后就当前对象的父原型链就改变了 实例后,它的默认值是指向原型对象的 (重上面的test.\_\_proto\_\_===Function.prototype就可以看出来) /------------------------------------------------------------------------------------------------------------- 可以测试一下 例子如下 //请在firefox测试 function test()\{\} alert(test.name); //可以看到是test alert(test.\_\_proto\_\_ === Function.prototype); //可以看到是true alert(test.constructor === Function); //还是true alert(test.prototype); //可以看到是object test.prototype.constructor(); //可以看到是执行了自己 至于prototype.\_\_proto\_\_;单独来写些例子 Object.prototype为原型链的终点 function test()\{\} alert(test.prototype.\_\_proto\_\_ === Object.prototype) //test的父为Function 它的原形链为Object.prototype alert(Function.prototype.\_\_proto\_\_ === Object.prototype) //Object是顶层 所以还是Object.prototype 一个类,如何实例化成一个对象了,类里面的prototype里的属性又是怎么成为实例里面的属性的了 这里不得不说一下new 的过程 大概可以分成3步 <1> var p=\{\}; 也就是说,初始化一个对象p。 <2> p.\_\_proto\_\_=Person.prototype; <3> Person.call(p);也就是说构造p,也可以称之为初始化p。 别人给的一个new的过程 /\* new操作原理(spiderMonkey引擎下) \*/ var a = function(sA,sH)\{ var x = "x"; this.a = sA; this.h = sH; this.say = function()\{alert(this.a+','+x)\} \} a.prototype.hi = function()\{alert(this.h)\} var createInstance = function(source)\{ var p = \{\} var args = Array.prototype.slice.call(arguments,1); source.apply(p,args); p.\_\_proto\_\_ = source.prototype; return p; \} var A = createInstance(a,"A","hi A"); A.say(); A.hi(); 如一个类 ,new 之后的对象如下 function test()\{ this.name="taozi"; \} test.prototype=\{ sex : "nan" \} var ss = new test(); /\* ss就相当于 \{ name : "taozi", \_\_proto\_\_ : \{sex : "nan"\} \} \*/ //可以测试一下 alert('-----------我是华丽的分割线'); alert(ss.\_\_proto\_\_ === test.prototype); //记得在firefox下测试 ie下无法访问到\_\_proto\_\_ 可以看到弹出来的是true 每个对象在初始化的时候都会 \_\_proto\_\_有这么一个属性; 它指向的是父的原型 即Object.prtotype; 如: (请在firefox下测试) var test =\{\}; alert(test.\_\_proto\_\_); alert(test.\_\_proto\_\_.a); //出现的是undefined Object.prototype.a = "test"; alert(test.\_\_proto\_\_.a); //test 当有一个对象 假如是test ;查找他的a属性,如果找不到,那么他就会去\_\_proto\_\_里找这个属性,如果还找不到,就会到\_\_proto\_\_的\_\_proto\_\_中去找,这样一直找啊找,直到没有\_\_proto\_\_为止,这就是传说中的原型链. 下面是一个例子; Object.prototype.obj = "A"; function test()\{ this.obj = "C"; \}; test.prototype.obj ="B"; var ss = new test(); /\* ss可以看成 \{ obj :"C", \_\_proto\_\_ : \{obj : "B",\_\_proto\_\_ :\{ obj :"A" \}\} \} \*/ alert(ss.obj) //可以弹出来的是C delete ss.obj; /\* ss可以看成 \{ \_\_proto\_\_ : \{obj : "B",\_\_proto\_\_ :\{ obj :"A" \}\} \} \*/ alert(ss.obj); //可以看到弹出的是B delete test.prototype.obj; /\* ss可以看成 \{ \_\_proto\_\_ : \{\_\_proto\_\_ :\{ obj :"A" \}\} \} \*/ alert(ss.obj); //可以看出弹出的是A了 另外一个例子 (自己动手修改prototype.\_\_proto\_\_的指向) Object.prototype.id = 0; function test1()\{\} function test2()\{\} function test3()\{ this.id = 7; \} test1.prototype =\{ id : 4, \_\_proto\_\_ : \{ id : 3, \_\_proto\_\_ :\{ id : 2, \_\_proto\_\_ :\{ id : 1 \} \} \} \} test2.prototype.id = 5; test3.prototype.id = 6; test2.prototype.\_\_proto\_\_ = test1.prototype; test3.prototype.\_\_proto\_\_ = test2.prototype; var wt = new test3(); alert(wt.id) delete wt.id alert(wt.id) delete test3.prototype.id alert(wt.id) delete test3.prototype.\_\_proto\_\_.id alert(wt.id) delete test3.prototype.\_\_proto\_\_.\_\_proto\_\_.id alert(wt.id) delete test3.prototype.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.id alert(wt.id) delete test3.prototype.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.id alert(wt.id) delete test3.prototype.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.\_\_proto\_\_.id alert(wt.id) 知道了原型链,那也就知道了为什么现在写类都把公共的方法写在原型上,因为可以节省资源嘛..哈哈
还没有评论,来说两句吧...