JavaScript 中的类与静态方法

2022-08-30 00:18:06

我知道这将起作用:

function Foo() {};
Foo.prototype.talk = function () {
    alert('hello~\n');
};

var a = new Foo;
a.talk(); // 'hello~\n'

但是如果我想打电话

Foo.talk() // this will not work
Foo.prototype.talk() // this works correctly

我找到了一些方法来工作,Foo.talk

  1. Foo.__proto__ = Foo.prototype
  2. Foo.talk = Foo.prototype.talk

还有其他方法可以做到这一点吗?我不知道这样做是否正确。您在 JavaScript 代码中使用类方法还是静态方法?


答案 1

首先,请记住,JavaScript主要是一种原型语言,而不是基于类的语言1。 不是一个类,它是一个函数,它是一个对象。您可以使用关键字该函数实例化对象,这将允许您创建类似于标准OOP语言中的类的内容。Foonew

我建议忽略大多数时候,因为它的跨浏览器支持很差,而是专注于学习工作原理。__proto__prototype

如果您有一个从函数2 创建的对象的实例,并且您以任何方式访问其成员之一(方法、特性、属性、常量等),则访问将沿着原型层次结构向动,直到它 (a) 找到该成员,或者 (b) 找不到另一个原型。

层次结构从被调用的对象开始,然后搜索其原型对象。如果原型对象具有原型,则返回重复,如果不存在原型,则返回该重复。undefined

例如:

foo = {bar: 'baz'};
console.log(foo.bar); // logs "baz"

foo = {};
console.log(foo.bar); // logs undefined

function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
console.log(f.bar);
// logs "baz" because the object f doesn't have an attribute "bar"
// so it checks the prototype
f.bar = 'buzz';
console.log( f.bar ); // logs "buzz" because f has an attribute "bar" set

在我看来,你至少已经在某种程度上理解了这些“基本”部分,但我需要明确它们才能确定。

在 JavaScript 中,一切都是对象3

一切都是一个对象。

function Foo(){}它不仅定义了一个新函数,还定义了一个可以使用 访问的新函数对象。Foo

这就是为什么您可以使用 访问 的原型的原因。FooFoo.prototype

您还可以做的是在 上设置更多功能Foo

Foo.talk = function () {
  alert('hello world!');
};

可以使用以下命令访问此新功能:

Foo.talk();

我希望到现在为止,您已经注意到函数对象上的函数与静态方法之间的相似性。

可以考虑创建类实例,为类定义共享方法,并为类定义公共静态方法。f = new Foo();Foo.prototype.bar = function(){...}Foo.baz = function(){...}


ECMAScript 2015 为这些类型的声明引入了各种语法糖,以使它们更易于实现,同时也更易于阅读。因此,前面的示例可以写为:

class Foo {
  bar() {...}

  static baz() {...}
}

它允许被称为:bar

const f = new Foo()
f.bar()

并被称为:baz

Foo.baz()

1:class 在 ECMAScript 5 规范中是“未来保留字”,但 ES6 引入了使用 class 关键字定义类的功能。

2:本质上是一个由构造函数创建的类实例,但是有很多细微差别,我不想误导你

3:基元值(包括未定义null、布尔值、数字和字符串)在技术上不是对象,因为它们是低级语言实现。布尔值、数字和字符串仍然与原型链交互,就好像它们是对象一样,因此,为了这个答案的目的,即使它们不完全是“对象”,也更容易将它们视为“对象”。


答案 2

您可以按如下方式实现它:

function Foo() {};

Foo.talk = function() { alert('I am talking.'); };

您现在可以调用“talk”功能,如下所示:

Foo.talk();

你可以这样做,因为在JavaScript中,函数也是对象。