JavaScript nesnelerindeki yapıcılar


Yanıtlar:


408

Prototipleri kullanma:

function Box(color) // Constructor
{
    this.color = color;
}

Box.prototype.getColor = function()
{
    return this.color;
};

"Renk" gizleme (özel üye değişkenine benziyor):

function Box(col)
{
   var color = col;

   this.getColor = function()
   {
       return color;
   };
}

Kullanımı:

var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green

3
@BorisB, evet yaparsınız - bu, Box nesnesindeki color ve getColor'u tanımlar, aksi takdirde normal kapsamda değişkenler atarsınız.
Nick

4
@Evet evet öyle. Gizlenen alternatif bir pasaj sağladım color. Hangisini kullandığınızı büyük ölçüde kişisel tercihe bağlı olarak öneririm (koruma ve basitlik)
Nick

6
@CamiloMartin Her zaman gerekli olmamakla birlikte, değişken "özel" (veya bu durumda adsız) yapmak, harici kodun sınıfınızın uygulama ayrıntılarına bağımlı olmasını önlemenin yararlı bir yolu olabilir. Sadece sınıfın hangi öğelerinin genel / özel olduğunu belirtmek bile harici kullanıcılar için yararlı olabilir.
Nick

49
varözel değişken yapar. thisortak bir değişken yapıyor
EhevuTov

3
@AlanKis (En azından bazı Javascript motorlarında) yığın izlemesi anonim işlev durumunda bile Foobelirtilmezken, ikinci durumda Fooçağrıldığını bilecektir . Hata ayıklama için çok yararlı.
Joachim Isaksson

248

JavaScript'te bazen OOP benzeri davranışlar için kullandığım bir şablon. Gördüğünüz gibi kapanışları kullanarak özel (hem statik hem de örnek) üyeleri simüle edebilirsiniz. Ne new MyClass()dönecektir atanmış yalnızca özelliklere sahip bir nesnedir thisnesne ve içinde prototypenesnesi "sınıfına."

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
        // private
        var id = nextId++;
        var name = 'Unknown';

        // public (this instance only)
        this.get_id = function () { return id; };

        this.get_name = function () { return name; };
        this.set_name = function (value) {
            if (typeof value != 'string')
                throw 'Name must be a string';
            if (value.length < 2 || value.length > 20)
                throw 'Name must be 2-20 characters long.';
            name = value;
        };
    };

    // public static
    cls.get_nextId = function () {
        return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
        announce: function () {
            alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
                  'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
        }
    };

    return cls;
})();

Bu kalıbı kullanarak kalıtım hakkında bana soru soruldu, işte gidiyor:

// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
    // We use an intermediary empty constructor to create an
    // inheritance chain, because using the super class' constructor
    // might have side effects.
    var construct = function () {};
    construct.prototype = superCls.prototype;
    cls.prototype = new construct;
    cls.prototype.constructor = cls;
    cls.super = superCls;
}

var MyChildClass = (function () {
    // constructor
    var cls = function (surName) {
        // Call super constructor on this instance (any arguments
        // to the constructor would go after "this" in call(…)).
        this.constructor.super.call(this);

        // Shadowing instance properties is a little bit less
        // intuitive, but can be done:
        var getName = this.get_name;

        // public (this instance only)
        this.get_name = function () {
            return getName.call(this) + ' ' + surName;
        };
    };
    inherit(cls, MyClass); // <-- important!

    return cls;
})();

Ve hepsini kullanmak için bir örnek:

var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"

var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"

alert(john instanceof MyClass); // true

Gördüğünüz gibi, sınıflar birbirleriyle doğru bir şekilde etkileşime giriyorlar (statik kimliği paylaşıyorlar MyClass, announceyöntem doğru get_nameyöntemi kullanıyor vb.)

Dikkat edilmesi gereken bir şey, örnek özelliklerinin gölgelenmesi gerektiğidir. Aslında, inheritişlevin , işlev olan tüm örnek özelliklerinden (kullanma hasOwnProperty) geçmesini sağlayabilir ve otomatik olarak bir super_<method name>özellik ekleyebilirsiniz . Bu, this.super_get_name()onu geçici bir değerde saklamak yerine kullanarak çağırmanıza izin verir call.

