标签:
reopen不知道怎么翻译了,如果按照reopen翻译过来应该是“重新打开”,但是总觉得不顺,所以就换成“扩展”了。当你想扩展一个类你可以直接使用reopen()方法为一个已经定义好的类添加属性、重写类里的方法。如果是使用extend()方法你需要重新定义一个子类,然后在子类中添加新的属性、方法。
前一篇所过,调用create()方法时候不能传入的参数属性名称必须要跟类成员一致,但是使用reopen()方法可以传入新的参数。与extend()方法非常相似,下面的代码演示了它们的不同之处。
Parent = Ember.Object.extend({ name: ‘ubuntuvim‘, fun1() { console.log("The name is " + this.name); }, common() { console.log("common method..."); } }); // 使用extend()方法添加新的属性、方法 Child1 = Parent.extend({ // 给类Parent为新增一个属性 pwd: ‘12345‘, // 给类Parent为新增一个方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重写父类的common()方法 common() { //console.log("override common method of parent..."); this._super(); } }); var c1 = Child1.create(); console.log("name = " + c1.get(‘name‘) + ", pwd = " + c1.get(‘pwd‘)); c1.fun1(); c1.fun2(); c1.common(); console.log("-----------------------"); // 使用reopen()方法添加新的属性、方法 Parent.reopen({ // 给类Parent为新增一个属性 pwd: ‘12345‘, // 给类Parent为新增一个方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重写类本身common()方法 common() { console.log("override common method by reopen method..."); //this._super(); } }); var p = Parent.create(); console.log("name = " + p.get(‘name‘) + ", pwd = " + p.get(‘pwd‘)); p.fun1(); p.fun2(); p.common(); console.log("---------------------------"); // 使用extend()方法添加新的属性、方法 Child2 = Parent.extend({ // 给类Parent为新增一个属性 pwd: ‘12345‘, // 给类Parent为新增一个方法 fun2() { console.log("The pwd is " + this.pwd); }, // 重写父类的common()方法 common() { //console.log("override common method of parent..."); this._super(); } }); var c2 = Child2.create(); console.log("name = " + c2.get(‘name‘) + ", pwd = " + c2.get(‘pwd‘)); c2.fun1(); c2.fun2(); c2.common();
从执行结果可以看到如下的差异:
同点:
都可以用于扩展某个类。
异点:
extend需要重新定义一个类并且要继承被扩展的类;
reopen是在被扩展的类本身上新增属性、方法;
到底用那个方法有实际情况而定,reopen方法会改变了原类的行为,就如演示实例一样在reopen方法之后调用的Child2类的common方法的行为已经改改变了,在编码过程忘记之前已经调用过reopen方法就有可能出现自己都不知道怎么回事的问题!
如果是extend方法会导致类越来越多,继承树也会越来越深,对性能、调试也是一大挑战,但是extend不会改变被继承类的行为。
使用reopenClass()方法可以扩展static类型的属性、方法
Parent = Ember.Object.extend(); // 使用reopenClass()方法添加新的static属性、方法 Parent.reopenClass({ isPerson: true, // name: ‘123‘ // 不能设置String类型的属性!!!,报Uncaught TypeError: Cannot assign to read only property ‘name‘ }); Parent.reopen({ isPerson: false, name: ‘ubuntuvim‘ }); console.log(Parent.isPerson); console.log(Parent.name); // 输出空 console.log(Parent.create().get(‘isPerson‘)); console.log(Parent.create().get(‘name‘)); // 输出 ubuntuvim
但是有个疑问是reopenClass()新增string类型的属性时候提示不允许!!!官网教程也没说明这个问题,估计是代码有问题。有时间看看是怎么回事……
标签:
原文地址:http://my.oschina.net/u/565401/blog/502325