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

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

问题描述

我知道这会有效:

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

var a = new Foo;
a.talk(); //'你好〜\\ n'

但如果我想打电话

  Foo.talk()//这不起作用
Foo.prototype.talk()//这个工作正常

我找到一些方法可以使 Foo.talk 工作,


  1. Foo .__ proto__ = Foo.prototype

  2. Foo.talk = Foo.prototype.talk

还有其他吗?这样做的方法?我不知道这样做是否正确。你在JavaScript代码中使用类方法还是静态方法?

解决方案

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

我建议大多数时候忽略 __ proto __ ,因为它的浏览器支持很差,而是专注于学习关于 prototype 如何工作。



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



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



例如:

  foo = {bar:'baz'}; 
alert(foo.bar); //提醒baz

foo = {};
alert(foo.bar); //提示undefined

函数Foo(){}
Foo.prototype = {bar:'baz'};
f = new Foo();
alert(f.bar);
//警告baz,因为对象f没有属性bar
//所以它检查原型
f.bar ='buzz';
alert(f.bar); //提醒buzz因为f有一个属性bar设置






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



在JavaScript中,一切都是对象 3



一切是一个对象。



function Foo(){} 不只是定义一个新函数,它定义了一个可以使用<$访问的新函数对象c $ c> Foo 。



这就是你可以访问 Foo 的原因原型 Foo.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引入了定义类的能力使用关键字。



2:本质上是由构造函数创建的类实例,但有许多微妙的差异,我不想误导你



3:原始值—其中包括 undefined null ,布尔值,数字和字符串—在技术上不是对象,因为它们是低级语言实现。布尔值,数字和字符串仍然与原型链相互作用,就像它们是对象一样,所以为了这个答案的目的,即使它们不完整,也更容易将它们视为对象。


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

Is there some 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?

解决方案

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 it's prototype object. If the prototype object has a prototype, it repeats, if no prototype exists, undefined is returned.

For example:

foo = {bar: 'baz'};
alert(foo.bar); //alerts "baz"

foo = {};
alert(foo.bar); //alerts undefined

function Foo(){}
Foo.prototype = {bar: 'baz'};
f = new Foo();
alert(f.bar);
//alerts "baz" because the object f doesn't have an attribute "bar"
//so it checks the prototype
f.bar = 'buzz';
alert( f.bar ); //alerts "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 therefor 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.

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

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