Prototip üzerindeki yöntemler için, yukarıdakiler hakkında endişelenmenize gerek yoktur, ancak süper sınıfın prototip yöntemlerine erişmek istiyorsanız, sadece arayabilirsiniz this.constructor.super.prototype.methodName. Daha az ayrıntılı yapmak istiyorsanız, elbette kolaylık özellikleri ekleyebilirsiniz. :)


7
cls.prototypeParça hakkında sadece bir not : "örnekler arasında paylaşılan" yalnızca değeri okumak (arama announce) içindir. myClassInstance.announceBaşka bir değere ayarlarsanız , içinde yeni bir özellik oluşturur myClassInstance, bu nedenle sınıfın diğer örnekleri için değil, yalnızca bu nesne için geçerlidir. Ancak atamak MyClass.prototype.announcetüm örnekleri etkileyecektir.
Matthew Crumley

1
Sorun değil, yardım etmekten memnunum! :)
Blixt

2
Teşekkür ederim! Çok Beğendim! Bu yaklaşımda sınıf mirası örneği gösterebilir misiniz?
Dmitrij Golubev

2
@DmitrijGolubev, Brad Dwyer ve Nathan C. Tresch: Kalıtım ekledim, ancak oldukça karmaşıklaşıyor, bu yüzden JavaScript'te bu kadar hardcore mirasa ihtiyacınız yoksa genellikle daha basit bir çözümle gitmenizi tavsiye ederim (ki bu sadece prototip dili).
Blixt

1
@guiomie Bu bir "genel statik" yöntemdir, bu yüzden bunu yapıcı işlevinde ("sınıf") olarak adlandırırsınız, örnek olarak değil:MyClass.get_nextId()
Blixt

166

Bana öyle geliyor ki birçoğunuz bir kurucu değil, alıcılar ve ayarlayıcılar örneği veriyorsunuz, yani http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) .

lunched-dan daha yakındı ama örnek jsFiddle'da işe yaramadı.

Bu örnek, yalnızca nesnenin oluşturulması sırasında çalışan özel bir yapıcı işlevi oluşturur.

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   var __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

Genel özellikler atamak istiyorsanız, kurucu şöyle tanımlanabilir:

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   var __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black

45
Bu nasıl 1 numaralı cevap değil? Sadece Jon, parametreleri olan bir yapıcı yarattı.
Rap

1
Yapımcılar için bu paradigmayı kullanarak kalıtım örneği almamızın bir yolu var mı?
Nathan C. Tresch

1
@Rap Jon'un yapıcı örneğinde Box()işlev olduğu için parametre yoktur :). Ancak bu örnek ve diğer cevaplardaki örnekler parametreleri kabul etmek için kolayca genişletilebilir.
Alexander Stepaniuk

2
@AndersonGreen, Box'a bir parametre ekleyebilir ve daha sonra bir fonksiyon parametresi olarak özel yapıcıya iletebilirsiniz.
Gautham C.Ağustos

1
"Özel yapımcılara" gerek yok. Yapmanız gereken sadece Boxişlevini yapmak ve gitmek için iyi (hala "özel"). Javascript'teki "Özel" kelimesine sözcük alanı üzerinden erişilebileceği anlamına gelir; üyelere atanmasına gerek yok. Ayrıca: bu kod yanlış. Küresel bir __constructdeğişken yaratır , ki bu oldukça kötüdür. varkapsamını kısıtlamak için kullanılmalıdır __construct.
mattbasta

23

Peki "yapıcı" mülkiyetin anlamı nedir? Nerede yararlı olabileceğini, herhangi bir fikri bulamıyor musunuz?

Constructor özelliğinin amacı, JavaScript sınıfları gibi davranmanın bir yolunu sağlamaktır. Eğer şeylerden biri olamaz yararlı yapmak oluşturulduktan geçirildikten sonra bir nesnenin yapıcısı değiştirmektir. Karmaşık.

Birkaç yıl önce üzerinde oldukça kapsamlı bir parça yazdım: http://joost.zeekat.nl/constructors-considered-mildly-confusing.html


