我正在学习javascript中的课程,并且我正在运行以下代码 这是main.js
var dog1 = new Dog("a",1);
var dog2 = new Dog("b",2);
dog1.howl();
dog1.howl = function(){
console.log("test");
};
dog2.howl();
dog1.howl = null;
dog1.howl();
这是Dog.js子类
function Dog (name,legs) {
Animal.call(this,name);
this.legs = legs;
}
Dog.prototype = Object.create(Animal.prototype);
//Dog.prototype.constructor = Dog;
Dog.prototype.howl = function(){
console.log("woef"+ this.name + " :" + this.legs);
};
最后是Animal.js,这是超类
function Animal(name){
this.name = name;
}
Animal.prototype.howl = function(){
console.log("i can only howl"+ this.name);
};
我期望得到的结果是
woefa :1
test
i can only howla
但我得到了
woefa :1
woefb :2
Main.js:11 Uncaught TypeError: dog1.howl is not a function
我希望通过删除函数对象委托将调用超类中的howl函数,但显然不会发生这种情况。
我犯的错误是什么?问题的解决方案代码是什么?
答案 0 :(得分:0)
因为在dog1.howl = null;
中您只是将嚎叫设置为null
,而不是将其删除,所以当您在dog1.howl();
javascript中尝试将null
作为函数调用时,由于null
不起作用,它会抛出该错误。
逐行描述:
var dog1 = new Dog("a",1);
var dog2 = new Dog("b",2);
dog1.howl(); // It'll use its prototype's howl, which will howls woefa :1
dog1.howl = function(){
console.log("test");
};
dog2.howl(); // new howl function defined for dog1 will only affect dog1, so dog2 still howls : woefb :2
dog1.howl = null; // Assign null to howl property.
dog1.howl(); // As null is not function, error is throw.
你应该做的是
// Remove dog1's howl property from itself, so now it'll use the prototypes'howl function.
delete dog1.howl;
如果你想让dog1嚎叫到i can only howla
,你必须让动物的嚎叫功能可见,因为首先会找到Dog.prototype.howl,你需要删除Dog .prototype的嚎叫(导致所有的狗现在像动物一样嚎叫)或创造一个新的嚎叫,它遍历到可以嚎叫的原始对象:
function Animal(name){
this.name = name;
}
Animal.prototype.howl = function(){
console.log("i can only howl"+ this.name);
};
function Dog (name,legs) {
Animal.call(this,name);
this.legs = legs;
}
Dog.prototype = Object.create(Animal.prototype);
//Dog.prototype.constructor = Dog;
Dog.prototype.howl = function(){
console.log("woef"+ this.name + " :" + this.legs);
};
var dog1 = new Dog("a",1);
var dog2 = new Dog("b",2);
dog1.howl();
console.log('howl before set:', dog1.howl === dog2.howl); // This would be true, as they both reference to their prototype.
dog1.howl = function(){
console.log("test");
};
// This would always be true, as you have same prototype.
console.log(dog1.__proto__.howl === dog2.__proto__.howl);
// This would be false, as dog1 now use a new assigned one, while dog2 use the prototype one.
console.log('howl after set:', dog1.howl === dog2.howl);
dog2.howl();
delete dog1.howl;
console.log("howl after delete:", dog1.howl === dog2.howl); // This would be true
// Make all the dogs able to howl like animal..
Dog.prototype.originHowl = function() {
var current = this;
var parent = Object.getPrototypeOf(current);
// Traverse up prototype chain and break until the parents can't howl.
while(parent.howl && parent.howl instanceof Function) {
current = parent;
parent = Object.getPrototypeOf(current);
}
current.howl.call(this);
};
dog1.originHowl();