1
FrankFang128 2015-07-14 22:21:54 +08:00 via Android 1
每个对象的 __proto__ 属性指向其构造函数的 prototype 属性
方法 function 是一种特殊的对象 Object 琢磨这两句话 constructor 的作用就是指向构造函数。 买本美国人写的JS书看看吧。 |
2
YuJianrong 2015-07-14 22:53:11 +08:00 3
1. 所有函数都是对象,和其他对象区别在于有一个内部成员 [[call]],你调用函数的时候其实就是调用这个成员
2. 所以函数上可以挂任何成员,prototype 是其中之一,一般会挂上一个对象,这时候就叫prototype 原型对象(所以问题一是这是一样的) 3. 当你调用 new FuncA() 的时候,其实做了这些事情 a. 生成一个空对象 {} b. 设置这个空对象的内部成员 [[prototype]] 为 FuncA.prototype ,这个内部成员在v8中是可以访问的__proto__ c. 以这个空对象为 this 调用 FuncA, 即 FuncA.call(this, xxx) 4. 至于 FuncA.prototype.constructor, 对于一个函数的缺省 prototype来说就是函数本身,即 FuncA.prototype.constructor === FuncA 不过这个其实几乎没有任何用处,你大可忽视这个东西。 盗张图: http://www.codeproject.com/KB/scripting/687093/PrototypeGraph.png |
3
Biwood 2015-07-15 00:03:32 +08:00 2
一、为什么函数都有一个原型对象?
因为 JavaScript 里面的任何一个函数都可以作为构造函数使用,所谓构造函数,就是用来构造对象用的函数,使用 new Foo() 操作就能生成一个新的对象,这个新的对象是基于 Foo() 函数的原型对象来生成的,这就是原型对象存在的意义。构造函数在构造一个新对象的过程中需要有一个原型来做参考,这个原型就是构造函数的原型对象。 二、这个 constructor 属性起什么作用? constructor 翻译过来就是构造器,在这里就是指 new 出来的新对象的构造函数,一般我们通过新对象的 constructor 属性可以找到是哪个函数构造了它,这就是 constructor 属性的作用。原型对象上之所以有 constructor 属性,是因为这个属性要继承给新生成的对象,以方便能够找到当前这个构造函数。 |
4
an168bang521 2015-07-15 00:54:30 +08:00 2
[问题一] :这个 Foo( ) 函数怎么会存在 prototype 属性的同时,还有一个 Foo prototype 原型对象?
答:这个要从继承方面来理解的,Jquery就是通过这个继承来搞的,而且这么模式有良好的可扩展性;我的理解是prototype存在的意义就是为了原型链继承;传统的单例模式,工厂模式,就不说了,这个你应该理解的;因为工厂模式,得到的数据,都是一样的,不利于保护私有变量;所以引发出了原型链继承这种模式,这种模式,不仅可以有公有的,也有私有的;Foo这个是属于构造函数,Foo相当于自然界中的类;假设f1,和f2是Foo这个构造函数的两个实例;f1和f2会继承Foo本身包含的字符串;这些继承过来的东西都是私有的,虽然f1和f2里面的内容一样,但是他们并不想等;f1.a!==f2.a;举个例子,就好比我们俩都属于人类(人类相当于构造Foo函数),我们俩都继承了人类这个类的特征,我有一个鼻子两只手,你也有一个鼻子两只手;但是我的手不等于你的手;当然f1和f2也要有相同的属性;这个就是prototype出现的原因,这里还有了解一下,每一个对象都有__proto__这个属性,f1和f2是Foo的是例,函数派生自Object,所以函数上也有__proto__的;换句话说,Foo除了有prototype外,还有__proto__这个属性;在f1和f2的实例中查找不到的时候,会通过f1.__proto__来查询。f1.__proto__指向Foo.prototype开辟的那个内存地址;f1.__proto__===Foo.prototype;同样f2__proto__===Foo.prototype;如果在Foo.prototype定义了一个b方法;f1.__proto__.b===f2.__proto__.b;然后再说下查找顺序。这个如果foo.prototype也没有,会一直找的,直到找到Object这个基类上;如果Object的原型也没有。那就报错了。你也可以在控制台输出console.dir(f1),你把f1详细输出看下,就知道他们是怎么回事了;如果想在Foo扩展公有的东西,可以Foo.prototype={ XX:xx,AA:aa,BB:bb}这样写; 但是上面扩展的虽然可以用,但是有一个例外,就是contructor属性不再指向Foo了;这是因为写函数.prototype的时候,本质上重写了默认的prototype对象;因此 constructor属性也就变成了新对象的 constructor属性,指向Object构造函数了,不再指向Foo;原理就不再继续说了,因为我好不容易才扯到第二个constructor上来的,扯多了就跑远了; [问题] 二:这个 constructor 属性在这里面到底起的是什么作用? 好吧终于从问题一引申到问题二了,这个比较好理解,就是起到当默认指向的改变时候,向上面讲的那个情况下,可以强制写回来;上面的写法可以这样改进: Foo.prototype={ constructor:Foo,XX:xx,AA:aa,BB:bb}这样就妥妥的了; |
5
ariestiger 2015-07-15 01:23:13 +08:00
有没有兴起了解一下这门语言?http://iolanguage.org/
|
6
83f420984 OP |