I want to be able to do something like
var x = {};
x.something = function(y){
console.log(y);
};
x("hi"); // Call it without using .something
Is this possible? Any ideas?
var x = function(str) {
return x.something(str);
};
x.something = function(str) {
console.log(str);
};
Functions are objects, so you could do something like:
var x = function(y) {
console.log(y);
}
x.prop = function(){ return 'This works'; };
x('hi');
console.log(x.prop());
Related
I'm trying to train myself to write chaining function but got error of
Cannot read property 'minus' of undefined(…)
What's wrong with my code?
var math = function(){
var result = 0;
var add = function(param){
result += param;
};
var minus = function(param){
result -= param;
};
var print = function(){
console.log(result)
};
return {add:add, minus: minus, print:print};
}
var calculator = math();
var result = calculator.add(5).minus(1).print();
console.log(result)
You need to return the object (this) in this case, to "chain" like you are expecting
You print() also doesn't return anything so result is always undefined.
var math = function(){
var result = 0;
var add = function(param){
result += param;
return this;
};
var minus = function(param){
result -= param;
return this;
};
var print = function(){
console.log('result: ' + result);
// print doesnt return anything, it needs to if you want to assign anything by calling it
return result;
};
return {add:add, minus: minus, print:print};
}
var calculator = math();
var result = calculator.add(5).minus(1).print();
console.log(result)
You can also store a reference to the object returned.
var math = function() {
var result = 0;
var add = function(param) {
result += param;
return math;
};
var minus = function(param) {
result -= param;
return math;
};
var print = function() {
console.log(result)
};
var math = {
add: add,
minus: minus,
print: print
};
return math;
}
var calculator = math();
calculator.add(5).minus(1).print();
I'm trying to figure out the answer to this question:
Without using Javascript's bind function, implement the magic function so that:
var add = function(a, b) { return a + b; }
var addTo = add.magic(2);
var say = function(something) { return something; }
var welcome = say.magic('Hi, how are you?');
addTo(5) == 7;
welcome() == 'Hi, how are you?';
I think I need to use call or apply but I just don't know, if someone could point me in the right direction or provide some literature it would be much appreciated.
You can use closure, and apply function
Function.prototype.magic = function(){
var self = this;
var args = Array.from(arguments);
return function(){
return self.apply(null, args.concat(Array.from(arguments)));
}
}
var add = function(a, b) { return a + b; }
var addTo = add.magic(2);
var say = function(something) { return something; }
var welcome = say.magic('Hi, how are you?');
console.log(addTo(5) == 7);
console.log(welcome() == 'Hi, how are you?');
Also you can look to Polyfill for bind function on MDN
Please see below code:
Object.prototype.magic = function (message) {
alert(message);
}
var add = function (a, b) { return a + b; }
var addTo = add.magic(2);
var say = function (something) { return something; }
var welcome = say.magic('Hi, how are you?');
addTo(5) == 7;
welcome() == 'Hi, how are you?';
I have a small piece of code written like in below.
var MY = MY || {};
MY.Farm = (function () {
var add = function(x){
console.log(x)
return this + this;
};
return {
add: function(x){
return add(x);
}
}
});
On a separate file I create sheep an instance of MY.Farm
var sheep = new MY.Farm()
I want to be able to call the function like the following with an output 6
sheep.add(3).add(2).add(1)
Any ideas how I can achieve this? What are the changes required to the MY.Farm snippet to accommodate this?
Thanks in advance.
Something like this
var MY = MY || {};
MY.Farm = (function () {
var x=0;
return {
add: function(newX){
if(typeof(newX) !="undefined") {
x+=newX;
return this;
}
return x;
}
}
});
var sheep = MY.Farm();
console.log( sheep.add(2).add(4).add());
http://jsfiddle.net/7q0143er/
You're not too far off. The trick is you need to keep track of the value somewhere, like in a private variable, and add needs to return this. Finally, you need a way to get the value out when you're done:
MY.Farm = function () {
var total = 0;
return {
add: function(x) {
total += x;
return this;
},
value: function() {
return total;
}
};
};
var sheep = new MY.Farm();
sheep.add(3);
console.log(sheep.value()); // => 3
console.log(sheep.add(1).add(2).value()); // => 6
Let's say I have a function like this:
function foo(){
var myValue = 5;
var myOtherValue = 1;
return {
getValue: function(){
return [myValue, myOtherValue];
}
}
}
Is there a way I can extend/overwrite this function somehow without touching the original function so that when I call getValue() I get [SOME OTHER VALUE I CHOOSE, myOtherValue]?
If not, can I do it at the instance level?
var myFoo = new foo();
myFoo.getValue = function(){
return [0, myOtherValue]; // how to I access myOtherValue?
}
If you don't want to modify foo, you can do this:
function foo(){
var myValue = 5;
var myOtherValue = 1;
return {
getValue: function(){
return [myValue, myOtherValue];
}
}
}
var myFoo = new foo();
//move getValue to _getValue
myFoo._getValue = myFoo.getValue;
//do custom getValue
myFoo.getValue = function(){
return [0, myFoo._getValue()[1]];
}
function foo(){
var myValue = 5;
var myOtherValue = 1;
return {
getValue: function(){
return [myValue, myOtherValue];
}
}
}
var myFoo = new foo();
var storeOriginal= myFoo.getValue;
myFoo.getValue = function(){
//your code
storeOriginal();
}
You can't.
myOtherValue is only defined in the scope of foo.
You could have to rewrite to something like this:
function foo(){
var myValue = 5;
return {
myOtherValue: 1,
getValue: function(){
return [myValue, this.myOtherValue];
}
}
}
Then you could do:
var myFoo = new foo();
myFoo.getValue = function(){
return [0, myFoo.myOtherValue];
}
function foo() {
.. original stuff ..
}
var hidden_foo = foo;
function decorator() {
var internal = hidden_foo();
// here is the proxy object
return {
getValue: function() {
return [SOME OTHER VALUE I CHOOSE, internal.getValue()[1]];
}
}
}
// overwrite the original function with our decorated version
foo = decorator;
You can't access a variable in a closure. However, you can define the new function to delegate to the original function to access it:
var myFoo = new foo();
myFoo.getValue = (function (original) {
return function(){
var val = original();
val[0] = 0;
return val;
};
}(myFoo.getValue));
Here is a fiddle of this solution so you can try it out yourself: http://jsfiddle.net/6Ux92/1/
You can do like this
function myFoo() {
var vals = foo().getValue();
return {
getValue : function(){
return [0, vals[1]]
}
}
}
vals[1] is obviously myOtherValue
you could wrap this function with a decorator function:
var decorator = function() {
var someNewValue = ...;
var myOtherValue = foo().getValue()[1];
return [someNewValue, myOtherValue];
}
Try this :
function foo(){
this.myValue = 5;
var myOtherValue = 1;
return {
getValue: function(){
return [this.myValue, myOtherValue];
}
}
}
var bar = new foo();
bar.myValue = "whatever";
i think i did not understand javascript module pattern.
I just create this module:
var mycompany = {};
mycompany.mymodule = (function() {
var my = {};
var count = 0;
my.init = function(value) {
_setCount(value);
}
// private functions
var _setCount = function(newValue) {
count = newValue;
}
var _getCount = function() {
return count;
}
my.incrementCount = function() {
_setCount(_getCount() + 1);
}
my.degreeseCount = function() {
_setCount(_getCount() - 1);
}
my.status = function() {
return count;
}
return my;
})();
var a = mycompany.mymodule;
var b = mycompany.mymodule;
console.debug(a, 'A at beginning');
console.debug(a, 'B at beginning');
a.init(5);
b.init(2);
console.log('A: ' + a.status()); // return 2 (wtf!)
console.log('B: ' + b.status()); // return 2`
Where is the mistake?
I thought that my code would have returned to me not 2 value, but 5.
What's the reason?
a and b are the exact same objects.
var a = mycompany.mymodule;
var b = mycompany.mymodule;
What you want to do is create two different objects which have the same prototype. Something similar to this:
mycompany.mymodule = (function () {
var my = function () {};
my.prototype.init = function (value) {
_setCount(value);
};
my.prototype.incrementCount = ...
// ...
return my;
}());
a = new mycompany.mymodule();
b = new mycompany.mymodule();
a.init(5);
b.init(2);
For more info, research "javascript prototypal inheritance"
In JavaScript, objects are passed by reference, not copied.
To explain further, here is a simplified version of your code:
var pkg = (function () {
var x = {};
return x;
}());
var a = pkg;
var b = pkg;
You do not create two separate objects but only reference the object pointed at by pkg from both a and b. a and b are exactly the same.
a === b // true
This means that calling a method on a you are ultimately doing the same to b (it points to the same object—x.)
You don't want to use the module pattern for this. You want the usual constructor+prototype.
function Pkg() {
this.count = 0;
};
Pkg.prototype.init = function (count) { this.count = count; };
var a = new Pkg();
var b = new Pkg();
a === b // false
a.init(2);
a.count === 2 // true
b.count === 2 // false
Here is a good read about module pattern.