声明一个公共的“静态”;函数在JavaScript类中

Declare a public "static" function inside a JavaScript class

本文关键字:静态 函数 类中 JavaScript 一个 声明      更新时间:2023-09-26

假设我需要声明一些privatestatic成员,以便在一些publicstatic方法中使用它…

// ***** Variant I *****
function supports() {
    var impl = document.implementation; // private, non-static
    this.SVG = function () {            // public, non-static
      return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
    };
}
// ***** Variant II *****
function supports() { }
supports.prototype.impl = document.implementation; // public, non-static
supports.SVG = function () {                       // public, static
  return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
};

我知道JavaScript中的"静态"OOP概念有一些困难,所以我的问题是:

我可以在中声明public static方法在"对象"的"声明体"中(如上面的"变体I")吗?

JavaScript中没有私有、静态或公共之分。只有局部和全局,范围内和范围外。使用IIFE捕获变量并返回闭包;这应该等同于一个静态方法。

var supports = (function supportsWrapper() {
    var impl = document.implementation; // "static"-ish.
    return function supports() {
      this.SVG = function () {
        return impl.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
      };
    }
})();

impl将只初始化一次,并且只能被supports读取,但在调用它之间将持续存在。

在你的变体II中,被认为是私有和静态的函数既不是私有的也不是静态的。

你是对的,定义类的私有静态成员是相当困难的,但如果你利用JavaScript的作用域,这是可能的。

var Person = (function(){
    var privateStaticProperty = true;
    function privateStatic() {
        return privateStaticProperty;
    }
    function Person(){
        // class declarations
    }
    Person.prototype.example = function() {
        return privateStatic();
    }
    return Person;
}());
var p = new Person();
console.log(p.example());

但是,请注意,如果在闭包之外扩展原型,那么所谓的私有静态成员将不可用。

在JavaScript中,没有静态术语或关键字,但是我们可以将这些数据直接放入函数对象中(就像在任何其他对象中一样)。

静态方法

静态方法,就像变量一样,附加在函数上。它们主要用于对象:
function Animal(name) {
  arguments.callee.count = ++arguments.callee.count || 1 
  this.name = name
}
Animal.showCount = function() {
  alert( Animal.count )
}
var mouse = new Animal("Mouse")
var elephant = new Animal("elephant")
Animal.showCount()  // 2

在分析了一些答案后,我看到的唯一解决方案是这个:

var Person = (function () {
    var _privateStatic = 'private static member';
    function privateStatic() {
        return _privateStatic + ' + private-s-function';
    }
    function Person() {
        this.publicNonStatic = 'public, non-static member';
        this.publicFunction = function () { 
            return this.publicNonStatic + '+ public non-static-function'; 
        }
        var _privateNonStatic = 'private, non-static member';
        function privateNonStatic() {
            return _privateNonStatic + " + private-ns-function"
        }
        this.publicStatic = Person.publicStatic = 'public static member';
        this.publicStaticFunction = Person.publicStaticFunction = function () {
            return Person.publicStatic + ' + public static function';
        }        
        // Accessible internal 
        var test = _privateNonStatic;
        test = _privateStatic;
        test = privateStatic();
        test = privateNonStatic();
        // other class declarations
    }
    return Person;
}());
// Accessible external members: 
var p = new Person();
console.log(p.publicFunction());
console.log(p.publicNonStatic);
console.log(p.publicStatic);
console.log(p.publicStaticFunction());
console.log(Person.publicStatic); 
console.log(Person.publicStaticFunction());

p。

然而,我注意到publicStaticFunction()只有在new Person()声明之后才能访问…因此,如果可用,则之前:

// Accessible external members: 
console.log(Person.publicStatic);           // NO WAY
console.log(Person.publicStaticFunction()); // NO WAY
var p = new Person(); // lazy declaration 
console.log(Person.publicStatic);           // IS OK!
console.log(Person.publicStaticFunction()); // IS OK!

,所以我想没有办法在函数Person体内实现它,只有在包装Person的匿名函数内…

所以初始的SVG示例应该是这样的:
var supports = (function(){
    function supports() { this.SVG = supports.SVG; } 
    supports.SVG = function () {
        return document.implementation.hasFeature("http://shortened", "1.1");
    };
    return supports;
}());
// usage of public, static method
if (supports.SVG()) {return 'supports SVG!';}