从静态方法调用 ES5 class 方法
Call ES5 class method from static method
我想从没有实例调用的静态函数中调用内部函数,如下所示:
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 is not a function
。
示例 here 使用 class 的变量,如 var Foo.Bar = function (options) {...
,但与 class 的实例不同调用内部函数?
let x= new Foo.Bar(options);
x.innerFunc();
还有其他方法吗?
PS:我知道 ES6 classes 但我暂时不想将此 class 迁移到 ES6,因为它不是完全直接的。
嗯...看来您还不知道 JavaScript 的内部工作原理,所以这里简单回顾一下。 :)
JavaScript 是一种面向对象的语言。对象字面量是对象,数组是对象,函数是对象等等
Java脚本不是一种基于class的语言。你可以说:“嘿,我在 ES6 中看到了 class
和 extends
关键字!”。是的,但这只是语法糖。 Java脚本不像Java那样基于classes,它基于原型。
使用 ES5 语法,有两种方法可以创建所谓的 "class":
- 对象字面量
- 构造函数
当你使用对象文字时,你的 class 看起来像这样:
var myClass = {
myAttribute: "foo",
myMethod: function () {
return "bar";
}
};
当你使用构造函数时,你的 class 看起来像这样:
function MyClass() {
this.myAttribute = "foo";
this.myMethod = function () {
return "bar";
};
}
这两种方法之间当然存在差异。使用对象文字,你有一种单例,其中属性在某种程度上都是静态的。使用构造函数,您可以生成实例,其属性将由 this 关键字引入。示例:
var myInstance = new MyClass();
console.log(myInstance);
此实例的 自有属性 中将包含 "myAttribute" 和 "myMethod"。这意味着这些属性与实例相关联。如果你想调用这个方法,你必须这样做:
myInstance.myMethod();
到目前为止一切顺利...但是我们之前所做的有些问题。 this.myMethod
将为 MyClass
的每个实例一次又一次地创建,并且它始终相同。一个更好的处理方法是把它放在 prototype 中,这样它就可以被所有实例共享:
function MyClass() {
this.myAttribute = "foo";
}
MyClass.prototype.myMethod = function () {
return "bar";
};
这好多了,但是 myMethod
仍然绑定到 MyClass
个实例...
现在我想创建一个静态方法。根据定义,我们的静态方法将绑定到 class,而不是它的实例:
MyClass.myStaticMethod = function () {
return "baz";
};
不错。在这里,为了实验,我想做这样的事情:
MyClass.myStaticMethod = function () {
myMethod();
};
这不起作用。为什么?事实上, myMethod
不存在于给定范围内,也不存在于外部范围内。 myMethod
已在另一个函数(构造函数)内声明并且未返回,因此从外部看不到。而且,这个函数已经放在MyClass
的原型中了。这意味着它在全球范围内不可用,而仅在 MyClass
的实例上可用。仔细想想,这是很合乎逻辑的。例如,当你想调用数组方法(Array.prototype中的方法)时,这样做是没有意义的:
push('test');
reverse();
includes('a');
您必须在数组(Array 的实例)上调用这些方法。
[].push('test');
['foo', 'bar', 'baz'].reverse();
['a', 'b'].includes('a');
我想从没有实例调用的静态函数中调用内部函数,如下所示:
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 is not a function
。
示例 here 使用 class 的变量,如 var Foo.Bar = function (options) {...
,但与 class 的实例不同调用内部函数?
let x= new Foo.Bar(options);
x.innerFunc();
还有其他方法吗?
PS:我知道 ES6 classes 但我暂时不想将此 class 迁移到 ES6,因为它不是完全直接的。
嗯...看来您还不知道 JavaScript 的内部工作原理,所以这里简单回顾一下。 :)
JavaScript 是一种面向对象的语言。对象字面量是对象,数组是对象,函数是对象等等
Java脚本不是一种基于class的语言。你可以说:“嘿,我在 ES6 中看到了
class
和extends
关键字!”。是的,但这只是语法糖。 Java脚本不像Java那样基于classes,它基于原型。
使用 ES5 语法,有两种方法可以创建所谓的 "class":
- 对象字面量
- 构造函数
当你使用对象文字时,你的 class 看起来像这样:
var myClass = {
myAttribute: "foo",
myMethod: function () {
return "bar";
}
};
当你使用构造函数时,你的 class 看起来像这样:
function MyClass() {
this.myAttribute = "foo";
this.myMethod = function () {
return "bar";
};
}
这两种方法之间当然存在差异。使用对象文字,你有一种单例,其中属性在某种程度上都是静态的。使用构造函数,您可以生成实例,其属性将由 this 关键字引入。示例:
var myInstance = new MyClass();
console.log(myInstance);
此实例的 自有属性 中将包含 "myAttribute" 和 "myMethod"。这意味着这些属性与实例相关联。如果你想调用这个方法,你必须这样做:
myInstance.myMethod();
到目前为止一切顺利...但是我们之前所做的有些问题。 this.myMethod
将为 MyClass
的每个实例一次又一次地创建,并且它始终相同。一个更好的处理方法是把它放在 prototype 中,这样它就可以被所有实例共享:
function MyClass() {
this.myAttribute = "foo";
}
MyClass.prototype.myMethod = function () {
return "bar";
};
这好多了,但是 myMethod
仍然绑定到 MyClass
个实例...
现在我想创建一个静态方法。根据定义,我们的静态方法将绑定到 class,而不是它的实例:
MyClass.myStaticMethod = function () {
return "baz";
};
不错。在这里,为了实验,我想做这样的事情:
MyClass.myStaticMethod = function () {
myMethod();
};
这不起作用。为什么?事实上, myMethod
不存在于给定范围内,也不存在于外部范围内。 myMethod
已在另一个函数(构造函数)内声明并且未返回,因此从外部看不到。而且,这个函数已经放在MyClass
的原型中了。这意味着它在全球范围内不可用,而仅在 MyClass
的实例上可用。仔细想想,这是很合乎逻辑的。例如,当你想调用数组方法(Array.prototype中的方法)时,这样做是没有意义的:
push('test');
reverse();
includes('a');
您必须在数组(Array 的实例)上调用这些方法。
[].push('test');
['foo', 'bar', 'baz'].reverse();
['a', 'b'].includes('a');