锁定老帖子 主题:javascript面向对象技术基础(五)
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-12-08
类变量/类方法/实例变量/实例方法 function Person(name,age) { //定义方法 this.name = name; this.age = age; } var o = new Object(); //空对象 alert(o.name + "_" + o.age); //undefined_undefined Person.call(o,"sdcyst",18); //相当于调用:o.Person("sdcyst",18) alert(o.name + "_" + o.age); //sdcyst_18 Person.apply(o,["name",89]);//apply方法作用同call,不同之处在于传递参数的形式是用数组来传递 alert(o.name + "_" + o.age); //name_89 --------------------------------- 实例变量和实例方法都是通过实例对象加"."操作符然后跟上属性名或方法名来访问的,但是我们也可以为类来设置方法或变量, Person.counter = 0; //定义类变量,创建的Person实例的个数 function Person(name,age) { this.name = name; this.age = age; Person.counter++; //没创建一个实例,类变量counter加1 }; Person.whoIsOlder = function(p1,p2) { //类方法,判断谁的年龄较大 if(p1.age > p2.age) { return p1; } else { return p2; } } var p1 = new Person("p1",18); var p2 = new Person("p2",22); alert("现在有 " + Person.counter + "个人"); //现在有2个人 var p = Person.whoIsOlder(p1,p2); alert(p.name + "的年龄较大"); //p2的年龄较大
prototype属性的应用: function Circle(radius) { this.radius = radius; this.area = function() { return 3.14 * this.radius * this.radius; } } var c = new Circle(1); alert(c.area()); //3.14 假设我们定义了100个Circle类的实例对象,那么每个实例对象都有一个radius属性和area方法, function Circle(radius) { this.radius = radius; } Circle.prototype.area = function() { return 3.14 * this.radius * this.radius; } var c = new Circle(1); alert(c.area()); //3.14
现在,让我们用prototype属性来模拟一下类的继承:首先定义一个Circle类作为父类,然后定义子类 function Circle(radius) { //定义父类Circle this.radius = radius; } Circle.prototype.area = function() { //定义父类的方法area计算面积 return this.radius * this.radius * 3.14; } function PositionCircle(x,y,radius) { //定义类PositionCircle this.x = x; //属性横坐标 this.y = y; //属性纵坐标 Circle.call(this,radius); //调用父类的方法,相当于调用this.Circle(radius),设置PositionCircle类的 //radius属性 } PositionCircle.prototype = new Circle(); //设置PositionCircle的父类为Circle类 var pc = new PositionCircle(1,2,1); alert(pc.area()); //3.14 //PositionCircle类的area方法继承自Circle类,而Circle类的 //area方法又继承自它的prototype属性对应的prototype对象 alert(pc.radius); //1 PositionCircle类的radius属性继承自Circle类 /* 注意:在前面我们设置PositionCircle类的prototype属性指向了一个Circle对象, 因此pc的prototype属性继承了Circle对象的prototype属性,而Circle对象的constructor属 性(即Circle对象对应的prototype对象的constructor属性)是指向Circle的,所以此处弹出 的是Circ. */ alert(pc.constructor); //Circle /*为此,我们在设计好了类的继承关系后,还要设置子类的constructor属性,否则它会指向父类 的constructor属性 */ PositionCircle.prototype.constructor = PositionCircle alert(pc.constructor); //PositionCircle 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-12-09
最后修改:2008-12-09
引用 f.call(o, 1, 2);
作用就相当于 o.m = f; o.m(1,2); delete o.m; 在这里,我不敢苟同。 请用firebug调试器调试。调试时在f函数中设下断点,检查this对象,是否已经具有了o对象中的属性。 具体如何归纳总结,我想到时你心中有数。 在你后来的例子中由于你的o与f中的属性相同,给你了不全面的归纳总结 请楼主,执行下面的语句。 function f(a,b){ alert(a+''+b+''); alert(this.x); } var o={}; o.a='3'; o.x='d'; f.call(o,1,2); alert("====="); 当上面执行后,你会发现f原本没有x属性,在这里居然有了x属性,其次还是"d". 将发现产生三次消息提示框。依次为: 12 d ===== |
|
返回顶楼 | |
发表时间:2008-12-09
按照某些人的做法,应该让你的这篇网文投一新手贴。 理由:会误导新手,把更多新手拉入阴沟。我这种新手都能发现错误。 转眼一想:论坛,是讨论的地方,难道就只能出最正确最完美的东东吗? 难道不允许在讨论中,发现问题、纠正问题、加深理解、完善总结吗? 不说了,我要进行我的桌面布局管理器了。在这里借楼主的贴,发点牢骚 。对 楼主说声Sorry! |
|
返回顶楼 | |
发表时间:2008-12-09
非常感谢您的意见,不过在这里我还是要坚持自己的观点:
我还是以你的例子为基础进行辩驳: function f(a,b){ alert(a+'_'+b); alert(this.x); } f(2,3); //2_3 undefined var o={}; o.a='3'; o.x='d'; f.call(o,1,2); //1_2 d /** 下面的例子是根据文章中提到的模拟call的作用 */ o.m = function(a,b) { alert(a+'_'+b); alert(this.x); } o.m(1,2); //1_2 d delete o.m; 希望你能帮我解释一下上面的例子和文章中的内容有什么冲突. |
|
返回顶楼 | |
发表时间:2008-12-09
yunhaifeiwu 写道 按照某些人的做法,应该让你的这篇网文投一新手贴。理由:会误导新手,把更多新手拉入阴沟。我这种新手都能发现错误。转眼一想:论坛,是讨论的地方,难道就只能出最正确最完美的东东吗?难道不允许在讨论中,发现问题、纠正问题、加深理解、完善总结吗?不说了,我要进行我的桌面布局管理器了。在这里借楼主的贴,发点牢骚 。对楼主说声Sorry! 我真的希望你能给我指出错误之处,我好改正以免误导大家.说实话,写这样的东西我自己都没 有谱,而且很多东西我是按照原书的内容翻译后自己理解,如果出错的话我一定会改正过来,再次感谢!! |
|
返回顶楼 | |
发表时间:2008-12-09
最后修改:2008-12-09
sdcyst 写道 非常感谢您的意见,不过在这里我还是要坚持自己的观点:
我还是以你的例子为基础进行辩驳: function f(a,b){ alert(a+'_'+b); alert(this.x); } f(2,3); //2_3 undefined var o={}; o.a='3'; o.x='d'; f.call(o,1,2); //1_2 d /** 下面的例子是根据文章中提到的模拟call的作用 */ o.m = function(a,b) { alert(a+'_'+b); alert(this.x); } o.m(<script type="text/javascript" src="http://www.iteye.com/javascripts/tinymce/themes/advanced/langs/zh.js"></script><script type="text/javascript" src="http://www.iteye.com/javascripts/tinymce/plugins/javaeye/langs/zh.js"></script>1,2); //1_2 d delete o.m; 希望你能帮我解释一下上面的例子和文章中的内容有什么冲突. 测试了,你的这种也是正确的。从中受教了。感谢中! |
|
返回顶楼 | |
发表时间:2008-12-09
yunhaifeiwu 希望不要给自己挖坑, 楼主是欢迎讨论的. 你有问题可以指出. 我想楼主这么耐心地在这一系列每个贴里都有耐心的回答. 决不会排斥异议的.
|
|
返回顶楼 | |
发表时间:2008-12-09
srdrm 写道 yunhaifeiwu 希望不要给自己挖坑, 楼主是欢迎讨论的. 你有问题可以指出. 我想楼主这么耐心地在这一系列每个贴里都有耐心的回答. 决不会排斥异议的.
首先申明:没有针对楼主。到javascript是因为高手多,从中学习来着。学习过程,不可能不出现理解性的偏差,发现了及时纠正过来罢了。 |
|
返回顶楼 | |
发表时间:2008-12-09
yunhaifeiwu 写道 测试了,你的这种也是正确的。从中受教了。感谢中! f.call(o, 1, 2); 作用就相当于 o.m = f; o.m(1,2); delete o.m; 上面这个例子是原文中的,后来我测试的时候也是这样.你可以找到原书看一下. 我非常害怕自己的帖子会对别人产生误导,所以非常感谢你的意见. 扣个字眼:你在回复中说,"你的这种测试也是正确的",但是我还是没弄明白你原来 想要表达的意思,包括你觉得那个例子. |
|
返回顶楼 | |
发表时间:2008-12-09
sdcyst 写道 yunhaifeiwu 写道 测试了,你的这种也是正确的。从中受教了。感谢中! f.call(o, 1, 2); 作用就相当于 o.m = f; o.m(1,2); delete o.m; 上面这个例子是原文中的,后来我测试的时候也是这样.你可以找到原书看一下. 我非常害怕自己的帖子会对别人产生误导,所以非常感谢你的意见. 扣个字眼:你在回复中说,"你的这种测试也是正确的",但是我还是没弄明白你原来 想要表达的意思,包括你觉得那个例子. 你说的 引用 f.call(o, 1, 2);
作用就相当于 o.m = f; o.m(1,2); delete o.m; 揭示f.call的含义,这是从等价代码的角度上揭示的。如果用文字进行描述又是怎样的呢? msdn上的描述很准确,很严密,但是理解有点困难。 因此我站到我测试得到的结果,进行总结归纳: f.call(o,1,2)的含义是: 1 调用了函数f .其实际参数是 1,2 2 在f函数执行时也仅在f函数执行时,f中的this参数中具有o中的属性。如果原来有与o相同的属性, 则会被覆盖掉。 申明:以上仅仅是个人对call的自我总结,目的是辅助理解,准确的定义请看相关权威教材。三人行必有 我师,如果有误,请指出,我会及时更正。在技术论坛上,谢绝因观点不一样,而进行人身攻击。 |
|
返回顶楼 | |