Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这种Javascript继承方法是否有问题?_Javascript_Inheritance - Fatal编程技术网

这种Javascript继承方法是否有问题?

这种Javascript继承方法是否有问题?,javascript,inheritance,Javascript,Inheritance,我希望用JavaScript进行一些继承,在搜索inter-webs时,我发现了许多继承的示例、多种方法和实现。我最终找到了一个我喜欢的,因为它很简单,从所有的阅读和学习中,我想出了这个方法: var Animal = function () { var self = this; self.legs = 4; self.makeNoise = function () { return "noise"; }; }; var Dog = functi

我希望用JavaScript进行一些继承,在搜索inter-webs时,我发现了许多继承的示例、多种方法和实现。我最终找到了一个我喜欢的,因为它很简单,从所有的阅读和学习中,我想出了这个方法:

var Animal = function () {
    var self = this;
    self.legs = 4;
    self.makeNoise = function () {
        return "noise";
    };
};

var Dog = function () {
    var self = new Animal();
    self.base = {
        makeNoise: self.makeNoise
    };

    self.makeNoise = function () {
        var noise = "bark \n";
        noise += self.base.makeNoise();

        return noise;
    };

    return self;
};

var Monkey = function () {
    var self = new Animal();
    self.base = {
        makeNoise: self.makeNoise
    };
    self.legs = 2;
    self.makeNoise = function () {
        var noise = "weird monkey sound \n";
        noise += self.base.makeNoise();

        return noise;
    };

    return self;
};

$("#monkey").click(function () {
    var monkey = new Monkey();
    var result = "Legs: " + monkey.legs + "\n";
    result += "Noise: " + monkey.makeNoise();
    alert(result);
});

$("#dog").click(function () {
    var dog = new Dog();
    var result = "Legs: " + dog.legs + "\n";
    result += "Noise: " + dog.makeNoise();
    alert(result);
});
您可以找到一个工作的JSFIDLE


正如您从代码中看到的,我在
base
变量中保留了原始base函数的引用,这样我就可以调用
base
。你认为这种方法有什么不对吗?任何缺点,未来可能出现的问题,我遗漏了什么?

除了返回
self
打破继承链之外,您可能对JavaScript的继承技术有误解:

JavaScript是一种基于原型的语言,这意味着适当的继承设置如下:

function Animal(){}

Animal.prototype.walk = function(){
    console.log('walking...');
};

Animal.prototype.roar = function(){
    alert('roar');
};

function Dog(){}

Dog.prototype = new Animal();

Dog.prototype.roar = function(){
    alert('bark!');
};

var animal = new Animal();
var dog = new Dog();

animal.walk();
dog.walk();   // both can call the walk function

animal.roar(); // alerts roar
dog.roar(); // alerts bark
原型继承允许共享对象定义的内存(将一个对象记录到控制台以了解我的意思)。换句话说,
Dog
的每个实例都将使用相同的
roar
函数,但通过将属性直接附加到构造函数中的
this
,您将阻止原型链,并将函数的内存委派给该对象的每个实例。如果要创建该对象的多个实例,应用程序的性能将反映这一点


@在我的例子中,Thom演示了经典继承与原型的对比。这两种方法都是正确的,但这里有一个好方法。

此外,通过返回
self
打破继承链,您可能会对JavaScript的继承技术产生误解:

JavaScript是一种基于原型的语言,这意味着适当的继承设置如下:

function Animal(){}

Animal.prototype.walk = function(){
    console.log('walking...');
};

Animal.prototype.roar = function(){
    alert('roar');
};

function Dog(){}

Dog.prototype = new Animal();

Dog.prototype.roar = function(){
    alert('bark!');
};

var animal = new Animal();
var dog = new Dog();

animal.walk();
dog.walk();   // both can call the walk function

animal.roar(); // alerts roar
dog.roar(); // alerts bark
原型继承允许共享对象定义的内存(将一个对象记录到控制台以了解我的意思)。换句话说,
Dog
的每个实例都将使用相同的
roar
函数,但通过将属性直接附加到构造函数中的
this
,您将阻止原型链,并将函数的内存委派给该对象的每个实例。如果要创建该对象的多个实例,应用程序的性能将反映这一点


@在我的例子中,Thom演示了经典继承与原型的对比。两者都是对的,但这是一篇好文章。

这是一篇优秀的文章:


这是一篇优秀的文章:


嗯,有一件事是错的:

var dog = new Dog();
console.log(dog instanceof Dog) //=> false
问题是,你所做的实际上不是继承。您只需使用函数返回动物对象的修改版本。这会导致一种类似于继承的行为,但不是一回事

JavaScript的对象模型使用了一种称为原型链的东西,这与典型的面向对象继承非常相似。Mozilla开发者网络有一篇关于这方面的好文章:

下面是一个示例,说明如何在示例中使用原型继承:

var Animal = function() {};
Animal.prototype = {
    legs: 4,
    makeNoise: function () {
        return "noise";
    }
};

