This question already has answers here:
What is the 'new' keyword in JavaScript?
(17 answers)
Closed 3 years ago.
I have code like this:
function Thing() {
function foo() {
alert('1');
}
return { foo : foo }
}
window['myThings'] = {
bar : function() {
let t = new Thing();
t.foo = function() {
Thing.prototype.foo.call(this);
alert('2');
}
}
}
And have error: "Uncaught TypeError: Cannot read property 'call' of undefined". I want override object method with custom method, from which call parent method and then add some code. Where is my mistake?
P. S. Read article on the link from the comments and change code like this:
Thing = function () {
this.someVar = 1;
foo();
}
Thing.foo = function() {
alert('1');
}
window['myThings'] = {
bar : function() {
let t = new Thing();
t.foo();
}
}
And now i have an error: foo is not a function...
P. P. S. Change code like this:
function Thing() {};
Thing.prototype = function (arg) {
this.someVar = arg;
this.foo();
}
Thing.prototype.foo = function() {
alert('1');
}
window['myThings'] = {
bar : function() {
let t = new Thing(1);
t.foo();
}
}
myThings.bar();
And now: arg passed to constructor not stored in someVar or not readed from it...
Solution is here:
function Thing(arg) {
var private = 'private';
this.public = 'public';
this.init = function(arg) {
private = arg;
this.foo();
alert(private);
}
this.foo = function() {
alert('foo');
}
this.init(arg);
};
window['myThings'] = {
things : [],
bar : function() {
this.things[0] = new Thing('privateArg');
function AnotherThing(arg) {
Thing.call(this, arg);
var parentFoo = this.foo;
this.foo = function() {
// Call parent method
parentFoo();
// Run custom code
alert('foo foo');
}
}
// Parent init called with parent foo() method
this.things[1] = new AnotherThing(2);
// Customized foo() called
this.things[1].foo();
}
}
myThings.bar();
Related
I am using JavaScript prototype chaining technique to chain functions as shown below:
var foo = (function () {
function fn(arg) {
if (!(this instanceof fn)) {
return new fn(arg);
}
this.arg = arg;
return this;
}
var func = function (element) {
return fn(element);
};
fn.prototype = {
bar: function () {
return this;
}
}
func.functions = fn;
return func;
}());
I would like to know how to access fn.prototype so I can add more functionality to the foo prototype outside its closure.
If I just simply do as follows, it won't work:
foo.prototype.baz = function () {
alert(this.arg);
}
foo("hello").baz();
However if fn assigned to the foo (func.functions = fn;) as it shown in the foo private closure I can do as follow and it will works:
foo.functions.prototype.baz = function () {
alert(this.arg);
}
foo("hello").baz();
Is there any other way to achieve this?
I think you are un-necessarily overcomplicating this. You can chain by simply doing this:
const foobar = function(){return this} // Initialize a new Object
const foo = text => {
const me = new foobar()
me.text = text
me.bar = a => (alert(me.text+": "+a), me)
return me
}
foo('A').bar('Test').bar('Test chained')
// Update the foobar class with baz
foobar.prototype.baz = function() {alert('BAZ worked!');return this}
foo('B').bar('1').baz().bar('2')
Note: Click Run code snippet to see the output
That's it!
Edit:
You can also do this with ES6 classes like:
class foobar {
constructor(text) {
this.text = text;
}
bar(a) {alert(this.text+": "+a);return this}
}
const foo = text => new foobar(text)
foo('A').bar('Test').bar('Test chained')
// Update the foobar class with baz
foobar.prototype.baz = function() {alert('BAZ worked!');return this}
foo('B').bar('1').baz().bar('2')
Playing around with some JS tests and I'm trying to instantiate some nested objects in my v namespace. As you'll see below, ClassA and ClassB work as expected. When I try and nest some objects under another property (myCustomProperty) I start running into issues! Could someone explain?
Below is the original code:
var v = (v) ? v : {};
v.someClassA = (function() {
this.hello = function() {
console.log("Class A Hello!");
}
});
v.someClassB = (function() {
this.hello = function() {
console.log("Class B Hello!");
}
});
// this all works!
var myClassA = new v.someClassA();
var myClassB = new v.someClassB();
v.myCustomProperty = (function() {
function someClassC() {
this.hello = function() {
console.log('C');
}
}
function someClassD() {
this.hello = function() {
console.log('D');
}
}
return {
someClassC: someClassC,
someClassD: someClassD
}
});
// Uncaught TypeError: v.myCustomProperty.someClassC is not a function! Why?
var myClassC = new v.myCustomProperty.someClassC();
var myClassD = new v.myCustomProperty.someClassD();
myClassA.hello();
myClassB.hello();
myClassC.hello();
myClassD.hello();
If I change my declaration of v.myCustomProperty to use object literal notation, then it ALL WORKS! :
v.myCustomProperty = {
someClassC: function() {
this.hello = function() {
console.log('C');
}
},
someClassD: function() {
this.hello = function() {
console.log('D');
}
}
}
I guess my question really is how would I make this work using the notation in my original snippet? Possible? Horrible practice to do it that way?
Thanks!
v.myCustomProperty is a function that returns an object. You have to call the function first:
new (v.myCustomProperty().someClassC)();
// ^^
Otherwise, v.myCustomProperty.someClassC() tries to access the property someClassC of the function, and we all know (hopefully) that functions don't have such a property.
Or maybe you intended to execute the function immediately and assign the object to myCustomProperty?
v.myCustomProperty = (function() {
// ...
}()); // <- call function
How to accede to the variable from the nested function in JavaScript?
function Foo() { // class Foo
this.name = 'myName';
this.bar = function() { // 'bar' method
return function() { // nested method
return this.name; // how to accede to that?
}
}
}
Is the variant bellow optimal :?
this.bar = function() { // 'bar' method
var innerName = this.name; // duplicated variable :-/
return function() { // nested method
return innerName;
}
}
The more usual approach is to keep a reference to the entire outer object:
function Foo() { // class Foo
var _self = this;
this.name = 'myName';
this.bar = function() { // 'bar' method
return function() { // nested method
return _self.name;
}
}
}
Like this:
function Foo() { // class Foo
var that = this;
this.name = 'myName';
this.bar = function() { // 'bar' method
return function() { // nested method
return that.name; // how to accede to that?
}
}
}
If you're in a ES6 capable environment, you can also arrow functions for that:
function Foo() {
this.name = 'myName';
this.bar = () = > () => this.name;
}
I have this object, dive:
var dive = new Foo.Bar();
And Foo.Bar looks like this:
var Foo = {
Bar: function() {
...
return function() {
// do stuff, no return
};
}
};
I'd like dive to have all the prototypes of another, existing object, however. Let's say window.Cow.prototype is:
{
moo: function() { ... },
eat: function() { ... }
}
What do I need to do to Foo.Bar so that I can do this:
dive.moo();
dive.eat();
var Foo = {
Bar: function() {
//...
return this; // technically unnecessary, implied by 'new' operator
}
};
Foo.Bar.prototype = new Cow(); // the secret sauce
dive = new Foo.Bar();
dive.moo(); // moo's like a Cow
Here is a working example without the Bar constructor jsFiddle
Thank you for the start, jimbojw! You were close, but you gave me enough information to get it:
function Cow() {
return {
talk: function() {
alert("mooo");
}
};
}
var Foo = {
Bar: function() {
function result() {
alert("Foo.Bar says...");
};
result.prototype = new Cow();
return new result;
}
};
new Foo.Bar().talk();
If you want to encapsulate Foo.Bar.prototype = you can do it without changing default constructor behavior:
function Cow() {
this.talk = function() {
alert("mooo")
}
}
var Foo = {
Bar: function() {
var constructor = function() {
this.eat = function() {
alert("gulp")
}
}
constructor.prototype = new Cow()
return constructor
}()
}
var foo = new Foo.Bar()
foo.talk()
foo.eat()
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Simplest/Cleanest way to implement singleton in JavaScript?
I'm using this pattern for singletons, in the example the singleton is PlanetEarth:
var NAMESPACE = function () {
var privateFunction1 = function () {
privateFunction2();
};
var privateFunction2 = function () {
alert('I\'m private!');
};
var Constructors = {};
Constructors.PlanetEarth = function () {
privateFunction1();
privateFunction2();
};
Constructors.PlanetEarth.prototype = {
someMethod: function () {
if (console && console.log) {
console.log('some method');
}
}
};
Constructors.Person = function (name, address) {
this.name = name;
this.address = address;
};
Constructors.Person.prototype = {
walk: function () {
alert('STOMP!');
}
};
return {
Person: Constructors.Person, // there can be many
PlanetEarth: new Constructors.PlanetEarth() // there can only be one!
};
}();
Since PlanetEarth's constructor remains private, there can only be one.
Now, something tells me that this self-cooked thing isn't the best one can do, mostly because I don't have an academic education and I tend to solve problems in stupid ways. What would you propose as a better alternative my method, where better is defined as stylistically better and/or more powerful?
(1) UPDATE 2019: ES7 Version
class Singleton {
static instance;
constructor() {
if (instance) {
return instance;
}
this.instance = this;
}
foo() {
// ...
}
}
console.log(new Singleton() === new Singleton());
(2) ES6 Version
class Singleton {
constructor() {
const instance = this.constructor.instance;
if (instance) {
return instance;
}
this.constructor.instance = this;
}
foo() {
// ...
}
}
console.log(new Singleton() === new Singleton());
Best solution found:
http://code.google.com/p/jslibs/wiki/JavascriptTips#Singleton_pattern
function MySingletonClass () {
if (arguments.callee._singletonInstance) {
return arguments.callee._singletonInstance;
}
arguments.callee._singletonInstance = this;
this.Foo = function () {
// ...
};
}
var a = new MySingletonClass();
var b = MySingletonClass();
console.log( a === b ); // prints: true
For those who want the strict version:
(function (global) {
"use strict";
var MySingletonClass = function () {
if (MySingletonClass.prototype._singletonInstance) {
return MySingletonClass.prototype._singletonInstance;
}
MySingletonClass.prototype._singletonInstance = this;
this.Foo = function() {
// ...
};
};
var a = new MySingletonClass();
var b = MySingletonClass();
global.result = a === b;
} (window));
console.log(result);
Why use a constructor and prototyping for a single object?
The above is equivalent to:
var earth= {
someMethod: function () {
if (console && console.log)
console.log('some method');
}
};
privateFunction1();
privateFunction2();
return {
Person: Constructors.Person,
PlanetEarth: earth
};
Extending the above post by Tom, if you need a class type declaration and access the singleton instance using a variable, the code below might be of help. I like this notation as the code is little self guiding.
function SingletonClass(){
if ( arguments.callee.instance )
return arguments.callee.instance;
arguments.callee.instance = this;
}
SingletonClass.getInstance = function() {
var singletonClass = new SingletonClass();
return singletonClass;
};
To access the singleton, you would
var singleTon = SingletonClass.getInstance();