The function that Extjs implements inheritance is a very core function Ext.extend. The extend method has two reconstructed versions. The first one accepts two parameters, the first one is extend(Function superclass, Object overrides), and the second one is extend(Function superclass, Object overrides). The first is extend(Function subclass, Function superclass,Object overrides): Function, and the second version is based on subclass. Superclass is the constructor of the superclass, overrides is an object, and the attributes inside are to override the attributes of the parent class. A subclass that inherits a parent class has all the methods in the prototype of the parent class. And subclasses can override the methods of the parent class (override). Furthermore, each object of the subclass can also override the methods of the parent class. In fact, I think this function has no effect. The effect of modifying the prototype is equivalent. Of course, the purpose of extjs is to completely shield the magical thing of prototype, so that programmers can process Javascript like other languages. Of course, even so, its inheritance is still somewhat different from ordinary inheritance. Let's take a look at an example first and prepare a Person class:
Person = function(name) { this.name = name; this.fn = function() { alert('I am a person') }; } Person.prototype.print=function(){ alert('I am a person');} Person.prototype.showAge = function() { alert('I am older than 0'); } Person.prototype.showName = function() { alert('Show Name:'+this.name) }; var per = new Person('Tom'); per.showName();子类:Student = function(id) { this.id = id; } Student.prototype.showID = function() { alert(this.id); } //子类的方法
Inheritance:
Ext.extend(Student, Person);
stu.showName(); !!No result! stu has no definition of name stu.fn(); !!No result stu.showID(); !!!Still no result At this point we have discovered some differences: the content in the constructor of the parent class will not be inherited. , the constructor of the parent class will not be called, and the existing methods of the subclass (in prototype) will also be lost! Continue reading and replace the code below Ext.extend with:
var stu = new Student('01'); Student.override({ print: function() { alert('I am a student'); } }); stu.override({ print: function() { alert('I am a bad student,but I won\'t affect others'); } }); stu.print(); stu.showAge(); var stu2 = new Student(); stu2.print();
The functions here can all be output as expected. showAge is the method of the parent class that is executed, and stu.print is specified in stu.override. method, and stu2 executes the method specified in Student.override. At this point, we can roughly guess how extend is implemented. Let’s look at its real source code. This method is located in Ext.js. The code and comments are as follows: extend : function(){
// inline overrides var io = function(o){ //注意这个方法的this,仅看这里并不知道这个this是什么,下面这个io会被赋值给sbp.override,也就是子类的prototype for(var m in o){ //从而每个子类的对象的override都会指向这个方法,如果子类对象调用了override,那么这个this就是子类的对象了。也就是 this[m] = o[m]; //上面的例子中stu.override表现出来的效果,仅对当前对象有效。从这里可以看出,override不仅仅是传统意义上的覆盖,完全也可以 } //用来添加新方法。 }; var oc = Object.prototype.constructor; return function(sb, sp, overrides){ if(Ext.isObject(sp)){ //是在检测当前使用的是哪个版本的重构函数。如果sp实际上是overrides,就做些替换工作,让变量的实际意义和名称相符合。 overrides = sp; sp = sb; sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);}; //这个没看懂…… } var F = function(){}, sbp, spp = sp.prototype; F.prototype = spp; //F是父类的一个“干净”拷贝,所谓干净,是指它不会把父类中在构造函数内部定义的属性带过来。 //例如 Person=function() // {this.privateFn=new function{ some code goes here}} //那么这个privateFn对子类是不可见的,所以在构造函数中利用this定义的属性都相当于是类的私有变量。 sbp = sb.prototype = new F(); //将子类的prototype设置为父类的prototype,继承的核心步骤。 sbp.constructor=sb; //设置正确的构造函数指向,见 JavaScript继承详解 sb.superclass=spp; //设置父类 if(spp.constructor == oc){ //没看懂……,这个是干嘛用的?望高人指点 spp.constructor=sp; } sb.override = function(o){ //子类的重写方法,这个重写方法是函数的重写方法。它修改的是prototype。 Ext.override(sb, o); //见最后。 }; sbp.superclass = sbp.supr = (function(){ //设置原型的父类 return spp; }); sbp.override = io; //给子类的prototype提供override方法,这样单个实体也可以覆盖,它修改的是实体对象。注意和上面的sb的override区分。 Ext.override(sb, overrides); //重写 sb.extend = function(o){return Ext.extend(sb, o);}; //给子类提供extend方法,以实现多重继承 return sb; //返回子类。 }; }();
The following is the code of Ext.override, which is relatively clear, and the inline override In comparison, it is the modified prototype:override:
function(origclass, overrides){ if(overrides){ var p = origclass.prototype; Ext.apply(p, overrides); if(Ext.isIE && overrides.hasOwnProperty('toString')){ // 这个是什么?IE的特殊点? p.toString = overrides.toString; } } }
Now we can start to formally introduce the event model of Extjs. Similar to events in other languages, you must first define an event for a class. Events in other languages (such as C#) generally have a special event type. The event type can actually be regarded as an array of delegates. Of course, the delegate is actually a function. Add The time listener (listener) just wants to add a delegate (function) to the delegate array. The so-called trigger event is to execute all the functions in the array. Javascript is similar, except that Javascript's functions are much more powerful and flexible than those languages, so there is no need for an event type. Javascript events look like a string (it should also retain an array internally). You can add events through the Observale.addEvents method, trigger events through Observale.fireEvent, and add event listeners through Observale.addListner. Here is an example that makes little sense but illustrates the problem.
Odder = function(min, max) { this.min = min; this.max = max; this.addEvents('onFindOdd'); } Ext.extend(Odder, Ext.util.Observable, { run: function() { for (var i = this.min; i < this.max; i++) { if (i % 2 != 0) { this.fireEvent('onFindOdd',i); } } } }); var p = new Odder(4, 8); p.addListener('onFindOdd',function(n){alert(n);}); p.run();
Odder is a class that passes in a range through a constructor, then looks for all odd numbers in the range, and triggers an event every time it finds one. Add an event handler to it to alert the odd numbers it finds. It should be noted that the parameters of the event handler here can only be kept consistent by the programmer. It is not as strongly typed as a delegate.
The above is the detailed content of Detailed explanation of the principle examples of how javascript implements extjs events. For more information, please follow other related articles on the PHP Chinese website!