Mesele "yeni" anahtar kelimeyi kullanmaktır. "d = new Drofto ()" boş bir nesne oluşturur ve Drofto işlevini "this" olarak sınırlanmış yeni nesne ile çalıştırır. Drofto işlevi herhangi bir şeyi döndürmekte serbesttir, ancak Drofto sınıfının bir üyesi olarak kabul edilecek bir şeyi döndürmek gelenekseldir.
Juan Lanus

16

Burada örnek: http://jsfiddle.net/FZ5nC/

Bu şablonu deneyin:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
  v1: null
 ,v2: null
 ,f1: function Name_Space_ClassName_f1(){}
}

//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;

//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>

Statik bir sınıf tanımlıyorsanız, ad alanınızı ayarlamanız gerekir:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

Örnek sınıf:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
    this.Width = width;
    this.Height = height;
    this.Color = color;
}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
  Width: null
 ,Height: null
 ,Color: null
 ,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext("2d");
    context.fillStyle = this.Color;
    context.fillRect(x, y, this.Width, this.Height);
 }
}

//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;

//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
    return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
    return new Shape.Rectangle(50,25,'#ff0000');
}
</script>

Örnek örnekleme:

<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");

var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);

var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);

Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>

Uyarı işlevleri AB = işlev A_B () olarak tanımlanır. Bu, betiğinizin hata ayıklamasını kolaylaştırmak içindir. Chrome'un Öğeyi Denetle panelini açın, bu komut dosyasını çalıştırın ve hata ayıklama geri izini genişletin:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};

//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
    A.Func.That.Does.Not.Exist();
}

Fail.Test();
</script>

Örnek eklendi. Ayrıca hata ayıklama çıktısını geliştirme hakkında bilgi eklendi.
bitlather

1
Muhtemelen soruna gereksiz bir karmaşıklık kattığı için. Bilgiçlik yanlısı boşluk ve statik sınıf bildirimi nedeniyle cevabınızı yazınızda bulmak zordur. Beni yanlış anlamayın, bu iyi bir bilgi ama anlayış kapısında bir ayak almaya çalışıyorsanız kesinlikle yararlı olmaktan daha kafa karıştırıcı. JS'de yarı yetkinim ve burada ne yaptığınızı veya bunun neden "Oluşturucu nasıl yapılır?"
Bmo

1
İçgörü için teşekkürler, Bmo. Uzun bir yazıydı, ancak iyi tanımlanmış bir nesneye ve statik sınıf uygulamasına bağlı değilse bir kurucu kullanımını anlamıyorum. C ++ veya Java öğrenirken, yapıcıların nasıl uygulanacağının yanı sıra sınıfların nasıl uygulanacağını da öğrenmeniz gerekir. Web geliştirme bu javascript yazma yöntemi tökezledi beri çok daha keyifli hale geldi ve sadece paylaşmak istedim. Kemanı yukarı taşıdım, böylece bulmak daha kolay. Umarım bu durum karışıklığı netleştirir.
bitlather

1
@Bmo ad alanı ile ilgili iki satır özellikle aşağıda yorum yapıcı verildi, tam olarak yapıcı bulmak zor yapar ciddi - DOSYA ÜSTÜNDE OLMALIDIR? İsim alanı ile bir örnek vermek çok hoş, javascript dev topluluğu, adlar çakıştığında bulmak zor hatalara neden olan ad alanlarını körü körüne yok sayar. Js devs'in internetteki bir gönderiden bir metin parçası kopyalayıp, işlerine ihtiyaç duyduklarına benzer bir şey yaptıklarını düşündüklerini görmek üzücü.
user3285954

1
Genel olarak js ve web geliştirme ile ilgili en büyük sorun, geliştiricilerin çoğunun endüstrinin 50+ yıl içinde yarattığı tüm uygulamaları görmezden gelmesi ve ajax çağrısı yapabilmeleri için kral olduklarını düşünmeleridir. Javascript'te iyi bilinen kalıpları ve uygulamaları kullanmaya başlamak çok uzun zaman aldı görmek çok üzücü.
user3285954

10

Bu bir kurucu:

function MyClass() {}

Ne zaman yaparsın

var myObj = new MyClass();

MyClass yürütülür ve bu sınıftan yeni bir nesne döndürülür.


