JavaScript類


3 Answers

我認為你所尋找的是“揭示原型模式”。

Dan Wahlin有一篇很棒的博客文章: http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx ://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern http://weblogs.asp.net/dwahlin/archive/2011/08/03/techniques-strategies-and-patterns-for-structuring-javascript-code-revealing-prototype-pattern.aspx

甚至更好的Pluralsight關於這個和其他相關JavaScript結構的課程: http://pluralsight.com/training/courses/TableOfContents?courseName=structuring-javascript&highlight=dan-wahlin_structuring-javascript-module1!dan-wahlin_structuring-javascript-module2!dan-wahlin_structuring-javascript-module5!dan-wahlin_structuring-javascript-module4!dan-wahlin_structuring-javascript-module3#structuring-javascript-module1 ://pluralsight.com/training/courses/TableOfContents?courseName = struct-javascript&highlight / = light -wahlin_structuring-javascript-module1!dan -wahlin_structuring -javascript-module2!dan http://pluralsight.com/training/courses/TableOfContents?courseName=structuring-javascript&highlight=dan-wahlin_structuring-javascript-module1!dan-wahlin_structuring-javascript-module2!dan-wahlin_structuring-javascript-module5!dan-wahlin_structuring-javascript-module4!dan-wahlin_structuring-javascript-module3#structuring-javascript-module1

Question

我理解基本的JavaScript偽類:

function Foo(bar) {
    this._bar = bar;
}

Foo.prototype.getBar = function() {
    return this._bar;
};

var foo = new Foo('bar');
alert(foo.getBar()); // 'bar'
alert(foo._bar); // 'bar'

我也理解模塊模式,它可以模擬封裝:

var Foo = (function() {
    var _bar;

    return {
        getBar: function() {
            return _bar;
        },
        setBar: function(bar) {
            _bar = bar;
        }
    };
})();

Foo.setBar('bar');
alert(Foo.getBar()); // 'bar'
alert(Foo._bar); // undefined

但是這兩種模式都有類似OOP的屬性。 前者不提供封裝。 後者不提供實例化。 可以修改這兩種模式以支持偽繼承。

我想知道的是,是否有任何模式允許:

  • 遺產
  • 封裝(支持“私有”屬性/方法)
  • 實例化(可以有多個“類”實例,每個實例都有自己的狀態)






我最近在考慮這個特定主題以及各種方法的局限性。 我能夠提出的最佳解決方案如下。

它似乎解決了繼承,實例化和封裝的問題(至少從谷歌Chrome v.24的測試中解決),儘管可能以內存使用為代價。

function ParentClass(instanceProperty) {
  // private
  var _super = Object.create(null),
      privateProperty = "private " + instanceProperty;
  // public
  var api = Object.create(_super);
  api.constructor = this.constructor;
  api.publicMethod = function() {
     console.log( "publicMethod on ParentClass" );
     console.log( privateProperty );
  };
  api.publicMethod2 = function() {
     console.log( "publicMethod2 on ParentClass" );
     console.log( privateProperty );
  };
  return api;
}

function SubClass(instanceProperty) {
    // private
    var _super = ParentClass.call( this, instanceProperty ),
        privateProperty = "private sub " + instanceProperty;
    // public
    var api = Object.create(_super);
    api.constructor = this.constructor;
    api.publicMethod = function() {
       _super.publicMethod.call(this); // call method on ParentClass
        console.log( "publicMethod on SubClass" );
        console.log( privateProperty );
    }
    return api;
}

var par1 = new ParentClass(0),
    par2 = new ParentClass(1),
    sub1 = new SubClass(2),
    sub2 = new SubClass(3);

par1.publicMethod();
par2.publicMethod();
sub1.publicMethod();
sub2.publicMethod();
par1.publicMethod2();
par2.publicMethod2();
sub1.publicMethod2();
sub2.publicMethod2();



此閉包允許實例化和封裝,但不允許繼承。

function Foo(){
    var _bar = "foo";

    return {
        getBar: function() {
            return _bar;
        },
        setBar: function(bar) {
            _bar = bar;
        }
    };
};

a = Foo();
b = Foo();

a.setBar("bar");
alert(a.getBar()); // "bar"
alert(b.getBar()); // "foo"



Related