var Dog = function () {};
// Notice: Dog.prototype is inheriting from Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.makeNoise = function () {
    var noise = "bark \n";
    // Notice: calling Animal's makeNoise function with
    // 'this' set to our dog object.
    noise += Animal.prototype.makeNoise.call(this);

    return noise;
};

var Monkey = function () {};
// Notice: Monkey.prototype is inheriting from Animal.prototype
Monkey.prototype = Object.create(Animal.prototype)
Monkey.prototype.legs = 2;
Monkey.prototype.makeNoise = function () {
    var noise = "weird monkey sound \n";
    // Notice: calling Animal's makeNoise function with
    // 'this' set to our monkey object.
    noise += Animal.prototype.makeNoise.call(this);

    return noise;
};

$("#monkey").click(function () {
    var monkey = new Monkey();
    var result = "Legs: " + monkey.legs + "\n";
    result += "Noise: " + monkey.makeNoise();
    alert(result);
});

$("#dog").click(function () {
    var dog = new Dog();
    var result = "Legs: " + dog.legs + "\n";
    result += "Noise: " + dog.makeNoise();
    alert(result);
});

$("#inheritance").click(function () {
    var dog = new Dog();
    var monkey = new Monkey();
    var result = 'dog instanceof Dog = ' + (dog instanceof Dog) + "\n" +
        'dog instanceof Animal = ' + (dog instanceof Animal) + "\n" +
        'dog instanceof Monkey = ' + (dog instanceof Monkey) + "\n" +
        'monkey instanceof Monkey = ' + (monkey instanceof Monkey) + "\n" +
        'monkey instanceof Animal = ' + (monkey instanceof Animal) + "\n" +
        'monkey instanceof Dog = ' + (monkey instanceof Dog) + "\n";
    alert(result);
});

好吧,有一件事不对:

var dog = new Dog();
console.log(dog instanceof Dog) //=> false
问题是,你所做的实际上不是继承。您只需使用函数返回动物对象的修改版本。这会导致一种类似于继承的行为,但不是一回事

JavaScript的对象模型使用了一种称为原型链的东西,这与典型的面向对象继承非常相似。Mozilla开发者网络有一篇关于这方面的好文章:

下面是一个示例,说明如何在示例中使用原型继承:

var Animal = function() {};
Animal.prototype = {
    legs: 4,
    makeNoise: function () {
        return "noise";
    }
};

var Dog = function () {};
// Notice: Dog.prototype is inheriting from Animal.prototype
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.makeNoise = function () {
    var noise = "bark \n";
    // Notice: calling Animal's makeNoise function with
    // 'this' set to our dog object.
    noise += Animal.prototype.makeNoise.call(this);

    return noise;
};

var Monkey = function () {};
// Notice: Monkey.prototype is inheriting from Animal.prototype
Monkey.prototype = Object.create(Animal.prototype)
Monkey.prototype.legs = 2;
Monkey.prototype.makeNoise = function () {
    var noise = "weird monkey sound \n";
    // Notice: calling Animal's makeNoise function with
    // 'this' set to our monkey object.
    noise += Animal.prototype.makeNoise.call(this);

    return noise;
};

$("#monkey").click(function () {
    var monkey = new Monkey();
    var result = "Legs: " + monkey.legs + "\n";
    result += "Noise: " + monkey.makeNoise();
    alert(result);
});

$("#dog").click(function () {
    var dog = new Dog();
    var result = "Legs: " + dog.legs + "\n";
    result += "Noise: " + dog.makeNoise();
    alert(result);
});

$("#inheritance").click(function () {
    var dog = new Dog();
    var monkey = new Monkey();
    var result = 'dog instanceof Dog = ' + (dog instanceof Dog) + "\n" +
        'dog instanceof Animal = ' + (dog instanceof Animal) + "\n" +
        'dog instanceof Monkey = ' + (dog instanceof Monkey) + "\n" +
        'monkey instanceof Monkey = ' + (monkey instanceof Monkey) + "\n" +
        'monkey instanceof Animal = ' + (monkey instanceof Animal) + "\n" +
        'monkey instanceof Dog = ' + (monkey instanceof Dog) + "\n";
    alert(result);
});

迁移到使用“new Monkey”的候选函数可能意味着继承,但在该函数中返回除“this”之外的内容意味着没有继承。最好只调用Monkey(),而不使用“new”前缀,以避免读者混淆。JS已有的继承有什么问题?MDN有一篇关于这方面的优秀文章:@DaveNewton你是指原型继承?可能迁移到使用“new Monkey”意味着继承,但返回除“this”之外的内容在这种情况下,函数意味着没有继承。最好只调用Monkey(),而不使用“new”前缀,以避免读者混淆。JS已有的继承有什么问题?MDN有一篇关于这方面的优秀文章:@DaveNewton你是指原型继承?喜欢简单的解释、链接和令人大开眼界的
console.log(dog instanceof dog)
。更好的是,您的代码示例基于我的示例。因此,我接受你的回答!喜欢简单的解释、链接和令人大开眼界的
console.log(dog instanceof dog)
。更好的是,您的代码示例基于我的示例。因此,我接受你的回答!