【问题标题】:Declare a public "static" function inside a JavaScript class在 JavaScript 类中声明一个公共的“静态”函数
【发布时间】:2015-09-18 10:01:14
【问题描述】:

假设我需要声明一些 private static 成员以在一些 public static 方法中使用它。 .

// ***** 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");
};

我知道使用“静态”OOP 概念的 JavaScript 存在一些困难,所以我的问题是:

我可以在“对象”的“声明主体”中声明 public static 方法inside(如上面的“变体 I”) )?

【问题讨论】:

  • supports.prototype.impl = ... - 公共非静态(成员)
  • @hindmost:感谢指正!我相应地修复了评论

标签: javascript oop static-methods


【解决方案1】:

在您的变体 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());

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

【讨论】:

  • 如何在“类体”中声明public静态方法?
  • @Serge 你已经发现自己在变体 II supports.SVG 中是公开的和静态的。确保将其保留在类声明之外(如您的示例中所示),因为每次实例化类时都会执行内部的所有内容,这也是将其用作构造函数的原因。
  • 因此您确认在 JavaScript 不可能在“类声明”内部声明“公共静态”函数,(如在 C# 中,例如)它只应该被包装在一个匿名函数中
  • @Serge 是可能的,但是每次实例化类时都会重新定义它,这没有任何意义。 JavaScript 没有像 C++、C#、Java 等其他编程语言那样的对象模型。等到你需要析构函数 :D 它被称为类但它不是类,它只是一个函数,它也是一个对象,因为函数是 JavaScript 中的对象
  • @Serge 我猜你是对的,所以你能做的最好的就是在外面声明。
【解决方案2】:

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

静态方法

静态方法,就像变量一样,附加到函数上。它们主要用于对象:

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

【讨论】:

【解决方案3】:

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 读取,但在调用它之间会持续存在。

【讨论】:

  • 如何在“类体”中声明public静态方法?
  • JS 中没有“类主体”(至少从 ES5 开始)。如果您按照 Java 对“静态方法”的定义,它们只是在构造函数上定义的函数。如果你停止用 JavaScript 编写 Java,开始编写 JavaScript,你会更快乐。
【解决方案4】:

分析一些答案后我看到的唯一解决方案是:

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());

PS。

我注意到 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!';}

【讨论】:

    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2022-06-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多