2016-02-13 14 views
5

Mam trzy sposoby na wykonanie funkcji i zwrócenie jej. (Może jest coś więcej?), Ale nie znam różnic między nimi i kiedy z nich korzystać. Czy ktoś mógłby wyjaśnić.Trzy różne sposoby korzystania z funkcji javascript, ale nie znam plusów i minusów. Czy ktoś mógłby wyjaśnić różnice?

var test1 = function() { 
    var funk1 = function() { 
     console.log(1); 
    } 
    var funk2 = function(msg) { 
     console.log(msg); 
    } 
    return { 
     funk1: funk1, 
     funk2: funk2 
    } 
}; 

var test2 = function() { 
    this.funk1 = function() { 
     console.log(1); 
    } 
    this.funk2 = function(msg) { 
     console.log(msg); 
    } 
}; 

var someThing = test1(); 
someThing.funk1(); 
someThing.funk2(2); 

var someThing = new test1(); 
someThing.funk1(); 
someThing.funk2(2); 

var thingElse = new test2(); 
thingElse.funk1(); 
thingElse.funk2(2); 
+0

przejdź do samouczków dotyczących wzorców. Mnóstwo samouczków z wyjaśnieniami, dlaczego są dobre i złe. – epascarello

Odpowiedz

4

to wzór moduł/biblioteki/wtyczki

var test1 = function() { 
    var funk1 = function() { 
     console.log(1); 
    } 
    return { 
     funk1: funk1 
    } 
}; 

to OOP (programowanie obiektowe-) wzór

var test2 = function() { 
    this.funk1 = function() { 
     console.log(1); 
    } 
}; 

Różnica

var t = test1() //function call, t is result of test1 function execution 
var t = new test1() //instance initialization, t is instance of test1 class 

Rozważmy to prosty model

Mamy producenta, który produkuje samochody, producent ma pewne metody, a samochód ma swoje własne metody, nie będziemy modyfikować właściwości użytkowych producenta, ale nadal nie możemy uzyskać dostępu do technologii, której producent używa do stworzenia samochodu , więc samochód jest czarną skrzynką, która eksponuje niektóre publiczne rekwizyty i nie można go modyfikować.

//service for creating/controlling manufactorer 
var ManufacturerService = function(companyName) { 
    var self = this; 
    self.companyName = companyName; 

    //encapsulation 
    var Car = function(name, number){ 
     var createdAt = new Date(); 
     var engineStarts = 0; 

     //instance property, doesn't have setter 
     Object.defineProperty(this, 'info', { 
      get: function(){ 
       return { 
        name: name, 
        createdAt: createdAt, 
        engineStarts: engineStarts 
       } 
      } 
     }); 

     //instance method 
     this.startEngine = function(){ 
      //private property, available only on instance, and cannot be extracted 
      engineStarts++; 

      //reference to ManufacturerService.companyName 
      console.log(self.companyName + ' ' + name + ':' + number + ' engine Started'); 
     } 
    } 
    var createCar = function(name){ 
     //check cache/duplication/validation 
     //or use custom behavior 
     var carNumber = ManufacturerService.genShortUid(); 
     return new Car(name, carNumber); 
    } 
    var getName = function(){ 
     return self.companyName; 
    } 
    return { 
     getName: getName, 
     createCar: createCar 
    } 
}; 
//static method, this can be overriden by 3rdParty or user 
ManufacturerService.genShortUid = function genShortUid() { 
    return ('0000' + (Math.random()*Math.pow(36,4) << 0).toString(36)).slice(-4); 
} 

użytkowania urządzenia, ManufacturerService jest napisany jako plugin/biblioteki, ale zauważ, że model samochodu jest całkowicie zamknięty, co oznacza, że ​​model jest całkowicie ukryty przed światem zewnętrznym

//create a service instance 
var VolvoCompany = new ManufacturerService('Volvo'); 

//access encapsulated Car model by createCar method 
//which is available only on instance of service 
var Golf = VolvoCompany.createCar('Golf'); 

//instance method of car Model 
Golf.startEngine(); //logs Volvo Golf:vnv6 engine Started 

Golf.info 
//returns 
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1} 

//try to hack car instance 
Golf.info.name = 'test'; 
Golf.name = 'test'; 

Golf.info 
//returns same object, as Car model doesn't have exported setters 
Object {name: "Golf", createdAt: Sat Feb 13 2016 17:39:57 GMT+0600 (ALMT), engineStarts: 1}  

//customize guid generator of ManufacturerService 
ManufacturerService.genShortUid = function(){ 
    return '1111'; 
} 

//reuse same service for another Car model 
var Mazda = VolvoCompany.createCar('Mazda'); 

//instance method of car Model 
Mazda.startEngine(); //logs Volvo Mazda:1111 engine Started 

Podsumowanie

ManufacturerService eksport ograniczona liczba metod i całkowicie otwarta, ale instancja jest całkowicie zamknięta, a nawet niewidoczna.

Edycja/sugestie/komentarze są mile widziane

+0

Czy istnieje różnica między test1() a nowym test1()? powinni zrobić dokładnie to samo, prawda? – pailhead

+0

'new test1()' jest inicjalizacją instancji, 'test1()' jest po prostu wywołaniem funkcji –

+0

w prawo, ale oba zwracają obiekt dosłownie, z zamknięciem. Domyślam się, o co pytam, tytuł mówi "trzy różne ...", ale wydaje się, że ma tylko dwa różne sposoby. Pierwsze dwa wydają się takie same. Innym sposobem byłoby użycie test1 jako singleton, przez wykonanie Ththing = test1 zamiast wywoływania funkcji. Ponieważ nie ma nic w zamknięciu, które nie jest odsłonięte, i nic, co mogłoby zmienić zachowanie tych funkcji, ten właśnie może być po prostu użyty w ten sposób. – pailhead

Powiązane problemy