1
Açıklığa kavuşturmak için, bunun ne anlama geldiğini sınıfınızın en üstünde söyleyebilirsiniz alert(valuePassedInAsArgument);ve bu her örnekleme için bir kez çalışacaktır, bu yüzden tüm sınıf kurucunun kendisidir.
Martin Lyne

new object is returned of that class- daha çok bu işlevin yeni bir nesnesi döndürülmüş gibi değil mi?
Don Cheadle

Javascript fonksiyonları nesneler vardır
Leo

8

Bu dersi çok faydalı buldum. Bu yaklaşım, jQuery eklentilerinin çoğu tarafından kullanılır.

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

Şimdi,

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"

10
İnsanları ne zaman kullandığımı görüyorumklass
Madbreaks

8

Bu desen bana iyi hizmet etti. Bu kalıpla, ayrı dosyalarda sınıflar oluşturur ve bunları "gerektiği gibi" genel uygulamanıza yüklersiniz.

// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};

// "Package" 
// Similar to how you would establish a package in other languages
(function() {

// "Class"
var MyClass = function(params) {
    this.initialize(params);
}

    // "Private Static" vars 
    //    - Only accessible to functions in this class.
    //    - Doesn't get wiped out when we create a new instance.
    var countInstances = 0;
    var allInstances = [];

    // "Private Static" functions 
    //    - Same as above, but it's a function accessible 
    //      only to other functions in this class.
    function doSomething(){
    }

    // "Public Static" vars
    //    - Everyone has access.
    //    - Doesn't get wiped out when we create a new instance.
    MyClass.counter = 0;

    // "Public Static" functions
    //    - Same as above, but anyone can call this "static method".
    //    - Kinda like a singleton class situation.
    MyClass.foobar = function(){
    }

    // Public properties and methods are built into the "prototype"
    //    - This is how each instance can become unique unto itself.
    //    - Establishing "p" as "local" (Static Private) variable 
    //      simply so we don't have to keep typing "MyClass.prototype" 
    //      for each property and function.
var p = MyClass.prototype;

    // "Public" vars
    p.id = null;
    p.firstname = null;
    p.lastname = null;

    // "Private" vars
    //    - Only used by "this" instance.
    //    - There isn't "true" privacy for each 
    //      instance so we have to fake it. 
    //    - By tradition, we indicate "privacy"  
    //      by prefixing it with an underscore. 
    //    - So technically, anyone can access, but we simply 
    //      don't tell anyone about it (e.g. in your API)
    //      so no one knows about it :)
    p._foo = null;

    p.initialize = function(params){
        this.id = MyClass.counter++;
        this.firstname = params.firstname;
        this.lastname = params.lastname;
        MyClass.counter++;
        countInstances++;
        allInstances.push(this);
    }

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ".  Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
    }


// Assign class to app
myApp.MyClass = MyClass;

// Close the "Package"
}());

// Usage example:
var bob = new myApp.MyClass({   firstname   :   "bob",
                                lastname    :   "er"
                            });

bob.doAlert("hello there");

Bunlar örnek değişkenleridir, ancak C ++ veya Java'da olduğu gibi "özel" değil "genel" erişilebilirliğe sahiptirler.
Potatoswatter

Örneğe göre olan, ancak tüm örneklerde ortak olmayan özel bir değişken (klasik anlamda) oluşturmaya nasıl devam edersiniz?
bob

Douglas Crockford'un sitesine bakın , dil tasarımcılarından biri ve en önde gelen otorite. Her zaman onun kalıplarını takip etmiyorum, ancak genel olarak özel bir değişken varyapıcıda (veya işlev bağımsız değişkeninde veya yapıcı benzeri bir işlevde) yereldir .
Ocak'ta Potatoswatter

Bahşiş için teşekkürler ... bir sonraki sayfada ne aradığımı açıklıyor: javascript.crockford.com/private.html
bob

Oh, bağlantıyı test etmediğim için özür dilerim: P
Potatoswatter


6

Ben henüz kimse kapatma kullanmıyor çünkü sanırım javascript kapatma ile ne yapacağımı göndereceğim.

