经典继承的一个疑问

<script>
    function Animal(age)
    {
        this.age = age;
    }
    Animal.prototype = {
        constructor:Animal,
        bark:function(){
            alert(this+'is barking');
        }
    }
    //....
    function extend(){
            var F = new Function();
            F.prototype = Animal.prototype;
            Dog.prototype = new F();
            //还原子类构造器
            Dog.prototype.constructor = Dog;
        };
    extend();
    function Dog(sex,age)
    {
        this.sex = sex;
        Animal.call(this,age);

        
    }
    dog = new Dog('boy','23');
    console.log(dog.sex + dog.age );
    dog.bark();
</script>

图片描述

此处的代码为什么要生成 F这一个空函数作为一个临时中转,不直接使用 Dog.prototype = Animal.prototype呢?

阅读 3k
5 个回答

你直接把Dog.prototype = Animal.prototype,这时假如我的Dog.prototypeAnimal.prototype指向的是同一片内存,那么就意味着一个改变就会影响另外一个,所以采取这种方式,为Dog.prototype重新开辟内存。

关于js的继承,实现的方式有几种,最好不要去对应面向对象诸如Java,C#之类的继承(而且,现在很多的前端框架都在弱化继承,因为js是基于原型的)。

我也写过一个js的继承(部分代码):

pm.extend=function(sp,ext){
    //
    if(!utils.isFunction(sp)){
        
        return utils.extend.apply(this,slice.call(arguments,0));
    }
    var F=function(){
        
        //call the constructor
        F.superclass.constructor.apply(this,slice.call(arguments,0));          
    };
    
    //
    F.prototype=new sp();
    //
    utils.extend(F.prototype,ext);
    //
    F.prototype.constructor=sp;
    
    sp=ext.constructor !=ObjectProto.constructor ? ext.constructor : sp.prototype.constructor;
    F.superclass=sp.prototype;
    if(F.prototype.constructor === ObjectProto.constructor){
        
        F.prototype.constructor=F;
    }
    
    return F;
};

js的继承会导致出现几个问题,constructor改变,prototype指向出现问题,通过instanceof得不到你想要的继承关系等。

你这里,那个F函数就是为了解决prototype指向的问题的(可以看看相关的书籍,在这里推荐一下月影的《JavaScript王者归来》)

对于js的继承这个东东,建议还是停留在学习,了解上,可以看看一些常见的面向对象的js的设计,比如Extjs(这个用于学习js相关的很有用),Dojo等。

如果父子的 prototype 都指向一个相同的对象,如果子对象的 prototype 的属性被修改,那么就会影响到父对象。所以用一个中介 new F() 来改变这个情况。

直接使用 Dog.prototype = Animal.prototype
这样的话,Dog.prototype更改了,则会引起Animal.prototype更改,这肯定不合你的要求吧?

现在也可以使用Object.create实现继承,dog.prototype=Object.create(animal.prototype)不会造成dog.prototype和animal.prototype指向同一片内存的情况。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题