Javascript 需要进行根本性的澄清

Javascript 需要进行根本性的澄清,javascript,Javascript,我懂一点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 T

我懂一点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
有何用途。 它只是为了满足方法
调用
的签名,它是如何工作的

第二个问题是,在javascript中,我们可以动态添加任何内容, 在我的例子中,我添加了一个
sayHello()
属性,并用匿名函数分配它。 像
DerivedFunc.prototype.sayHello
,我是在
BaseFunc
DerivedFunc
中添加一个属性/方法,当它添加到prototype中时,我理解它应该添加到
BaseFunc
。但是当我执行上面的代码时,我得到一个错误,
sayHello
没有定义

有人能告诉我出了什么问题吗,谢谢

在我到达基线函数调用(this,x,y)之前,一切看起来都很好;这一行应该调用基函数,但是在这个上下文中它有什么用途呢

它的存在使得在对
BaseFunc
的调用中,
this
具有与调用
DerivedFunc
中相同的值,因此行
this.X=X
BaseFunc
中的这些正在分配给正确的实例。(调用函数设置
的特定值是
.call
.apply
函数方法所做的。)

但是当我执行上面的代码时,我得到一个错误,sayHello没有定义

如果您遇到问题的地方是
d.sayHello
,那是因为您错过了
d=DerivedFunc(1,2,3)行上的
new
操作符。由于
DerivedFunc
仅作为函数而不是通过
new
调用时没有任何返回值,
d
未定义


请注意,您执行继承的方式虽然很常见,但也存在一些问题。主要问题是:

DerivedFunc.prototype = new BaseFunc;
您试图使用一个设计用于创建实例的函数,该函数接受参数,以便创建
DerivedFunc
将分配给对象的原型实例。那么,
BaseFunc
应该如何处理缺少的参数?然后,再次调用它(从
DerivedFunc
)来初始化实例
BaseFunc
正在执行双重任务

下面是您如何纠正的,首先是冗长的版本:

function x() { }
x.prototype = BaseFunc.prototype;
DerivedFunc.prototype = new x;
DerivedFunc.prototype.constructor = DerivedFunc;
或者如果您可以依赖ES5的
对象。创建

DerivedFunc.prototype = Object.create(BaseFunc.prototype);
DerivedFunc.prototype.constructor = DerivedFunc;
现在我们没有调用
BaseFunc
来创建原型,但是我们仍然将其
prototype
对象作为
DerivedFunc
prototype
对象的底层原型。我们不再存在如何处理
BaseFunc
的参数的问题,而且
BaseFunc
的调用方式只是按照其设计的方式:初始化单个实例,而不是原型

当然,不是每次都要编写派生构造函数,而是要为它编写一个助手脚本


如果您对JavaScript继承层次结构感兴趣,您可能想看看我的简短脚本——不一定是为了使用,而是为了了解这些东西是如何工作的。与使用脚本执行这些操作相比,使用和比较可能特别有用。

您好,请完成以下操作。我希望它能给你一些关于继承和调用()的想法


//继承
函数父函数(){
this.add=函数(a,b){
返回a+b;
}
this.subtract=函数(a,b){
返回a-b;
}
}
函数子(){
this.display=函数(){
警觉(本条增补第(11、23)款);
}
}
child.prototype=新父级()//子扩展父。。。。继承
child.prototype.constructor=child//重置构造函数属性
var obj=新的子对象();
obj.display();
/*
.call()和.apply()
它们允许我们的对象从其他对象借用方法,并将它们作为自己的方法调用
*/
个人变量={
名称:“昆丹”,
显示:功能(名称){
警报(this.name+‘欢迎’+name);
}
};
个人显示(“Dipa”)//昆丹欢迎迪帕
var person1={name:'Java Master'};
person.display.call(person1,'Sachin')//爪哇大师欢迎萨钦
//这里person1对象在调用函数中传递
//如果我们在函数中使用call,并且希望传递相同的函数对象,那么这将在call函数中传递
/*
我们可以传递更多参数,如下所示
person.display.call(person1'a',b',c');
方法apply()的工作方式与call()相同,但不同之处在于要传递给另一个对象的方法的所有参数都作为数组传递。
*/
person.display.apply(person1,['a','b','c']);

var d=DerivedFunc(1,2,3)这是反对在his中使用JavaScript中的“类”的原因之一:它的语法正确,没有引发错误,但您可能没有得到您想要的。实际上,您可能指的是
var d=new-DerivedFunc(1,2,3)
@Passerby:有一百万个编程错误在语法上是正确的,不会引起错误,但它们并没有达到程序员的预期效果。我不知道为什么人们会如此痴迷于这一点,它并不比其他人更糟。阅读@shrsh I“将”您的代码“转换”为伪“面向类”代码可能会让您受益匪浅代码:Crowder:谢谢你的回答,先生,我添加了new,它适用于派生,但为什么我不能在BaseFunc上调用sayHello,因为我添加了派生的.prototype.sayH
<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>