问题在代码中function Circle(){}
Circle.PI = 3.14;//(1)
Circle.prototype.PI = 3.14;//(2)
//我知道的区别
//(1)的PI不能给Circle的对象直接调用
//var c = new Circle(); c.PI undefined
//(2)的PI能给Circle的对象直接调用
//var c = new Circle(); c.PI == 3.14
//还有其他区别吗?
Circle.PI = 3.14;//(1)
Circle.prototype.PI = 3.14;//(2)
//我知道的区别
//(1)的PI不能给Circle的对象直接调用
//var c = new Circle(); c.PI undefined
//(2)的PI能给Circle的对象直接调用
//var c = new Circle(); c.PI == 3.14
//还有其他区别吗?
什么是原型链?
Circle.PI = 3.14;//(1) 对Circle对象,也就是Function类的实例化对象的一个属性而已
Circle.prototype.PI = 3.14;//(2)function 的原型增加一个属性 ,作用域原型生成的实例化对象都包含这个属性
这个PI是在Circle这个对象的属性,有点类似c#或者Java的静态的变量,对于new Circle()的实例是不起作用的Circle.prototype.PI = 3.14;
这个Pi是设置到Circle的原型上,所有的new Circle() 都共享的,且相互不影响
既然是共享的话应该是相互影响的吧?
Circle.prototype.PI = 3.14;
Circle.prototype.getPI =function(){
alert(this.PI);
};
var c1=new Circle();
c1.getPI(); //输出3.14
var c2=new Circle();
c2.PI=3.1415926;
c2.getPI();//输出3.1415926delete c2.PI;
c2.getPI();
原则是:先找实例,再找原型
第一个因为实例上没有,直接从原型上找 3.14
第二个实例上有,先找实例的3.1415926,然后删除实例的,输出的就是原型上的3.14
@@,你说的那个先找实例,再找原型的我也明白,我现在问的是‘类变量’与prototype的区别,不是问实例变量与prototype的区别
}Person.prototype.name = "ZhangSan";其中Person是类变量
Person.prototype是Person的原型属性Person的原型属性指向Person的原型对象当一个实例var person1 = new Person();
person1.__prototype__.name = "Lisi";改变了Person的原型对象时,那么var person2 = new Person();alert(person2.name); // "Lisi"
每个函数都有一个属性prototype, prototype也是一个对象,当实例化一个函数var c = new Circle()时,会将 Circle函数的引用赋值给实例的constructor属性, 也就是所c.constructor 就是Cirlcle函数, 同时Cirlcle的protorype属性会赋值给实例属性,
PI:3.14
}
"类变量” 的说法其实不准确,PI只是Circle对象的一个属性,还是隐式的,针对的是function
他的实例是不具有这个属性的,而类这个概念来讲,重要的是function() 的过程你问题里面已经提到了,两个东西不是一个体系的
java里面我不知道,但在c#里面
public class A
{
public static string getA()
{
return "A";
}
}public class B
{
public B(){
A a=new A();
string _a=a.getA(); //这是错误的
string _a1=A.getA(); //这是正确的
}
}
}Person.prototype.hand = "人的手";
Person.prototype = {head: "人的头", hand: "人的手"}
简单的说,Circle.PI和Circle.prototype都是Circle的属性,PI是你定义的属性,prototype是内置的属性,可以理解为与生俱来的属性。
prototype属性是一个原型对象,并且规定Circle实例对象从这个原型继承属性和方法,规则就是如此,prototype是JS实现继承的基石。
Circle.prototype.PI所有实例可以共享,而Circle.PI不能,因为并不是从Circle继承,而是从Circle.prototype继承。Circle实例的constructor属性(从Circle.prototype继承而来)指向Circle,所以通过实例也可以调用“静态”属性Circle.PI,殊途同归:
(new Circle).constructor.PI === Circle.PI参考:http://www.mollypages.org/misc/js.mp
但是我觉得你后面的解释靠谱(不是说我觉得靠谱就是对的,不靠谱就是错的,呵呵。只是从个人角度表达的一个观点)
对啊,prototype就是给你用的,你可以给prototype添加属性或方法,然后实例共享这些属性方法,你还纠结什么呢?看看我18楼最后给出的链接:Javascript Object Hierarchy,应该对你理解有帮助。
引用 19 楼 的回复:
我现在的问题是Circle.prototype.PI,这个不是与生俱来的
对啊,prototype就是给你用的,你可以给prototype添加属性或方法,然后实例共享这些属性方法,你还纠结什么呢?看看我18楼最后给出的链接:Javascript Object Hierarchy,应该对你理解有帮助。我个人觉得两者的作用可以说是一样的,是想发个帖问问是不是还有其他的区别,可以学习一下
原理就是:Circle不仅是一个类,也是这个类的一个默认实例化对象.Circle和其它再new出来的实例是兄弟关系(或者说是月饼和月饼的关系),并非父子关系(或者说并非是月饼模子和月饼的关系).所以Circle.PI等于只是给Circle这个类的默认实例增加了属性,对于其它new出来的兄弟实例,只是继承父类的内容,其中不包括你对那个实例增加的属性.
当用 Circle.prototype.PI = 3.14; 时,通过Circle.prototype是找到了真正的父类,给它增加的就将带入所有根据它实例化出来的对象中.Circle.prototype.PI是月饼模子里的花纹,Circle.PI是你在从棋子里扣出来的月饼上自己刻的花纹.就这样的关系和区别.
对于继承来说
function Circle(){}
Circle.PI = 3.14;function test()
{
}
test.prototype = Circle;
var _test=new test();
alert(_test.PI); 这个是可以的,已测
Circle是他本身的默认实例化对象,这个还真不知道,学习了
Circle.PI = 3.14;//(1)你先要搞清楚,上面的并不等同于下面的:
function Circle(){
this.PI=3.14
}
下面的例子就可以看出它们的区别了。function Circle(){
this.PI=1;
}
Circle.PI = 2;
Circle.prototype.PI = 3;
alert(Circle.PI);//2
alert(new Circle().PI);//1跟你说得戏剧化一点:Circle.PI这个是私生子,你自己知道的
Circle.prototype.PI这个是大房生的,摆上台面的,世人都知道的,这个大房生的儿子是死是活,是长圆了还是长扁了,跟私生子一点关系都么有
Circle和其它再new出来的实例是兄弟关系
-----------这个值得商榷。因为Circle和new出来的实例的模子不同,Circle的模子是Function.prototype,new Circle出来的实例模子是Circle.prototype。Circle和new Circle的继承链不同,当然最后都会在Object.prototype汇合。如果说Circle是实例化对象,那它是Function的实例化对象,并非自己的实例化对象。本来JavaScript不是面向对象的语言,用这些概念去套,非驴非马,更像是骡。Circle理解为constroctor,Circle.prototype理解为月饼模子,这样比较合理,个人认为。
如果非要用父子来界定它们之间的关系:var circle = new Circle()
alert(circle instanceof Circle) //trueCircle是喜当爹,属于户口本上的爹,喜当爹可以教会你个性化的属性方法——目濡耳染那必须的。Circle.prototype才是幕后的真爹,你的遗传基因来自它,喜当爹没有教会你的技能,首先问真爹,不会再问真爹的真爹这就是真爹(原型)继承。