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()
Related
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();
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')
I am new to Javascript and I want to send parameter via an object.
I also have tried to create my objects, but unfortunately it did not work. Here's the code:
var obj = (function(foo) {
var str = foo;
var bar = function() {
alert(this.str+" Bar");
}
})();
When I call obj('foo').bar();, I want it to produce foo Bar. How to do that?
This should solve your problem:
var obj = function(foo) {
return {
bar: function() {
alert(foo + ' Bar');
}
}
}
obj('foo').bar();
EDIT: You can even use the "Run code snippent" to test it :)
There are tons of solution for your case. I'll provide my favourite one.
var obj = function(foo) {
if (!(this instanceof obj)) {
return new obj(foo);
}
this.str = foo;
}
obj.prototype.bar = function() {
alert(this.str + " Bar");
};
obj('foo').bar();
//or
new obj('foo').bar();
How could I do this?
Class
var Factory = (function() {
var Class = function() {
this.name = 'John';
this.methods = {
get: function(callback) {
callback();
}
};
};
return {
createClass: function() {
return new Class();
}
};
}());
Usage
var MyClass = Factory.createClass();
MyClass.methods.get(function() {
this.name // => returns undenfined
});
Thanks for any help!
You need to save a reference to this in the outer Class function and call call:
var instance = this;
this.methods = {
get: function(callback) {
callback.call(instance);
}
};
var Class = function() {
// Save a reference to this that can be used in local closures.
var me = this;
this.name = 'John';
this.methods = {
get: function(callback) {
// Use 'call()', passing the reference to the 'Class' object
callback.call(me);
}
};
};
#SLaks - The declaration of scope as a Global variable is bad practice.
#Ferdinand Beyer - have you tested if it functions?
The better way will be the scope binding. The Prototype javascript framework produced a nice concept and we can easily implement it like
Function.prototype.bind = function(scope) {
var _function = this;
return function() {
return _function.apply(scope, arguments);
}
}
and then yoou code should have only a single change and it will maintin the scope of your class.
var Factory = (function() {
var Class = function() {
this.name = 'John';
var me = this;
this.methods = {
get: function(callback) {
callback();
}
};
};
return {
createClass: function() {
return new Class();
}
};
}());
var MyClass = Factory.createClass();
MyClass.methods.get(function() {
console.info(this.name) // => returns undenfined
}.bind(MyClass));
I mean only the function call get with .bind(MyClass)
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();