var user = function(id) {
  // private properties & methods goes here.
  var someValue;
  function doSomething(data) {
    someValue = data;
  };

  // constructor goes here.
  if (!id) return null;

  // public properties & methods goes here.
  return {
    id: id,
    method: function(params) {
      doSomething(params);
    }
  };
};

Bu çözüm için görüş ve önerilerinizi bekliyoruz. :)


1
Birkaç yorum: 1) ifadesi (! İd) güvenli değilse, 0 veya false gibi değerler, bunun true değerini değerlendirmesine ve null değerini döndürmesine neden olur. Bu durumda === null ve === undefined daha iyi olurdu tanımsız veya null olup olmadığını kontrol etmek istediğiniz tahmin ediyorum. 2) Bu, bir kurucuya göre Modül desenine ( yeterince uygun ) ( yeterince yeterli ) bir yapıcı bir nesne döndürürken yeni anahtar kelimeyle eşleştirdiğinizde, bu durumda bir nesne yerine 'bu' değerlerini ayarlamış olursunuz.
Zengin

4

Yukarıdaki Nick'in numuneyi kullanarak, nesneler için bir kurucu oluşturabilir olmadan da nesne tanımında geçen ifadesi olarak bir dönüş ifadesini kullanarak parametreleri. Yapıcı işlevinizi aşağıdaki gibi döndürün ve nesneyi her oluşturduğunuzda kodu __construct içinde çalıştırır:

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();

1
Yapıcı işlevini döndürmüyorsunuz, sadece çağırıyorsunuz.
David Conrad

this.getColor();Yukarıdaki satırda kullanmaya çalışırsanız alert("Object Created.");hiçbir şey uyarılmaz. "GetColor tanımlanmadı" gibi bir hata oluşacaktır. Yapının nesnedeki diğer yöntemleri çağırabilmesini istiyorsanız, diğer tüm yöntemlerden sonra tanımlanması gerekir. Yani __construct();son hatta çağırmak yerine sadece orada inşa tanımlamak ve ()sonra otomatik yürütmek için zorla koymak .
thinsoldier

Düzeltme. ()__Construct tanımının sonuna eklenmesi hala hatayla sonuçlandı. __construct();Hatayı önlemek için orijinal kodda olduğu gibi kendi hattında aramak zorunda kaldım .
thinsoldier

4

Belki biraz daha basit oldu, ancak 2017'de şu an ortaya koyduğum şey:

class obj {
  constructor(in_shape, in_color){
    this.shape = in_shape;
    this.color = in_color;
  }

  getInfo(){
    return this.shape + ' and ' + this.color;
  }
  setShape(in_shape){
    this.shape = in_shape;
  }
  setColor(in_color){
    this.color = in_color;
  }
}

Yukarıdaki sınıfı kullanırken, aşağıdakilere sahibim:

var newobj = new obj('square', 'blue');

//Here, we expect to see 'square and blue'
console.log(newobj.getInfo()); 

newobj.setColor('white');
newobj.setShape('sphere');

//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());

Gördüğünüz gibi, yapıcı iki parametre alır ve nesnenin özelliklerini ayarlıyoruz. Ayrıca, setterişlevleri kullanarak nesnenin rengini ve şeklini değiştiririz ve getInfo()bu değişikliklerden sonra değişimin değiştiğini kanıtlarız .

Biraz geç, ama umarım bu yardımcı olur. Bunu mochabirim testi ile test ettim ve iyi çalışıyor.


3

Typescript - açık kaynak kodlu MicroSoft kullanıyorsanız yaparlar :-)

class BankAccount {
 balance: number;
 constructor(initially: number) {
 this.balance = initially;
 }
 deposit(credit: number) {
 this.balance += credit;
 return this.balance;
 }
}

Typcript, javascript yapılarına derlenen OO yapılarını 'sahte' hale getirmenizi sağlar. Büyük bir projeye başlıyorsanız, size çok zaman kazandırabilir ve henüz kilometre taşı 1.0 sürümüne ulaşmıştır.

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

Yukarıdaki kod 'derlenir':

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();

Büyük bir proje üzerinde çalışıyorum ve insanları TypeScript'in çalışan bir çekim yapacağına ikna etmeye çalışıyorum. Bunun nasıl gittiğini göreceğiz.
wootscootinboogie

