当我写出这段代码时,恍然大悟!!!

bbjbepzz 2012-12-25 09:26:21

function Animal(){
}
Animal.prototype = {
group : '',
gender : '',
eat : function(){
return 'Yum , food! nom nom';
},
sleep : function(){
return 'zzzzzz...';
}
}
function Bird(){
}
function extend(subClass,superClass){
/*声明一个空构造函数*/
function fn(){}
/*将空函数原型指向父类,这样fn就有了superClass成员了,fn是为下面子类继承做准备用的。*/
fn.prototype = superClass.prototype;
/*将子类的原型指向空函数的实例*/
subClass.prototype = new fn();
/*因为前面改变了子类构造函数的原型会影响constructor属性(指向Object了),所以重新指定一下子类的constructor属性*/
subClass.prototype.constructor = subClass;
/*添加一个属性,保存子类的父类构造函数*/
subClass.baseConstructor = superClass;
/*添加一个属性,保存子类的父类构造函数原型*/
subClass.__super__ = superClass.prototype;
}
extend(Bird , Animal);
var bird = new Bird();
console.log(bird.eat());

今天在书上看到这段代码,自己动手试了下,运行成功后,感觉这代码有点眼熟,然后打开Extjs的ext-all-debug.js源码,找到extend方法。果然神似,曾经看的头晕的代码,今天终于明白了,发帖来跟大家分享下,加了点注释,不对的地方希望大家拍砖指正,谢谢。
...全文
231 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
bbjbepzz 2012-12-26
  • 打赏
  • 举报
回复
引用 4 楼 lzpggg 的回复:
JavaScript code?123456789101112131415161718192021222324252627282930313233343536373839404142extend : function(){ // inline overrides var io = function(o){ for(var m in o){ ……
引用错了 我说像的是继承的那几段代码,Extjs的extend方法还给子类添加静态方法:override,实例方法:override,extend。还有其它一些。
bbjbepzz 2012-12-26
  • 打赏
  • 举报
回复
引用 3 楼 JParser 的回复:
JavaScript code?12345678910111213function extend(subClass,superClass){ if(Object.create){ subClass.prototype=Object.create(superClass.prototype,{}); } else{ functio……
我说像的是继承的那几段代码,Extjs的extend方法还给子类添加静态方法:override,实例方法:override,extend。还有其它一些。
bbjbepzz 2012-12-26
  • 打赏
  • 举报
回复
引用 楼主 bbjbepzz 的回复:
JavaScript code?12345678910111213141516171819202122232425262728293031function Animal(){}Animal.prototype = { group : '', gender : '', eat : function(){ return 'Yum , food!……
上面这些代码是按书上打的。原型继承也确实存在这个问题,如果数据类型是引用型的,比如:[],{},一个对象修改后,其它对象也会修改。 所以一般用组合继承,prototype加apply或call。把方法写在原型上,属性写在构造函数里面。 如下:

function Animal(group,gender,walk){
	this.group = group;
	this.gender = gender;
	this.walk = walk;
}
Animal.prototype = {
	eat : function(){
		return 'Yum , food! nom nom';
	},
	sleep : function(){
		return 'zzzzzz...';
	}
}
function Bird(group,gender,walk){
	Animal.call(this,group,gender,walk);
}
function Person(group,gender,walk){
	Animal.call(this,group,gender,walk);
}
function extend(subClass,superClass){
	/*声明一个空构造函数*/
	function fn(){}
	/*将空函数原型指向父类,这样fn就有了superClass成员了,fn是为下面子类继承做准备用的。*/
	fn.prototype = superClass.prototype;
	/*将子类的原型指向空函数的实例*/
	subClass.prototype = new fn();
	/*因为前面改变了子类构造函数的原型会影响constructor属性(指向Object了),所以重新指定一下子类的constructor属性*/
	subClass.prototype.constructor = subClass;
	/*添加一个属性,保存子类的父类构造函数*/
	subClass.baseConstructor = superClass;
	/*添加一个属性,保存子类的父类构造函数原型*/
	subClass.__super__ = superClass.prototype;
}
extend(Bird , Animal);
extend(Person , Animal);
var bird = new Bird('aa','bb',{method:'walk'});
var person = new Person('cc','dd',{method:'xxx'});
bird.walk.method = "fly";
console.log(person.walk.method);
lzpggg 2012-12-26
  • 打赏
  • 举报
回复

extend : function(){
    // inline overrides
    var io = function(o){
      for(var m in o){
        this[m] = o[m];
      }
    };
    var oc = Object.prototype.constructor;

    return function(sb, sp, overrides){
      if(typeof sp == 'object'){
        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;
      sbp = sb.prototype = new F();
      sbp.constructor=sb;
      sb.superclass=spp;
      if(spp.constructor == oc){
        spp.constructor=sp;
      }
      sb.override = function(o){
        Ext.override(sb, o);
      };
      sbp.superclass = sbp.supr = (function(){
        return spp;
      });
      sbp.override = io;
      Ext.override(sb, overrides);
      sb.extend = function(o){
        return Ext.extend(sb, o);
      };
      return sb;
    };
  }()
这是100%的extjs 3.3.1的扩展函数,你看看有什么区别!
JParser 2012-12-26
  • 打赏
  • 举报
回复

function extend(subClass,superClass){
    if(Object.create){
        subClass.prototype=Object.create(superClass.prototype,{});
    }
    else{
        function fn(){}
        fn.prototype = superClass.prototype;
        subClass.prototype = new fn();
    }
    subClass.prototype.constructor = subClass;    
    subClass.baseConstructor = superClass;
    subClass.__super__ = superClass.prototype;    
}
豪情 2012-12-26
  • 打赏
  • 举报
回复

/*将子类的原型指向空函数的实例*/
    subClass.prototype = new fn();
为什么要new fn(),直接fn.prototype 不行吗?new fn()是直接继承自fn.prototype
Pliman 2012-12-25
  • 打赏
  • 举报
回复
空函数继承,很好... 我来个:
function Animal(){
        }
        Animal.prototype = {
            group : '',
            gender : '',
            eat : function(){
                return 'Yum , food! nom nom';
            },
            sleep : function(){
                return 'zzzzzz...';
            },
            walk : {
                "method" : "walk"
            }
        }
        function Bird(){
        }
        function Person(){
        }
        function extend(subClass,superClass){
            /*声明一个空构造函数*/
            function fn(){}
            /*将空函数原型指向父类,这样fn就有了superClass成员了,fn是为下面子类继承做准备用的。*/
            fn.prototype = superClass.prototype;
            /*将子类的原型指向空函数的实例*/
            subClass.prototype = new fn();
            /*因为前面改变了子类构造函数的原型会影响constructor属性(指向Object了),所以重新指定一下子类的constructor属性*/
            subClass.prototype.constructor = subClass;
            /*添加一个属性,保存子类的父类构造函数*/
            subClass.baseConstructor = superClass;
            /*添加一个属性,保存子类的父类构造函数原型*/
            subClass.__super__ = superClass.prototype;
        }
        extend(Bird , Animal);
        extend(Person , Animal);
        var bird = new Bird();
        var person = new Person();

        bird.walk.method = "fly";
        console.log(person.walk.method);
结果是神马呢?不错就是 fly,在使用new 操作符后,内部对象并没有新建拷贝..真令人沮丧... 要小心这种情况带来的程序出错,也算是空函数继承的一个小小bug吧。

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