Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

javascript - JavaScript中的类与静态方法(Class vs. static method in JavaScript)

I know this will work:

(我知道这会起作用:)

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

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

But if I want to call

(但是如果我想打电话)

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

I find some methods to make Foo.talk work,

(我找到一些使Foo.talk正常工作的方法,)

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

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代码中使用类方法还是静态方法?)

  ask by lostyzd translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First off, remember that JavaScript is primarily a prototypal language , rather than a class-based language 1 .

(首先,请记住JavaScript主要是一种原型语言 ,而不是基于类的语言 1 。)

Foo isn't a class, it's a function, which is an object.

(Foo不是类,而是函数,是对象。)

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.

(您可以使用new关键字该函数实例化一个对象该关键字将允许您使用标准OOP语言创建类似于类的内容。)

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.

(我建议大多数时候都忽略__proto__ ,因为它对跨浏览器的支持不佳,而应该专注于学习prototype工作方式。)

If you have an instance of an object created from a function 2 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.

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

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.

(如果原型对象具有原型,则重复该操作,如果不存在原型,则返回undefined 。)

For example:

(例如:)

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.

(在我看来,您已经至少已经对这些“基本”部分有所了解,但是为了确保它们,我需要使它们明确。)

In JavaScript, everything is an object 3 .

(在JavaScript中,一切都是对象3 。)

everything is an object.

(一切都是对象。)

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

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

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

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

What you can also do is set more functions on Foo :

(您还可以在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.

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

Think of f = new Foo();

(想想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.

(创建类实例时, Foo.prototype.bar = function(){...}为该类定义共享方法,而Foo.baz = function(){...}为该类定义公共静态方法类。)


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.

(ECMAScript 2015为此类声明引入了多种语法糖,以使其更易于实现,同时也更易于阅读。)

The previous example can therefore be written as:

(因此,前面的示例可以写成:)

class Foo {
  bar() {...}

  static baz() {...}
}

which allows bar to be called as:

(允许将bar称为:)

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

and baz to be called as:

(和baz被称为:)

Foo.baz()

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

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

2: essentially a class instance created by a constructor, but there are many nuanced differences that I don't want to mislead you

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

3: primitive values —which include undefined , null , booleans, numbers, and strings—aren't technically objects because they're low-level language implementations.

(3: 基本值(包括undefinednull ,布尔值,数字和字符串)在技术上不是对象,因为它们是底层语言实现。)

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.

(布尔值,数字和字符串仍然像它们是对象一样与原型链交互,因此,出于此答案的目的,即使它们并非完全相同,也更容易将它们视为“对象”。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...