@wootscootinboogie Bir günde (şu anda saat 5.30'da bitiyor) onunla oldukça uzak ve oldukça rahatım. Spesifikasyonları okumanızı şiddetle tavsiye ederim ve en az bir kez okumak için kendinize bir iyilik yaptığınız gerçek nitritli şeylerin yarısını atlayabilirsiniz. bu adamın videoları mükemmel youtube.com/user/basaratali/videos . iyi şanslar)
Simon_Weaver

1

JavaScript'te çağırma türü işlevin davranışını tanımlar:

  • Doğrudan çağırma func()
  • Bir nesne üzerinde yöntem çağırma obj.func()
  • Yapıcı çağırmanew func()
  • Dolaylı çağrı func.call()veyafunc.apply()

İşleç kullanılarak çağrı yaparken işlev yapıcı olarak çağrılır new:

function Cat(name) {
   this.name = name;
}
Cat.prototype.getName = function() {
   return this.name;
}

var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

JavaScript'teki herhangi bir örnek veya prototip nesnesi constructor, yapıcı işlevine başvuran bir özelliğe sahiptir.

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

Yapıcı özelliği hakkında bu gönderiyi kontrol edin .


0

Blixt'in harika şablonunu yukarıdan kullanırken, çok seviyeli kalıtımla (MyGhCCildClass genişletme MyChildClass genişletme MyClass) iyi çalışmadığını öğrendim - ilk ebeveynin yapıcısını tekrar tekrar çağırmaya devam ediyor. İşte basit bir çözüm - eğer böyle tanımlanmış zincir fonksiyonu ile this.constructor.super.call(this, surName);kullanmak yerine, çok seviyeli mirasa ihtiyacınız varsa chainSuper(this).call(this, surName);:

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}

0

http://www.jsoops.net/ Js'teki oop için oldukça iyi. Özel, korumalı, ortak değişken ve işlev ve ayrıca Kalıtım özelliği sağlarsa. Örnek Kod:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public

    pri.className = "I am A ";

    this.init = function (var1)// constructor
    {
        pri.className += var1;
    }

    pub.getData = function ()
    {
        return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
        + ", ID=" + pro.getClassId() + ")";
    }

    pri.getClassName = function () { return pri.className; }
    pro.getClassName = function () { return pri.className; }
    pro.getClassId = function () { return 1; }
});

var newA = new ClassA("Class");

//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)

//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined

0

sadece biraz çeşitlilik sunmak için. ds.oop , javascript içinde kurucuları olan sınıfları bildirmenin güzel bir yoludur. Olası her türlü kalıtım türünü (c # bile desteklemeyen 1 tür dahil) ve güzel arayüzleri destekler.

var Color = ds.make.class({
    type: 'Color',
    constructor: function (r,g,b) { 
        this.r = r;                     /* now r,g, and b are available to   */
        this.g = g;                     /* other methods in the Color class  */
        this.b = b;                     
    }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class

0

Burada java betiğinde bir noktayı fark etmeliyiz, sınıfsız bir dildir, ancak java betiğindeki işlevleri kullanarak bunu başarabiliriz. Bunu başarmanın en yaygın yolu, java komut dosyasında bir işlev oluşturmanız ve bir nesne oluşturmak için yeni anahtar kelime kullanmamız ve özellik ve yöntemleri tanımlamak için bu anahtar kelimeyi kullanmamız gerekir.

// Function constructor

   var calculator=function(num1 ,num2){
   this.name="This is function constructor";
   this.mulFunc=function(){
      return num1*num2
   };

};

var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call

//Constructors With Prototypes

var calculator=function(){
   this.name="Constructors With Prototypes";
};

calculator.prototype.mulFunc=function(num1 ,num2){
 return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call

-2

Çoğu durumda, bu bilgileri ileten bir yöntemi çağırabilmeniz için bir şekilde ihtiyacınız olan özelliği bildirmeniz gerekir. Başlangıçta bir özellik ayarlamanız gerekmiyorsa, nesne içindeki bir yöntemi böyle çağırabilirsiniz. Muhtemelen bunu yapmanın en güzel yolu değil, ama yine de işe yarıyor.

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.