Apa cara paling sederhana / paling bersih untuk menerapkan pola singleton dalam JavaScript?
Apa cara paling sederhana / paling bersih untuk menerapkan pola singleton dalam JavaScript?
Jawaban:
Saya pikir cara termudah adalah dengan mendeklarasikan objek literal sederhana:
var myInstance = {
method1: function () {
// ...
},
method2: function () {
// ...
}
};
Jika Anda ingin anggota pribadi menggunakan instance tunggal Anda, Anda dapat melakukan sesuatu seperti ini:
var myInstance = (function() {
var privateVar = '';
function privateMethod () {
// ...
}
return { // public interface
publicMethod1: function () {
// all private members are accessible here
},
publicMethod2: function () {
}
};
})();
Ini telah disebut dengan pola modul , pada dasarnya memungkinkan Anda untuk merangkum anggota pribadi pada objek, dengan mengambil keuntungan dari penggunaan penutupan .
UPDATE: Saya ingin menambahkan bahwa jika Anda ingin mencegah modifikasi objek singleton, Anda dapat membekukannya , menggunakan Object.freeze
metode ES5 .
Itu akan membuat objek tidak berubah, mencegah modifikasi pada struktur dan nilainya.
Selain itu saya ingin menyebutkan bahwa jika Anda menggunakan ES6, Anda dapat mewakili singleton menggunakan Modul ES dengan sangat mudah, dan Anda bahkan dapat memegang status privat dengan mendeklarasikan variabel pada cakupan modul :
// my-singleton.js
const somePrivateState = []
function privateFn () {
// ...
}
export default {
method1() {
// ...
},
method2() {
// ...
}
}
Kemudian Anda bisa mengimpor objek singleton untuk menggunakannya:
import myInstance from './my-singleton.js'
// ...
publicMethod1
menelepon publicMethod2
?
getInstance
metode statis , dan konstruktor pribadi-, tapi IMO, ini adalah cara paling "sederhana" untuk membangun objek singleton dalam Javascript, dan pada akhirnya memenuhi tujuan yang sama-objek tunggal, yang Anda tidak dapat menginisialisasi lagi (tidak ada konstruktor, itu hanya sebuah objek) -. Tentang kode yang Anda tautkan, ada beberapa masalah, tukar a
dan b
deklarasi variabel dan pengujian a === window
. Bersulang.
Saya pikir pendekatan terbersih adalah sesuatu seperti:
var SingletonFactory = (function(){
function SingletonClass() {
//do stuff
}
var instance;
return {
getInstance: function(){
if (instance == null) {
instance = new SingletonClass();
// Hide the constructor so the returned object can't be new'd...
instance.constructor = null;
}
return instance;
}
};
})();
Setelah itu, Anda dapat memanggil fungsi sebagai
var test = SingletonFactory.getInstance();
delete instance.constructor
:x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
Saya tidak yakin saya setuju dengan pola modul yang digunakan sebagai pengganti pola tunggal. Saya sering melihat lajang digunakan dan dilecehkan di tempat-tempat di mana mereka sama sekali tidak perlu, dan saya yakin pola modul mengisi banyak celah di mana programmer akan menggunakan singleton, namun pola modul bukan singleton.
var foo = (function () {
"use strict";
function aPrivateFunction() {}
return { aPublicFunction: function () {...}, ... };
}());
Segala sesuatu yang diinisialisasi dalam pola modul terjadi ketika Foo
dideklarasikan. Selain itu, pola modul dapat digunakan untuk menginisialisasi konstruktor, yang kemudian dapat dipakai beberapa kali. Sementara pola modul adalah alat yang tepat untuk banyak pekerjaan, itu tidak setara dengan singleton.
var Foo = function () {
"use strict";
if (Foo._instance) {
//this allows the constructor to be called multiple times
//and refer to the same instance. Another option is to
//throw an error.
return Foo._instance;
}
Foo._instance = this;
//Foo initialization code
};
Foo.getInstance = function () {
"use strict";
return Foo._instance || new Foo();
}
bentuk panjang, menggunakan pola modul
var Foo = (function () {
"use strict";
var instance; //prevent modification of "instance" variable
function Singleton() {
if (instance) {
return instance;
}
instance = this;
//Singleton initialization code
}
//instance accessor
Singleton.getInstance = function () {
return instance || new Singleton();
}
return Singleton;
}());
Di kedua versi pola Singleton yang saya berikan, konstruktor itu sendiri dapat digunakan sebagai accessor:
var a,
b;
a = new Foo(); //constructor initialization happens here
b = new Foo();
console.log(a === b); //true
Jika Anda merasa tidak nyaman menggunakan konstruktor seperti ini, Anda bisa melempar kesalahan dalam if (instance)
pernyataan, dan tetap menggunakan form panjang:
var a,
b;
a = Foo.getInstance(); //constructor initialization happens here
b = Foo.getInstance();
console.log(a === b); //true
Saya juga harus menyebutkan bahwa pola singleton cocok dengan pola fungsi konstruktor implisit:
function Foo() {
if (Foo._instance) {
return Foo._instance;
}
//if the function wasn't called as a constructor,
//call it as a constructor and return the result
if (!(this instanceof Foo)) {
return new Foo();
}
Foo._instance = this;
}
var f = new Foo(); //calls Foo as a constructor
-or-
var f = Foo(); //also calls Foo as a constructor
var singleton = {}
tidak sesuai dengan definisi itu.
var singleton = {}
adalah bagaimana Anda menerapkan singleton dalam Javascript .
Dalam es6
:
class Singleton {
constructor () {
if (!Singleton.instance) {
Singleton.instance = this
}
// Initialize object
return Singleton.instance
}
// Properties & Methods
}
const instance = new Singleton()
Object.freeze(instance)
export default instance
instance
bidang. Seperti saat ini ( instance
diatur ke this
) kelas ini mungkin memiliki bidang lain juga dan pembekuan tidak masuk akal.
Berikut ini berfungsi di simpul v6
class Foo {
constructor(msg) {
if (Foo.singleton) {
return Foo.singleton;
}
this.msg = msg;
Foo.singleton = this;
return Foo.singleton;
}
}
Kami menguji:
const f = new Foo('blah');
const d = new Foo('nope');
console.log(f); // => Foo { msg: 'blah' }
console.log(d); // => Foo { msg: 'blah' }
Dalam ES6 cara yang tepat untuk melakukan ini adalah:
class MyClass {
constructor() {
if (MyClass._instance) {
throw new Error("Singleton classes can't be instantiated more than once.")
}
MyClass._instance = this;
// ... your rest of the constructor code goes after this
}
}
var instanceOne = new MyClass() // Executes succesfully
var instanceTwo = new MyClass() // Throws error
Atau, jika Anda tidak ingin kesalahan dilemparkan pada pembuatan instance kedua, Anda bisa mengembalikan instance terakhir, seperti:
class MyClass {
constructor() {
if (MyClass._instance) {
return MyClass._instance
}
MyClass._instance = this;
// ... your rest of the constructor code goes after this
}
}
var instanceOne = new MyClass()
var instanceTwo = new MyClass()
console.log(instanceOne === instanceTwo) // logs "true"
instance
dan _instance
. Itu hanya konvensi penamaan dalam bahasa pemrograman yang kami beri nama variabel pribadi yang diawali dengan garis bawah. Saya menduga alasan kode Anda untuk tidak berfungsi adalah karena Anda menggunakan this.instance
alih-alihMyClass.instance
Ada lebih dari satu cara untuk menguliti kucing :) Tergantung pada selera atau kebutuhan spesifik Anda, Anda dapat menerapkan salah satu solusi yang diusulkan. Saya pribadi mencari solusi pertama CMS bila memungkinkan (ketika Anda tidak membutuhkan privasi). Karena pertanyaannya adalah yang paling sederhana dan paling bersih, itulah pemenangnya. Atau bahkan:
var myInstance = {}; // done!
Ini (kutipan dari blog saya) ...
var SingletonClass = new function() {
this.myFunction() {
//do stuff
}
this.instance = 1;
}
tidak masuk akal (contoh blog saya juga tidak) karena tidak memerlukan vars pribadi, jadi hampir sama dengan:
var SingletonClass = {
myFunction: function () {
//do stuff
},
instance: 1
}
this.f(){}
Saya mencela jawaban saya, melihat jawaban saya yang lain .
Biasanya pola modul (lihat jawaban CMS) yang BUKAN pola tunggal cukup baik. Namun salah satu fitur singleton adalah inisialisasi tertunda hingga objek diperlukan. Pola modul tidak memiliki fitur ini.
Proposisi saya (CoffeeScript):
window.singleton = (initializer) ->
instance = undefined
() ->
return instance unless instance is undefined
instance = initializer()
Yang dikompilasi dalam JavaScript ini:
window.singleton = function(initializer) {
var instance;
instance = void 0;
return function() {
if (instance !== void 0) {
return instance;
}
return instance = initializer();
};
};
Maka saya bisa melakukan hal berikut:
window.iAmSingleton = singleton(function() {
/* This function should create and initialize singleton. */
alert("creating");
return {property1: 'value1', property2: 'value2'};
});
alert(window.iAmSingleton().property2); // "creating" will pop up; then "value2" will pop up
alert(window.iAmSingleton().property2); // "value2" will pop up but "creating" will not
window.iAmSingleton().property2 = 'new value';
alert(window.iAmSingleton().property2); // "new value" will pop up
Karena sifat non-pemblokiran JavaScript, Singletons dalam JavaScript benar-benar jelek digunakan. Variabel global akan memberi Anda satu contoh melalui seluruh aplikasi juga tanpa semua panggilan balik ini, pola modul dengan lembut menyembunyikan internal di belakang antarmuka. Lihat jawaban @CMS.
Tapi, karena Anda menginginkan seorang singleton ...
var singleton = function(initializer) {
var state = 'initial';
var instance;
var queue = [];
var instanceReady = function(createdInstance) {
state = 'ready';
instance = createdInstance;
while (callback = queue.shift()) {
callback(instance);
}
};
return function(callback) {
if (state === 'initial') {
state = 'waiting';
queue.push(callback);
initializer(instanceReady);
} else if (state === 'waiting') {
queue.push(callback);
} else {
callback(instance);
}
};
};
Pemakaian:
var singletonInitializer = function(instanceReady) {
var preparedObject = {property: 'value'};
// calling instanceReady notifies singleton that instance is ready to use
instanceReady(preparedObject);
}
var s = singleton(singletonInitializer);
// get instance and use it
s(function(instance) {
instance.doSomething();
});
Lajang memberi Anda lebih dari satu contoh melalui seluruh aplikasi: inisialisasi mereka tertunda hingga penggunaan pertama. Ini adalah hal yang sangat besar ketika Anda berurusan dengan objek yang inisialisasi mahal. Mahal biasanya berarti I / O dan dalam JavaScript I / O selalu berarti panggilan balik.
Jangan percayai jawaban yang memberi Anda antarmuka instance = singleton.getInstance()
, mereka semua kehilangan intinya.
Jika mereka tidak menerima panggilan balik untuk dijalankan ketika instance sudah siap, maka mereka tidak akan berfungsi ketika initializer melakukan I / O.
Ya, panggilan balik selalu terlihat lebih buruk daripada panggilan fungsi yang segera mengembalikan contoh objek. Tetapi sekali lagi: ketika Anda melakukan I / O, callback wajib. Jika Anda tidak ingin melakukan I / O, maka instantiation cukup murah untuk melakukannya pada awal program.
var simpleInitializer = function(instanceReady) {
console.log("Initializer started");
instanceReady({property: "initial value"});
}
var simple = singleton(simpleInitializer);
console.log("Tests started. Singleton instance should not be initalized yet.");
simple(function(inst) {
console.log("Access 1");
console.log("Current property value: " + inst.property);
console.log("Let's reassign this property");
inst.property = "new value";
});
simple(function(inst) {
console.log("Access 2");
console.log("Current property value: " + inst.property);
});
Dalam contoh ini setTimeout
memalsukan beberapa operasi I / O yang mahal. Ini menggambarkan mengapa lajang di JavaScript benar-benar membutuhkan panggilan balik.
var heavyInitializer = function(instanceReady) {
console.log("Initializer started");
var onTimeout = function() {
console.log("Initializer did his heavy work");
instanceReady({property: "initial value"});
};
setTimeout(onTimeout, 500);
};
var heavy = singleton(heavyInitializer);
console.log("In this example we will be trying");
console.log("to access singleton twice before it finishes initialization.");
heavy(function(inst) {
console.log("Access 1");
console.log("Current property value: " + inst.property);
console.log("Let's reassign this property");
inst.property = "new value";
});
heavy(function(inst) {
console.log("Access 2. You can see callbacks order is preserved.");
console.log("Current property value: " + inst.property);
});
console.log("We made it to the end of the file. Instance is not ready yet.");
Saya mendapatkan contoh ini dari Pola JavaScript Membangun Aplikasi yang Lebih Baik dengan Pola Pengodean dan Desain Oleh Stoyan Stefanov buku jika Anda memerlukan beberapa kelas implementasi sederhana seperti objek singltone Anda dapat menggunakan fungsi langsung sebagai berikut:
var ClassName;
(function() {
var instance;
ClassName = function ClassName() {
//If private instance variable already initialized return reference
if(instance) {
return instance;
}
//If instance does not created save pointer of original reference
//to private instance variable.
instance = this;
//All constructor initialization will be here
// i.e.:
this.someProperty = 0;
this.someMethod = function() {
//Some action here
};
};
}());
Dan Anda dapat memeriksa contoh ini dengan mengikuti test case:
//Extending defined class like Singltone object using new prototype property
ClassName.prototype.nothing = true;
var obj_1 = new ClassName();
//Extending defined class like Singltone object using new prototype property
ClassName.prototype.everything = true;
var obj_2 = new ClassName();
//Testing does this two object pointing to same instance
console.log(obj_1 === obj_2); //Result is true, it points to same instance object
//All prototype properites work
//no matter when they were defined
console.log(obj_1.nothing && obj_1.everything
&& obj_2.nothing && obj_2.everything); //Result true
//Values of properties which is defined inside of constructor
console.log(obj_1.someProperty);// output 0
console.log(obj_2.someProperty);// output 0
//Changing property value
obj_1.someProperty = 1;
console.log(obj_1.someProperty);// output 1
console.log(obj_2.someProperty);// output 1
console.log(obj_1.constructor === ClassName); //Output true
Pendekatan ini melewati semua kasus uji sementara implementasi statis pribadi akan gagal ketika ekstensi prototipe digunakan (bisa diperbaiki tetapi tidak akan sederhana) dan implementasi statis publik kurang disarankan karena misalnya terpapar ke publik.
Saya pikir saya telah menemukan cara paling bersih untuk memprogram dalam JavaScript, tetapi Anda akan memerlukan imajinasi. Saya mendapat ide ini dari teknik kerja di buku "javascript bagian yang baik".
Alih-alih menggunakan kata kunci baru, Anda dapat membuat kelas seperti ini:
function Class()
{
var obj = {}; // Could also be used for inheritence if you don't start with an empty object.
var privateVar;
obj.publicVar;
obj.publicMethod= publicMethod;
function publicMethod(){}
function privateMethod(){}
return obj;
}
Anda dapat instantiate objek di atas dengan mengatakan:
var objInst = Class(); // !!! NO NEW KEYWORD
Sekarang dengan metode kerja ini dalam pikiran Anda dapat membuat singleton seperti ini:
ClassSingleton = function()
{
var instance= null;
function Class() // This is the class like the above one
{
var obj = {};
return obj;
}
function getInstance()
{
if( !instance )
instance = Class(); // Again no new keyword;
return instance;
}
return { getInstance : getInstance };
}();
Sekarang Anda bisa mendapatkan contoh Anda dengan menelepon
var obj = ClassSingleton.getInstance();
Saya pikir ini adalah cara yang paling rapi karena "Kelas" yang lengkap bahkan tidak dapat diakses.
@CMS dan @zzzzBov sama-sama memberikan jawaban yang bagus, tetapi hanya untuk menambahkan interpretasi saya sendiri berdasarkan saya telah pindah ke pengembangan node.js yang berat dari PHP / Zend Framework di mana pola singleton adalah umum.
Kode yang didokumentasikan komentar berikut ini didasarkan pada persyaratan berikut:
Kode saya sangat mirip dengan @ zzzzBov, kecuali saya sudah menambahkan rantai prototipe ke konstruktor dan lebih banyak komentar yang akan membantu mereka yang berasal dari PHP atau bahasa serupa menerjemahkan OOP tradisional ke sifat prototipe Javascripts. Mungkin bukan yang "paling sederhana" tapi saya percaya itu yang paling tepat.
// declare 'Singleton' as the returned value of a self-executing anonymous function
var Singleton = (function () {
"use strict";
// 'instance' and 'constructor' should not be availble in a "public" scope
// here they are "private", thus available only within
// the scope of the self-executing anonymous function
var _instance=null;
var _constructor = function (name) {
this.name = name || 'default';
}
// prototypes will be "public" methods available from the instance
_constructor.prototype.getName = function () {
return this.name;
}
// using the module pattern, return a static object
// which essentially is a list of "public static" methods
return {
// because getInstance is defined within the same scope
// it can access the "private" 'instance' and 'constructor' vars
getInstance:function (name) {
if (!_instance) {
console.log('creating'); // this should only happen once
_instance = new _constructor(name);
}
console.log('returning');
return _instance;
}
}
})(); // self execute
// ensure 'instance' and 'constructor' are unavailable
// outside the scope in which they were defined
// thus making them "private" and not "public"
console.log(typeof _instance); // undefined
console.log(typeof _constructor); // undefined
// assign instance to two different variables
var a = Singleton.getInstance('first');
var b = Singleton.getInstance('second'); // passing a name here does nothing because the single instance was already instantiated
// ensure 'a' and 'b' are truly equal
console.log(a === b); // true
console.log(a.getName()); // "first"
console.log(b.getName()); // also returns "first" because it's the same instance as 'a'
Perhatikan bahwa secara teknis, fungsi anonim yang dijalankan sendiri itu sendiri adalah Singleton sebagaimana ditunjukkan dengan baik dalam kode yang disediakan oleh @CMS. Satu-satunya tangkapan di sini adalah bahwa tidak mungkin untuk mengubah rantai prototipe konstruktor ketika konstruktor itu sendiri anonim.
Perlu diingat bahwa untuk Javascript, konsep "publik" dan "pribadi" tidak berlaku seperti di PHP atau Java. Tapi kami telah mencapai efek yang sama dengan memanfaatkan aturan Javascript tentang ketersediaan ruang lingkup fungsional.
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
Tidak yakin mengapa tidak ada yang mengemukakan ini, tetapi Anda bisa melakukannya:
var singleton = new (function() {
var bar = 123
this.foo = function() {
// whatever
}
})()
Jawaban paling jelas harus yang ini dari buku Belajar Pola Desain JavaScript oleh Addy Osmani.
var mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
// Private methods and variables
function privateMethod(){
console.log( "I am private" );
}
var privateVariable = "Im also private";
var privateRandomNumber = Math.random();
return {
// Public methods and variables
publicMethod: function () {
console.log( "The public can see me!" );
},
publicProperty: "I am also public",
getRandomNumber: function() {
return privateRandomNumber;
}
};
};
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: function () {
if ( !instance ) {
instance = init();
}
return instance;
}
};
})();
Saya percaya ini adalah cara paling sederhana / paling bersih dan paling intuitif meskipun membutuhkan ES7:
export default class Singleton { static instance; constructor(){ if(instance){ return instance; } this.state = "duke"; this.instance = this; } }
Kode sumbernya dari: adam-bien.com
new Singleton()
dapatkah saya menaruh 5 koin saya. Saya memiliki fungsi konstruktor, mis.
var A = function(arg1){
this.arg1 = arg1
};
Yang perlu saya lakukan hanyalah setiap objek yang dibuat oleh CF ini akan sama.
var X = function(){
var instance = {};
return function(){ return instance; }
}();
uji
var x1 = new X();
var x2 = new X();
console.log(x1 === x2)
Saya telah menemukan yang berikut ini sebagai pola Singleton termudah, karena menggunakan operator baru membuat ini segera tersedia dalam fungsi, menghilangkan kebutuhan untuk mengembalikan objek literal:
var singleton = new (function () {
var private = "A private value";
this.printSomething = function() {
console.log(private);
}
})();
singleton.printSomething();
Berikut adalah contoh sederhana untuk menjelaskan pola tunggal dalam javascript.
var Singleton=(function(){
var instance;
var init=function(){
return {
display:function(){
alert("This is a Singleton patern demo");
}
};
};
return {
getInstance:function(){
if(!instance){
alert("Singleton check");
instance=init();
}
return instance;
}
};
})();
// In this call first display alert("Singleton check")
// and then alert("This is a Singleton patern demo");
// It means one object is created
var inst=Singleton.getInstance();
inst.display();
// In this call only display alert("This is a Singleton patern demo")
// it means second time new object is not created,
// it uses the already created object
var inst1=Singleton.getInstance();
inst1.display();
Saya membutuhkan beberapa lajang dengan:
dan inilah yang saya pikirkan:
createSingleton ('a', 'add', [1, 2]);
console.log(a);
function createSingleton (name, construct, args) {
window[name] = {};
window[construct].apply(window[name], args);
window[construct] = null;
}
function add (a, b) {
this.a = a;
this.b = b;
this.sum = a + b;
}
args harus Array agar ini berfungsi sehingga jika Anda memiliki variabel kosong, cukup masukkan []
Saya menggunakan objek jendela dalam fungsi tetapi saya bisa melewati parameter untuk membuat ruang lingkup saya sendiri
parameter nama dan konstruk hanya String agar window [] berfungsi tetapi dengan beberapa pengecekan tipe sederhana, window.name dan window.construct juga dimungkinkan.
Bagaimana dengan cara ini, hanya memastikan kelas tidak bisa baru lagi.
Dengan ini, Anda dapat menggunakan instanceof
op, juga, Anda dapat menggunakan rantai prototipe untuk mewarisi kelas, ini adalah kelas reguler, tetapi tidak bisa baru itu, jika Anda ingin mendapatkan contoh cukup gunakangetInstance
function CA()
{
if(CA.instance)
{
throw new Error('can not new this class');
}else{
CA.instance = this;
}
}
/**
* @protected
* @static
* @type {CA}
*/
CA.instance = null;
/** @static */
CA.getInstance = function()
{
return CA.instance;
}
CA.prototype =
/** @lends CA#*/
{
func: function(){console.log('the func');}
}
// initilize the instance
new CA();
// test here
var c = CA.getInstance()
c.func();
console.assert(c instanceof CA)
// this will failed
var b = new CA();
Jika Anda tidak ingin mengekspos instance
anggota tersebut, tutup saja.
Berikut ini adalah cuplikan dari jalan saya untuk menerapkan pola tunggal. Ini terjadi pada saya selama proses wawancara dan saya merasa bahwa saya harus menangkap ini di suatu tempat.
/*************************************************
* SINGLETON PATTERN IMPLEMENTATION *
*************************************************/
//since there are no classes in javascript, every object is technically a singleton
//if you don't inherit from it or copy from it.
var single = {};
//Singleton Implementations
//Declaring as a Global Object...you are being judged!
var Logger = function() {
//global_log is/will be defined in GLOBAL scope here
if(typeof global_log === 'undefined'){
global_log = this;
}
return global_log;
};
//the below 'fix' solves the GLOABL variable problem but
//the log_instance is publicly available and thus can be
//tampered with.
function Logger() {
if(typeof Logger.log_instance === 'undefined'){
Logger.log_instance = this;
}
return Logger.log_instance;
};
//the correct way to do it to give it a closure!
function logFactory() {
var log_instance; //private instance
var _initLog = function() { //private init method
log_instance = 'initialized';
console.log("logger initialized!")
}
return {
getLog : function(){ //the 'privileged' method
if(typeof log_instance === 'undefined'){
_initLog();
}
return log_instance;
}
};
}
/***** TEST CODE ************************************************
//using the Logger singleton
var logger = logFactory();//did i just gave LogFactory a closure?
//create an instance of the logger
var a = logger.getLog();
//do some work
//get another instance of the logger
var b = logger.getLog();
//check if the two logger instances are same?
console.log(a === b); //true
*******************************************************************/
hal yang sama dapat ditemukan di halaman intisari saya
function Unicode()
{
var i = 0, unicode = {}, zero_padding = "0000", max = 9999;
//Loop through code points
while (i < max) {
//Convert decimal to hex value, find the character, then pad zeroes to the codepoint
unicode[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);
i = i + 1;
}
//Replace this function with the resulting lookup table
Unicode = unicode;
}
//Usage
Unicode();
//Lookup
Unicode["%"]; //returns 0025
Anda dapat melakukannya dengan dekorator seperti dalam contoh di bawah ini untuk TypeScript:
class YourClass {
@Singleton static singleton() {}
}
function Singleton(target, name, descriptor) {
var instance;
descriptor.value = () => {
if(!instance) instance = new target;
return instance;
};
}
Maka Anda menggunakan singleton Anda seperti ini:
var myInstance = YourClass.singleton();
Pada tulisan ini, dekorator tidak tersedia di mesin JavaScript. Anda perlu memastikan runtime JavaScript Anda memiliki dekorator yang benar-benar diaktifkan atau menggunakan kompiler seperti Babel dan TypeScript.
Juga perhatikan bahwa instance singleton dibuat "malas", yaitu, dibuat hanya ketika Anda menggunakannya untuk pertama kali.
Pola modul: dalam "gaya yang lebih mudah dibaca". Anda dapat dengan mudah melihat metode mana yang publik dan mana yang privat
var module = (function(_name){
/*Local Methods & Values*/
var _local = {
name : _name,
flags : {
init : false
}
}
function init(){
_local.flags.init = true;
}
function imaprivatemethod(){
alert("hi im a private method");
}
/*Public Methods & variables*/
var $r = {}; //this object will hold all public methods.
$r.methdo1 = function(){
console.log("method1 call it");
}
$r.method2 = function(){
imaprivatemethod(); //calling private method
}
$r.init = function(){
inti(); //making init public in case you want to init manually and not automatically
}
init(); //automatically calling init method
return $r; //returning all publics methods
})("module");
sekarang Anda dapat menggunakan metode publik seperti
module.method2 (); // -> Saya memanggil metode pribadi melalui peringatan metode publik ("Hai, metode pribadi")
Singleton:
Pastikan kelas hanya memiliki satu instance dan memberikan titik akses global untuk itu.
Pola Singleton membatasi jumlah instance objek tertentu menjadi hanya satu. Contoh tunggal ini disebut singleton.
Objek Singleton diimplementasikan sebagai fungsi anonim langsung. Fungsi dijalankan segera dengan membungkusnya dalam tanda kurung diikuti oleh dua tanda kurung tambahan. Itu disebut anonim karena tidak memiliki nama.
Program Sampel,
var Singleton = (function () {
var instance;
function createInstance() {
var object = new Object("I am the instance");
return object;
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
function run() {
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();
alert("Same instance? " + (instance1 === instance2));
}
run()
Simplest / Cleanest bagi saya berarti juga hanya untuk memahami dan tidak ada lonceng & peluit seperti yang banyak dibahas dalam diskusi versi Java:
Apa cara yang efisien untuk menerapkan pola tunggal di Jawa?
Jawaban yang paling cocok / paling bersih di sana dari sudut pandang saya adalah:
https://stackoverflow.com/a/70824/1497139
Dan itu hanya sebagian dapat diterjemahkan ke JavaScript. Beberapa perbedaan dalam Javascript adalah:
Tetapi mengingat sintaks ECMA terbaru adalah mungkin untuk mendekati:
Pola singleton sebagai contoh kelas JavaScript
class Singleton {
constructor(field1,field2) {
this.field1=field1;
this.field2=field2;
Singleton.instance=this;
}
static getInstance() {
if (!Singleton.instance) {
Singleton.instance=new Singleton('DefaultField1','DefaultField2');
}
return Singleton.instance;
}
}
Contoh Penggunaan
console.log(Singleton.getInstance().field1);
console.log(Singleton.getInstance().field2);
Contoh Hasil
DefaultField1
DefaultField2
function Once() {
return this.constructor.instance || (this.constructor.instance = this);
}
function Application(name) {
let app = Once.call(this);
app.name = name;
return app;
}
Jika Anda masuk kelas:
class Once {
constructor() {
return this.constructor.instance || (this.constructor.instance = this);
}
}
class Application extends Once {
constructor(name) {
super();
this.name = name;
}
}
Uji:
console.log(new Once() === new Once());
let app1 = new Application('Foobar');
let app2 = new Application('Barfoo');
console.log(app1 === app2);
console.log(app1.name); // Barfoo
Jika Anda ingin menggunakan kelas:
class Singleton {
constructor(name, age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
}
let x = new Singleton('s',1);
let y = new Singleton('k',2);
Output untuk yang di atas adalah:
console.log(x.name,x.age,y.name,y.age) // s 1 s 1
Cara lain menulis Singleton menggunakan fungsi
function AnotherSingleton (name,age) {
this.name = name;
this.age = age;
if(this.constructor.instance)
return this.constructor.instance;
this.constructor.instance = this;
}
let a = new AnotherSingleton('s',1);
let b = new AnotherSingleton('k',2);
Output untuk yang di atas adalah:
console.log(a.name,a.age,b.name,b.age)// s 1 s 1