Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class vs. static method in JavaScript

Tags:

javascript

oop

I know this will work:

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

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,

  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?

like image 820
lostyzd Avatar asked Oct 08 '11 02:10

lostyzd


People also ask

What is the difference between a class method and a static method?

Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class. Static methods do not know about class state.

What is static method in class in JavaScript?

A static method in JavaScript is a method that has a static keyword prepended to itself. Such methods cannot be accessed through instantiated objects but could be accessed through the class name. This is because static methods belong to the class directly. Inheritance even applies to static methods.

Can a class be static in JavaScript?

Definition and UsageThe static keyword defines static methods for classes. Static methods are called directly on the class ( Car from the example above) - without creating an instance/object ( mycar ) of the class.

Why we use static methods in JavaScript?

Static methods are often utility functions, such as functions to create or clone objects, whereas static properties are useful for caches, fixed-configuration, or any other data you don't need to be replicated across instances.


1 Answers

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.

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.

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.

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.

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 object3.

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.

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

What you can also do is set more functions on 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(); 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 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() {...} } 

which allows bar to be called as:

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

and baz to be called as:

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.

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

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.

like image 86
zzzzBov Avatar answered Oct 15 '22 22:10

zzzzBov