我对C#知之甚少,现在我已经开始使用JavaScript
并且在理解基础知识方面遇到了一些问题。
这是我的代码示例:
function BaseFunc(x, y) {
this.X = x;
this.Y = y;
}
function DerivedFunc(x, y, z) {
this.Z = z;
BaseFunc.call(this, x, y);
}
DerivedFunc.prototype = new BaseFunc;
function Test() {
var d = DerivedFunc(1, 2, 3);
var b = new BaseFunc(4, 5);
d.sayHello();
b.sayHello();
}
DerivedFunc.prototype.sayHello = function () {
alert("Result is: " + (this.X + this.Y + this.Z));
}
在上面的代码中,我试图进行继承。
一切看起来都很好,直到我到达BaseFunc.call(this, x, y);
行,这一行应该调用基函数,但在这种情况下this
的用途是什么。
只是为了满足方法call
的签名,它是如何工作的?
第二个问题是,在javascript中我们可以动态添加任何内容,
在我的例子中,我添加了一个sayHello()
属性并为其分配了一个匿名函数。
与DerivedFunc.prototype.sayHello
类似,我是在向BaseFunc
或DerivedFunc
添加属性/方法,因为它已添加到原型中,因此我应该将其添加到BaseFunc
中。但是当我执行上面的代码时,我得到sayHello
未定义的错误。
有人可以向我说明出了什么问题吗,谢谢?
答案 0 :(得分:1)
一切看起来都很好,直到我到达BaseFunc.call(this,x,y);这一行应该调用基函数,但在这种情况下使用它是什么。
这是因为在BaseFunc
的调用中,this
具有与调用DerivedFunc
时相同的值,因此行this.X = x;
等等BaseFunc
正在分配给正确的实例。 (调用函数设置this
的特定值是函数的.call
和.apply
方法的作用。)
但是当我执行上面的代码时,我得到的错误是,没有定义Hello。
如果您d.sayHello
遇到麻烦,那是因为您错过了new
行d = DerivedFunc(1, 2, 3);
运营商。由于DerivedFunc
仅在作为函数调用而不是通过new
调用时,没有任何返回值,d
将为undefined
。
请注意,您进行继承的方式虽然很常见但却存在问题。主要问题在于:
DerivedFunc.prototype = new BaseFunc;
您正在尝试使用一个旨在创建实例的函数,并接受参数,以便创建DerivedFunc
将分配给事物的原型实例。那么BaseFunc
应该对缺少的论点做些什么呢?然后,再次将其称为 (来自DerivedFunc
)以初始化实例。 BaseFunc
正在履行双重职责。
以下是您如何更正,首先是冗长的版本:
function x() { }
x.prototype = BaseFunc.prototype;
DerivedFunc.prototype = new x;
DerivedFunc.prototype.constructor = DerivedFunc;
或者,如果您可以依赖ES5的Object.create
:
DerivedFunc.prototype = Object.create(BaseFunc.prototype);
DerivedFunc.prototype.constructor = DerivedFunc;
现在我们没有调用BaseFunc
来创建原型,但我们仍然将其prototype
对象作为DerivedFunc
的{{1}}对象的基础原型。我们不再知道如何处理prototype
的参数,并且BaseFunc
仅以其被设计为被调用的方式调用:初始化单个实例,而不是原型。
当然,不是每次我们想要派生构造函数都写那个,而是有一个帮助脚本。
如果您对JavaScript继承层次结构感兴趣,您可能需要查看我的简短Lineage
脚本 - 不一定要使用,而是要了解这些内容的工作原理。 page showing how to do things without the script与使用脚本进行比较可能特别有用。
答案 1 :(得分:0)
嗨,请仔细阅读以下内容。我希望它能让你对继承和call()
有所了解<script type="text/javascript">
//inheritence
function parent() {
this.add = function (a, b) {
return a + b;
}
this.subtract = function (a, b) {
return a - b;
}
}
function child() {
this.display = function () {
alert(this.add(11, 23));
}
}
child.prototype = new parent(); //child extends parent.... inheritence
child.prototype.constructor = child; //resetting constructor property
var obj = new child();
obj.display();
/*
.call() and .apply()
They allow our objects to borrow methods from other objects and invoke them as their own
*/
var person = {
name: 'Kundan',
display: function(name) {
alert(this.name + ' welcomes ' + name);
}
};
person.display('Dipa'); //Kundan welcomes Dipa
var person1 = { name: 'Java Master' };
person.display.call(person1, 'Sachin'); //Java Master welcomes Sachin
//here person1 object is passed in the call function
//if we are using call inside a function and want to pass the same function object then this is passed in call function
/*
We can pass more parameters as follows
person.display.call(person1, 'a', 'b', 'c');
The method apply() works the same way as call() but with the difference that all parameters you want to pass to the method of the other object are passed as an array.
*/
person.display.apply(person1, ['a', 'b', 'c']);
</script>