为什么类方法不能调用其他类方法或它们本身?

时间:2019-07-04 09:19:45

标签: javascript ecmascript-6 ecmascript-2017

我很好奇为什么方法不能在javascript中调用其他方法或它们本身。例如,这会产生一个参考错误,提示未定义添加。

class sum {
  add(x, amt) {
    if(amt == 0) return x
    return add(x+1, amt-1)
  }
}
summer = new sum()
console.log(summer.add(5,5))

您必须改用this.add()。

现在,我知道方法已转换为原型上的函数,但我看不出如何解释我指出的这一局限性?

不能在定义add时引用它本身或其他带有闭包捕获的方法。

为什么这样?

3 个答案:

答案 0 :(得分:3)

@briosheje发表评论时,我正在说明这个缺点:

[
    {
        firstName: "David",
        lastName: "Peter"
    },
    {
        firstName: "David2",
        lastName: "Peter2"
    }
]

答案 1 :(得分:2)

我将尝试使它在理论上“稍微”些,而又不深入文档等。

将代码转换为纯JavaScript即可找到问题的主要答案。为此,您可以使用babel在线或在线打字稿游乐场。 无论哪种情况,转译后的代码都将如下所示:

"use strict";
var sum = /** @class */ (function () {
    function sum() {
    }
    sum.prototype.add = function (x, amt) {
        if (amt == 0)
            return x;
        return add(x + 1, amt - 1);
    };
    return sum;
}());
var summer = new sum();
console.log(summer.add(5, 5));

如您所见,add方法属于 sum 原型,它是函数。因此,您可以猜测访问add范围内的add只是不能隐式导致调用sum.prototype.add函数。

不同地,如果您查看正确代码:

class sum {
  add(x, amt) {
    if(amt == 0) return x
    return this.add(x+1, amt-1)
  }
}
var summer = new sum()
console.log(summer.add(5,5))

您将看到转译的代码将调用this方法:

"use strict";
var sum = /** @class */ (function () {
    function sum() {
    }
    sum.prototype.add = function (x, amt) {
        if (amt == 0)
            return x;
        return this.add(x + 1, amt - 1);
    };
    return sum;
}());
var summer = new sum();
console.log(summer.add(5, 5));

这实际上不是模糊的问题,而是在javascript中允许这种调用,因为add方法可从全局范围隐式获得。能够访问函数作用域中的全局作用域(因为请记住,无论发生什么情况,JavaScript中的class都会始终转译为函数)可以继承函数的标准行为,它可以访问其父级,拥有自己的范围并授予对全局范围的访问权限。

有点好奇:如果您实际上可以使用this.add访问add,则您将无法使用undefined,因为它是全局变量 ,因此您将无法访问和使用它,因为它隐式为this.undefined

因此,再一次,不是含糊不清,而是关于JavaScript 功能如何工作的。

答案 2 :(得分:0)

从根本上讲,Java语言中的OOP与和其他语言非常不同。实际上,没有一个强大的“类”概念。经典的OOP概念(例如Javascript中的类和实例)并非真正来自“类”,而是来自围绕属性查找以及function getTimeZone(UTCText){ document.getElementsByClassName(UTCText); console.log(UTCText) } this关键字的规则。其他所有内容只是函数,对象和属性,其中一些是“特殊的”,例如new

例如您可以像这样组装“类”:

prototype

这里没有真正的凝聚力,function Foo() { this.bar = 42; } function baz() { return this.bar; } Foo.prototype.baz = baz; let foo = new Foo; console.log(foo.baz());本质上不属于任何类,但是像这样组装,它们就像一个类。 baz语法只是这种机制的薄薄表皮。因此,如果您在函数中编写class,它将遵循变量作用域规则,并会在某个范围内查找变量,因此不会在原型上找到方法。