为什么 class 方法不能调用其他 class 方法或它们自己?
Why can't class methods call other class methods or themselves?
我很好奇为什么方法不能在javascript中调用其他方法或它们自己。例如,这会产生一个引用错误,指出 add is not defined.
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 被定义时,它可以引用自身或其他带有闭包捕获的方法。
为什么会这样?
当 @briosheje 发表评论时,我正在说明这个缺点:
function add() {
console.log('called the wrong add!');
}
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))
我会尝试使其"slightly"更理论化,而不会深入研究文档等。
您的问题的主要答案可以通过将您的代码转换为普通代码来找到 javascript。为此,您可以使用 babel online 或 typescript online playground。
无论哪种情况,转译后的代码都将如下所示:
"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
总是 转译为函数)允许继承函数的标准行为,即有权访问其父级、拥有自己的作用域并授予对全局作用域的访问权限。
一点好奇心:如果您实际上可以使用 add
访问 this.add
,您将无法使用 undefined
,因为它是一个 全局变量,因此您将无法访问和使用它,因为它隐式为 this.undefined
.
所以,再一次,不是歧义,而是javascript函数如何工作。
从根本上讲,Javascript 中的 OOP 与 java 和其他语言非常不同。 "classes" 实际上并没有很强的概念。 classic OOP 概念,如 classes 和 Javascript 中的实例并不是真正来自 "classes",而是来自 属性 查找和 this
和 new
关键字。其他一切都只是函数、对象和属性——其中一些是 "special",比如 prototype
.
例如你可以 assemble 一个 "class" 这样的:
function Foo() {
this.bar = 42;
}
function baz() {
return this.bar;
}
Foo.prototype.baz = baz;
let foo = new Foo;
console.log(foo.baz());
这里没有真正的凝聚力,baz
本质上不属于任何 class,但 assembled 像这样他们表现得像一个。而 class
语法只是此机制的薄薄一层。因此,如果您在 函数 中编写 add
,它会遵循变量范围规则并会在周围的某个范围内查找变量,它不会在原型上找到方法.
我很好奇为什么方法不能在javascript中调用其他方法或它们自己。例如,这会产生一个引用错误,指出 add is not defined.
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 被定义时,它可以引用自身或其他带有闭包捕获的方法。
为什么会这样?
当 @briosheje 发表评论时,我正在说明这个缺点:
function add() {
console.log('called the wrong add!');
}
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))
我会尝试使其"slightly"更理论化,而不会深入研究文档等。
您的问题的主要答案可以通过将您的代码转换为普通代码来找到 javascript。为此,您可以使用 babel online 或 typescript online playground。 无论哪种情况,转译后的代码都将如下所示:
"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
总是 转译为函数)允许继承函数的标准行为,即有权访问其父级、拥有自己的作用域并授予对全局作用域的访问权限。
一点好奇心:如果您实际上可以使用 add
访问 this.add
,您将无法使用 undefined
,因为它是一个 全局变量,因此您将无法访问和使用它,因为它隐式为 this.undefined
.
所以,再一次,不是歧义,而是javascript函数如何工作。
从根本上讲,Javascript 中的 OOP 与 java 和其他语言非常不同。 "classes" 实际上并没有很强的概念。 classic OOP 概念,如 classes 和 Javascript 中的实例并不是真正来自 "classes",而是来自 属性 查找和 this
和 new
关键字。其他一切都只是函数、对象和属性——其中一些是 "special",比如 prototype
.
例如你可以 assemble 一个 "class" 这样的:
function Foo() {
this.bar = 42;
}
function baz() {
return this.bar;
}
Foo.prototype.baz = baz;
let foo = new Foo;
console.log(foo.baz());
这里没有真正的凝聚力,baz
本质上不属于任何 class,但 assembled 像这样他们表现得像一个。而 class
语法只是此机制的薄薄一层。因此,如果您在 函数 中编写 add
,它会遵循变量范围规则并会在周围的某个范围内查找变量,它不会在原型上找到方法.