我有一个带有静态方法的类:
class User {
constructor() {
User.staticMethod();
}
static staticMethod() {}
}
静态方法是否有与此等效的方法(即引用没有实例的当前类)?
this.staticMethod()
所以我不必写类名:“User”。
来自 MDN 文档
静态方法调用是直接在类上进行的,而不是 可在类的实例上调用。静态方法通常用于 创建实用函数。
欲了解更多信息,请参阅=> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
你可以这样做 =>
this.constructor.staticMethod();
来调用静态方法。
class StaticMethodCall {
constructor() {
console.log(StaticMethodCall.staticMethod());
// 'static method has been called.'
console.log(this.constructor.staticMethod());
// 'static method has been called.'
}
static staticMethod() {
return 'static method has been called.';
}
}
您可以使用:
User.staticMethod()
代替:
this.constructor.staticMethod()
@Rohith K P 的答案就是简而言之的解决方案。
如果你想理解它,你需要了解 JavaScript 类“在幕后”是什么。
这是在 ES6 之前创建类的方式:
// This is a constructor function that initializes new Range objects.
// Note that it does not create or return the object. It just initializes this.
function Range(from, to) {
// Store the start and end points (state) of this new range object.
// These are noninherited properties that are unique to this object.
this.from = from;
this.to = to;
}
// All Range objects inherit from this object.
// Note that the property name must be "prototype" for this to work.
// Note that the prototype property is the property of the Range function
Range.prototype = {
// create some methods
// Return true if x is in the range, false otherwise
// This method works for textual and Date ranges as well as numeric.
includes: function(x) { return this.from <= x && x <= this.to; },
// A generator function that makes instances of the class iterable.
// Note that it only works for numeric ranges.
[Symbol.iterator]: function*() {
for( let x = Math.ceil( this.from); x <= this.to; x ++) yield x;
},
// Return a string representation of the range
toString: function() { return "(" + this.from + "..." + this.to + ")"; }
};
// Here are example uses of this new Range class
let r = new Range(1,3);
// r inherits from Range.prototype
r.includes(2) // = > true: 2 is in the range
r.toString() // = > "(1...3)"
[...r] // => [1, 2, 3]; convert to an array via iterator
所以,类本质上是一个函数,它是其原型对象的公共接口(构造函数)。
let F = function() {}; // This is a function object.
let p = F.prototype; // This is the prototype object associated with F.
let c = p.constructor; // This is the function associated with the prototype.
c === F // true
了解此示例中定义的类与 ES6 类的工作方式“完全相同”非常重要。在语言中引入“class”关键字并不会改变 JavaScript 基于原型的类的基本性质。
静态方法静态方法被定义为
构造函数的属性,而不是原型对象的属性。
static parse(s) {
let matches = s.match(/^\((\d+)\.\.\.(\d+)\)$/);
if (!matches) {
throw new TypeError(`Cannot parse Range from "${s}".`)
}
return new Range(parseInt(matches[1]), parseInt(matches[2]));
}
这段代码定义的方法是Range.parse(),而不是Range.prototype.parse(),你必须通过构造函数调用它,而不是通过实例:
let r = Range.parse('(1...10)'); // Returns a new Range object
r.parse('(1...10)'); // TypeError: r.parse is not a function
有时您会看到称为类方法的静态方法,因为它们是使用类/构造函数的名称调用的。使用该术语时,是将类方法与在类实例上调用的常规实例方法进行对比。因为静态方法是在构造函数上调用的,而不是在任何特定实例上调用的,所以在静态方法中使用this
关键字几乎没有意义。
来源:大卫·弗拉纳根。 JavaScript:权威指南。
static
事物绑定到类而不是实例。所以你至少必须指定类名。
如果您不想将它们绑定到类,请将它们设置为全局。
console.log(Object.getOwnPropertyNames(PaymentStrategy));
并且只需访问会员即可
const memberFun = PaymentStrategy["memberName"];
//if member is a function then execute
memberFun();
//or
memberFun(data);
class PaymentStrategy{
static Card(user){
console.log(`${user} will pay with a credit card`);
}
static PayPal(user){
console.log(`${user} will pay through paypal`);
}
static BKash(user){
console.log(`${user} will pay through Bkash`);
}
}
export default PaymentStrategy;
import PaymentStrategy from "./PaymentStrategy";
class Payment{
constructor(strategy = "BKash"){
this.strategy = PaymentStrategy[strategy];
console.log(Object.getOwnPropertyNames(PaymentStrategy));
}
changeStrategy(newStratgey){
this.strategy = PaymentStrategy[newStratgey];
console.log(`***Payment Strategy Changed***`);
}
showPaymentMethod(user){
this.strategy(user);
}
}
export default Payment;
```
```
import Payment from "./Payment"
const strategyPattern = (()=>{
const execute = ()=>{
const paymentMethod = new Payment();
paymentMethod.showPaymentMethod("Suru");
paymentMethod.showPaymentMethod("Nora");
paymentMethod.changeStrategy("PayPal");
paymentMethod.showPaymentMethod("Rafiq");
}
return{
execute:execute
}
})();
export {strategyPattern}
```
本质上,解决方案是将类本身传递给静态方法。例如:
class Foo {
static greet(Type) {
return `Hello, ${Type.name()}`
}
static name() {
return 'foo'
}
}
class Bar extends Foo {
static name() {
return 'bar'
}
}
现在你可以打电话了
Bar.greet(Bar) // returns 'Hello, bar'
class StaticMethodCall { constructor() {
console.log(StaticMethodCall.staticMethod());
// 'static method has been called.'
console.log(this.constructor.staticMethod());
// 'static method has been called.' }
static staticMethod() {
return 'static method has been called.'; } }
this.constructor.staticMethod()
会抛出错误,因为在构造函数中访问
this
之前必须调用超级构造函数。 假设您解决了上述问题,没有双关语的意思,我认为调用
this.constructor.staticMethod()
的唯一好处是您不依赖于类的名称 - 如果它发生变化。然而,这个好处可能微不足道,因为它只对从类内部进行的静态方法调用有好处。外部进行的静态方法调用必须类似于
StaticMethodCall.constructor.staticMethod()
,这违背了目的并且看起来很愚蠢。 总结:
如果您计划在类之外使用静态方法,我肯定会坚持使用 StaticMethodCall.staticMethod() 因为它更惯用和简洁。
如果您只打算在类中使用静态方法,那么也许可以使用
this.constructor.staticMethod()
,但它可能会让其他开发人员感到困惑并引导他们回到此页面:-)