从静态方法调用ES5类方法 [英] Call ES5 class method from static method

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

问题描述

我想从没有实例的静态函数中调用内部函数,例如:

I want to call an inner function from a static function that was called without an instance, like so:

Foo.Bar = function (options) {

    Autodesk.Viewing.Extension.call(this, options);

    ...

    this.innerFunc = function innerFunc(){
      ...
    }
};

Foo.Bar.prototype.constructor =
    Foo.Bar;

Foo.Bar.SomeStaticFunc = function () {
    innerFunc();
}

使用: Foo.Bar.SomeStaticFunc();

但是我得到 SomeStaticFunc不是函数

示例此处为该类使用变量,例如 var Foo.Bar = function(options){... ,但这不是

The example here uses a variable for the class, like var Foo.Bar = function (options) {... but isn't that the same as making an instance of the class like so and calling an inner function?

let x= new Foo.Bar(options);
x.innerFunc();

还有另一种方法吗?

PS:我了解ES6类,但是我现在不愿意将该类迁移到ES6,因为它并不完全简单。

PS: I know about ES6 classes but I prefer not to migrate this class to ES6 for now because it isn't totally straight forward.

推荐答案

好吧……看来您不知道JavaScript在内部如何工作,因此这里有个简短的回顾。 :)

Well... It seems that you do not know how JavaScript works internally, so here is a quick recap. :)


  • JavaScript IS 是一种面向对象的语言。对象文字是对象,数组是对象,函数是对象等。

  • JavaScript IS an object-oriented language. Object literals are objects, arrays are objects, functions are objects, etc.

JavaScript 不是是一种基于类的语言。您可能会说: 嘿,我在ES6中见过 class extends 关键字!。是的,但这只是语法糖。 JavaScript不是基于Java之类的,而是基于原型

JavaScript IS NOT a class-based language. You could say: "Hey, I've seen class and extends keywords in ES6!". Yes, but this is just syntactic sugar. JavaScript is not based on classes like Java, it is based on prototypes.

ES5语法,有两种方法可以创建所谓的类:

With ES5 syntax, there are two ways to create what you call a "class":


  • 对象文字

  • 构造函数

使用对象文字时,您的类如下所示:

When you use an object literal, your class looks like this:

var myClass = {
  myAttribute: "foo",
  myMethod: function () {
    return "bar";
  }
};

使用构造函数时,您的类如下所示:

When you use a constructor function, your class looks like this:

function MyClass() {
  this.myAttribute = "foo";
  this.myMethod = function () {
    return "bar";
  };
}

当然,这两种方法之间存在差异。使用对象文字,您可以得到一种Singleton,其中属性在某种程度上都是静态的。使用构造函数,您可以生成实例的实例,这些实例的属性将通过 this 关键字引入。示例:

There are of course differences between these two approaches. With the object literal, you have a sort of Singleton where properties are all static to some extent. With the constructor function, you can produce instances whose properties will be introduced by the this keyword. Example:

var myInstance = new MyClass();
console.log(myInstance);

此实例的自身属性中将包含 myAttribute和 myMethod 。这意味着这些属性与实例相关联。如果要调用此方法,则必须执行以下操作:

This instance will have "myAttribute" and "myMethod" in its own properties. This means that these properties are tied to the instance. If you want to call this method, you must do this:

myInstance.myMethod();

到目前为止,一切都还不错……但是我们以前所做的事情有问题。 this.myMethod 将为 MyClass 的每个实例一次又一次创建,并且始终相同。处理此问题的更好方法是将其放入原型,以便可以被所有实例共享:

So far so good... But there is something wrong with what we did previously. this.myMethod will be created again and again for each instance of MyClass and it is always the same. A better way to handle this is to put it in the prototype so that it can be shared by all instances:

function MyClass() {
  this.myAttribute = "foo";
}

MyClass.prototype.myMethod = function () {
  return "bar";
};

这要好得多,但是 myMethod 仍然与 MyClass 实例相关...

This is much better, but myMethod is still tied to MyClass instances...

现在我想创建一个静态方法。根据定义,我们的静态方法将与该类相关联,而不是与其实例相关联:

Now I want to create a static method. By definition, our static method will be tied to the class, not to its instances:

MyClass.myStaticMethod = function () {
  return "baz";
};

很好。在这里,为了进行实验,我想做这样的事情:

Nice. Here, for the sake of experimentation, I want to do something like this:

MyClass.myStaticMethod = function () {
  myMethod();
};

这不起作用。为什么?实际上, myMethod 在给定范围或外部范围中都不存在。 myMethod 已在另一个函数(构造函数)中声明,并且不会返回,因此从外部不可见。此外,此功能已放在 MyClass 的原型中。这意味着它不是全局可用的,而仅在 MyClass 的实例上可用。当您考虑它时,这是很合逻辑的。例如,当您要调用数组方法(Array.prototype中的方法)时,这样做是没有意义的:

This does not work. Why? In fact, myMethod does not exist in the given scope nor in the outer scope. myMethod has been declared inside another function (the constructor function) and it is not returned, so it is invisible from the outside. Moreover, this function has been put in the prototype of MyClass. This means that it is not available globally, but only on instances of MyClass. When you think about it, it is pretty logical. For instance, when you want to call array methods (methods in Array.prototype), it does not make sense to do that:

push('test');
reverse();
includes('a');

您必须在数组上调用这些方法(Array的实例)。

You must call these methods on an array (instance of Array).

[].push('test');
['foo', 'bar', 'baz'].reverse();
['a', 'b'].includes('a');

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

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