JavaScript 中的类与静态方法 [英] Class vs. static method in JavaScript

查看:33
本文介绍了JavaScript 中的类与静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这会奏效:

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

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

但是如果我想打电话

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

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

I find some methods to make Foo.talk work,

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

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

Are there other ways to do this? I don’t know whether it is right to do so. Do you use class methods or static methods in your JavaScript code?

推荐答案

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

First off, remember that JavaScript is primarily a prototypal language, rather than a class-based language1. Foo isn't a class, it's a function, which is an object. You can instantiate an object from that function using the new keyword which will allow you to create something similar to a class in a standard OOP language.

我建议大多数时候忽略 __proto__,因为它的跨浏览器支持很差,而是专注于了解 prototype 的工作原理.

I'd suggest ignoring __proto__ most of the time because it has poor cross browser support, and instead focus on learning about how prototype works.

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

If you have an instance of an object created from a function2 and you access one of its members (methods, attributes, properties, constants etc) in any way, the access will flow down the prototype hierarchy until it either (a) finds the member, or (b) doesn't find another prototype.

层次从被调用的对象开始,然后搜索它的原型对象.如果原型对象有原型,则重复,如果不存在原型,则返回undefined.

The hierarchy starts on the object that was called, and then searches its prototype object. If the prototype object has a prototype, it repeats, if no prototype exists, undefined is returned.

例如:

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

<小时>

在我看来,您至少已经对这些基本"部分有所了解,但为了确定起见,我需要将它们明确化.


It looks to me like you've at least somewhat understood these "basic" parts already, but I need to make them explicit just to be sure.

在 JavaScript 中,一切都是对象3.

In JavaScript, everything is an object3.

一切都是一个对象.

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

function Foo(){} doesn't just define a new function, it defines a new function object that can be accessed using Foo.

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

This is why you can access Foo's prototype with Foo.prototype.

你还可以在Foo上设置更多功能:

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

可以使用以下方法访问此新功能:

This new function can be accessed using:

Foo.talk();

我希望现在您已经注意到函数对象上的函数与静态方法之间的相似之处.

I hope by now you're noticing a similarity between functions on a function object and a static method.

f = new Foo(); 视为创建类实例,将 Foo.prototype.bar = function(){...} 视为定义共享类的方法,Foo.baz = function(){...} 为类定义公共静态方法.

Think of f = new Foo(); as creating a class instance, Foo.prototype.bar = function(){...} as defining a shared method for the class, and Foo.baz = function(){...} as defining a public static method for the class.

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

ECMAScript 2015 introduced a variety of syntactic sugar for these sorts of declarations to make them simpler to implement while also being easier to read. The previous example can therefore be written as:

class Foo {
  bar() {...}

  static baz() {...}
}

允许将 bar 称为:

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

baz 被称为:

Foo.baz()

<小时>

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


1: class was a "Future Reserved Word" in the ECMAScript 5 specification, but ES6 introduces the ability to define classes using the class keyword.

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

3: 原始值—包括undefinednull、布尔值、数字和字符串——在技术上不是对象,因为它们是低级语言实现.布尔值、数字和字符串仍然像对象一样与原型链交互,因此就本答案而言,即使它们不完全是对象",也更容易将它们视为对象".

3: primitive values—which include undefined, null, booleans, numbers, and strings—aren't technically objects because they're low-level language implementations. Booleans, numbers, and strings still interact with the prototype chain as though they were objects, so for the purposes of this answer, it's easier to consider them "objects" even though they're not quite.

这篇关于JavaScript 中的类与静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