0

I have the following code:

var mySigleton = new function()
{
    this.count = 123;
    document.write("<div onclick='ShowCount();''>Click</div>");

    function ShowCount() {
        alert(this.count);    
    };
}();

I need to call the function ShowCount() from the onclick event of the div created by the document.write(). However, I'm getting an error that ShowCount is undefined. Also, the ShowCount event has to access a value defined inside the singleton.

ihatemash
  • 1,365
  • 2
  • 20
  • 40
  • 3
    Inline event handlers run in global scope. You can use the locally defined function if you use the DOM API to create the element. However, even if you did that, `this` inside `ShowCount` won't refer to your singleton. Just make `count` a local variable and have `ShowCount` access it. – Felix Kling May 16 '17 at 17:22
  • 2
    [Never ever use `new function`](https://stackoverflow.com/questions/10406552/is-it-right-to-think-of-a-javascript-function-expression-that-uses-the-new-key-as-static) - it's *not* a singleton – Bergi May 16 '17 at 17:25

2 Answers2

2

You need to make ShowCount() accessible from outside the constructor function. You can do this by attaching the function to a ShowCount property of the returned instance. You then would need to call mySingleton.ShowCount():

var mySingleton = new function()
{
    this.count = 123;
    document.write("<div onclick='mySingleton.ShowCount();'>Click</div>");

    this.ShowCount = function() {
        alert(this.count);    
    };
}();

Remark: This is just to demonstrate how to fix your implementation, but as already pointed out in the comments above, it is not good style.

A better implementation would create the element and attach its event handlers using the DOM API while avoiding document.write(). Also, your singleton is actually none, so better rename it to something else to avoid confusion (or implement a real singleton):

function myClass() {
  this.count = 123;
  
  // Create <div> and attach onclick handler:
  let div = document.createElement('div');
  div.textContent = 'Click';
  div.onclick = () => alert(this.count);
  document.body.appendChild(div);
};


let instance = new myClass();

Depending on your use-case, it might still be unusual to have a constructor function create DOM elements.

Community
  • 1
  • 1
le_m
  • 15,910
  • 7
  • 55
  • 65
1

What you are trying to achieve is unclear...

By the way, there are lots of possible implementations of the Singleton pattern in JavaScript. Here is a possible one, with an IIFE:

var showCount = (function () {
  var count = 123;
  document.body.innerHTML = '<div onclick="showCount();">Click</div>';
  
  return function () {
    alert(count);
  }
})();
Badacadabra
  • 5,385
  • 7
  • 23
  • 42