越想越糊涂,请高手指点
function A()
{} function B()
{
B.prototype=new A();
} //B.prototype.z=0;
var b=new B();
alert(b.constructor);
B.prototype.z=0;
alert(b.z); //undefined
b=new B();
alert(b.constructor);
alert(b.z);//0
--------------------------
function A()
{} function B()
{
B.prototype=new A();
} B.prototype.z=0;
var b=new B();
alert(b.constructor);alert(b.z); //0
b=new B();
alert(b.constructor);
alert(b.z);//undefined
function A()
{} function B()
{
B.prototype=new A();
} //B.prototype.z=0;
var b=new B();
alert(b.constructor);
B.prototype.z=0;
alert(b.z); //undefined
b=new B();
alert(b.constructor);
alert(b.z);//0
--------------------------
function A()
{} function B()
{
B.prototype=new A();
} B.prototype.z=0;
var b=new B();
alert(b.constructor);alert(b.z); //0
b=new B();
alert(b.constructor);
alert(b.z);//undefined
第一段不说了.
第二段是刚好反过来.
修改B的原型里的属性时
B还是B
所以当第一次NEW的时候B获取的是B的实例.
所以能弹出0
而第一次运行后.
B就变成是A的实例了.
所以当再次NEW的时候返回的是A的实例
结果A的实例中没有z属性
所以undefined
When the [[Construct]] property for a Function object F is called, the following steps are taken:
1. Create a new native ECMAScript object.
2. Set the [[Class]] property of Result(1) to "Object".
3. Get the value of the prototype property of the F.
4. If Result(3) is an object, set the [[Prototype]] property of Result(1) to Result(3).
5. If Result(3) is not an object, set the [[Prototype]] property of Result(1) to the original Object prototype object as described in section 15.2.3.1.
6. Invoke the [[Call]] property of F, providing Result(1) as the this value and providing the argument list passed into [[Construct]] as the argument values.
7. If Type(Result(6)) is Object then return Result(6).
8. Return Result(1).
<script type="text/javascript">function A(){}function B(){B.prototype=new A();/*2*/}
B.prototype.z=0;//1var createInstance = function(source){
var p = {}
var args = Array.prototype.slice.call(arguments,1);
alert(source.prototype.constructor);//1
p.__proto__ = source.prototype;//1
source.apply(p,args);
alert(source.prototype.constructor);//2
return p;
}var A = createInstance(B);
alert(A.z);
</script>
要在FF下测试。另,cloudgamer的原始文档就是ECMA-262文档。
<script type="text/javascript">function A(){}function B(){B.prototype=new A();/*2*/}
B.prototype.z=0;//1var createInstance = function(source){
var p = {}
var args = Array.prototype.slice.call(arguments,1);
alert(source.prototype.constructor);//1
p.__proto__ = source.prototype;//1
source.apply(p,args);
alert(source.prototype.constructor);//2
return p;
}var a = createInstance(B);
alert(a.z);a = createInstance(B);
alert(a.z);
</script>
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
function fn(){}
//the value of implicit [[Prototype]] property of those objects derived from fn will be assigned to fn.prototype
fn.prototype={ attr1:"aaa", attr2:"bbb"};
var obj=new fn();
document.write(obj.attr1 + "<br />"); //result: aaa
document.write(obj.attr2 + "<br />"); //result: bbb
document.write(obj instanceof fn); //result: true
document.write("<br />");
//I change the prototype of fn here, so by the algorithm of Prototype the obj is no longer the instance of fn,
//but this won't affect the obj and its [[Prototype]] property, and the obj still has attr1 and attr2 properties
fn.prototype={};
document.write(obj.attr1 + "<br />"); //result: aaa
document.write(obj.attr2 + "<br />"); //result: bbb
document.write(obj instanceof fn); //result: false--------
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
function CF(q1, q2){
this.q1=q1;
this.q2=q2;
}
CF.P1="P1 in CF";
CF.P2="P2 in CF";
function Cfp(){
this.CFP1="CFP1 in Cfp";
}
CF.prototype=new Cfp();
var cf1=new CF("aaa", "bbb");
document.write(cf1.CFP1 + "<br />"); //result: CFP1 in Cfp
document.write(cf1.q1 + "<br />"); //result: aaa
document.write(cf1.q2 + "<br />"); //result: bbb----------
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
var cf1=new CF("aaa", "bbb");
var cf2=new CF(111, 222);
document.write(cf1.CFP1 + "<br />"); //result: CFP1 in Cfp
document.write(cf2.CFP1 + "<br />"); //result: CFP1 in Cfp
//it will result in a local property in cf1
cf1.CFP1="new value for cf1";
//changes on CF.prototype.CFP1 will affect cf2 but not cf1, because there's already a local property with
//the name CFP1 in cf1, but no such one in cf2
CF.prototype.CFP1="new value for Cfp";
document.write(cf1.CFP1 + "<br />"); //result: new value for cf1
document.write(cf2.CFP1 + "<br />"); //result: new value for Cfp
fn.prototype={ attr1:"aaa", attr2:"bbb"};
var obj=new fn();
document.write(obj.construcor); //undefined
alert(obj.constructor)//function Object{[native code]}----obj.constructor 如果是 fn 的话 ,这样就与 其它构造函数创建的对象的 constructor 一致了,这样不是更完美吗?为什么开发人员要像上面那样设计?其实这是一个钻牛角尖的问题,请 教高手,好让兄弟多明白些道理。谢谢了
在前面的例子中,p1和p2的类型都是Point,在JavaScript中,通过instanceof运算符可以验证这一点: p1 instanceof Point p2 instanceof Point但是,Point不是p1和p2的唯一类型,因为p1和p2都是对象,所以Obejct也是它们的类型.原型模式要求一个类型在一个时刻只能有一个原型(而一个实例在一个时刻显然可以有多个类型)。假如有一个对象,它所属的类型分别为ClassA、ClassB、ClassC和Object,那么必须满足这四个类构成某种完整的原型链,例如
function ClassA(){ ……}ClassA.prototype = new Object(); //这个可以省略function ClassB(){ ……}ClassB.prototype = new ClassA(); //ClassB以ClassA的对象为原型function ClassC(){ ……}ClassC.prototype = new ClassB(); //ClassC以ClassB的对象为原型var obj = new ClassC();alert(obj instanceof ClassC); //truealert(obj instanceof ClassB); //truealert(obj instanceof ClassA); //truealert(obj instanceof Object); //true