JavaScript Objects Rules - javascript

I am currently working on javascript Function and Objects but there is a little bit confusion.
I have created an object and called its method in the window like
obj.something();, it gives me result but when I write same code in console like console.log(obj.something());, it gives me undefined in the console
So, my question is obviously why & how?
var obj ={
value: 1,
increment: function () {
this.value += 1
// return this
},
add: function (v) {
this.value += v
// return this
},
shout: function () {
console.log(this.value);
// return this
}
};
obj.shout();
console.log(obj.shout());

undefined is the default return value from a function without return.
From MDN docs of return statement:
When a return statement is called in a function, the execution of this function is stopped. If specified, a given value is returned to the function caller. If the expression is omitted, undefined is returned instead.

You hava to return value from function ,Like this
var obj ={
value: 1,
increment: function () {
this.value += 1
// return this
},
add: function (v) {
this.value += v
// return this
},
shout: function () {
return this;
}
};
obj.shout();
console.log(obj.shout());

You can remove the display of "undefined" without adding a "return" by using the .call() instead of using () in a function.
var obj ={
value: 1,
increment: function () {
this.value += 1
// return this
},
add: function (v) {
this.value += v
// return this
},
shout: function () {
console.info("Line-14");
console.log(this.value);
console.info("Line-16");
//return;
}
};
var objectShootResult = obj.shout;
console.info("Line-21");
objectShootResult.call(obj);
console.info("Line-22");

Related

What is meaning by [Object, Object] error JavaScript

I have debugged my code for almost 2 hours as well as try to solve it by using this site Object but it does work. It seems there is an issue with the Controller model. The following is snapped from the code
var budgetController = (function () {
var number = 23;
})();
var UiController = (function () {
// get the html input (read the data )
// you can return whather var by var or retuen one object that has all the HTML compenents
var DOMStrings = {
inputType: '.add__type',
inputDesc: '.add__description',
inputValue: '.add__value',
inputBtn: '.add__btn'
};
return {
getInput: function () {
return {
type: document.querySelector(DOMStrings.inputType).value, // Will be either inc or exp
description: document.querySelector(DOMStrings.inputDesc).value,
value: document.querySelector(DOMStrings.inputValue).value
};
},
getDOMStrings: function () {
return DOMStrings;
}
};
})();
var Controller = (function (budgetCtr, UICtrl) {
// Immediately Invoked Function Expression
var DOM = UICtrl.getDOMStrings();
var CtrAddItem = function () {
// pass everthing to here
var output = UICtrl.getInput();
console.info("Data " + output);
}
document.querySelector('.add__btn').addEventListener('click', CtrAddItem);
document.addEventListener('keypress', function (event) {
if (event.keyCode === 13 || event.which === 13) {
CtrAddItem();
}
});
})(budgetController, UiController);
The [Object , Object] appeared whenever I console log the output on the controller model
Whenever you concat a string and an object using + the toString-method is called on the object (which by default just returns [object Object]). You should pass the object as the second argument instead:
console.info("Data", output);

How is variable named 'record' passed in function?

I am trying to build a pivot table & was using a open source code and fumbled over this function.
How is record[] passed to this function? There seems to be no passing or any declartion. How can it come directly?
Whole code can be found here https://github.com/plotly/react-pivottable/blob/master/src/Utilities.js
I have tried looking up the whole module for record[] variable for could only find direct use. Could not find where it's assigned values.
sum(formatter = usFmt) {
return function([attr]) {
return function() {
return {
sum: 0,
push(record) {
if (!isNaN(parseFloat(record[attr]))) {
this.sum += parseFloat(record[attr]+10000);
}
},
value() {
return this.sum;
},
format: formatter,
numInputs: typeof attr !== 'undefined' ? 0 : 1,
};
};
};
},
I wanted to use & modify data provided at record[]
How to use it?
In your code sample, record is a parameter of the function push on the object returned from the anonymous function returned from the anonymous function returned from (not a typo) the function sum.
You can decompose this code as:
const func = sum(formatter = usFmt) // returns anonymus function([attr]) {}
const func2 = func([attr]) // returns function() {}
const myLiteral = func2() // returns object literal
And your literal is equal as below
myLiteral = {
sum: 0,
push(record) {
if (!isNaN(parseFloat(record[attr]))) {
this.sum += parseFloat(record[attr]+10000);
}
},
value() {
return this.sum;
},
format: formatter,
numInputs: typeof attr !== 'undefined' ? 0 : 1,
}
And on your myLiteral you can e.g.
myLiteral.push(myRecord);

JS: how to capture output of a function every time it gets called

I have the following self-invoked function which is being utilized by the other functions across the app:
var Api = (function() {
var requestPayload;
var responsePayload;
return {
getRequestPayload: function() {
return requestPayload;
},
setRequestPayload: function(newPayloadStr) {
requestPayload = JSON.parse(newPayloadStr);
},
getResponsePayload: function() { // <-Function's output I need
return responsePayload;
},
setResponsePayload: function(newPayloadStr) {
responsePayload = JSON.parse(newPayloadStr);
}
};
}());
This function is called by other functions in the app like:
Api.getResponsePayload();
I want to capture the output of getResponsePayload function every time this function is called to utilize is for further processing.
I tried to create another function:
function runMe(responsePayload) {
console.log(responsePayload)
}
And it gets called everytime getResponsePayload function is called but the output I'm getting is undefined:
getResponsePayload: function() {
runMe();
return responsePayload;
How can I get the output of getResponsePayload function everytime it gets called by any other function in the app?
Just shim it, assuming this is for debug purposes. You may want to handle exceptions more explicitly, just be sure to rethrow to be transparent.
Api.getResponsePayload = (function(previousFn){
return function() {
var result = previousFn.apply(this, arguments);
// print them or something
return result;
}
})(Api.getResponsePayload)
Edit: Here is a generalisation of the method above:
function logMethodCallsOn(object, methodName) {
var actualMethod = object[methodName];
object[methodName] = function() {
var title = methodName + "(" + Array.prototype.map.call(arguments, function (val) { return JSON.stringify(val); }).join(", ") + ")";
try {
var result = actualMethod.apply(this, arguments);
console.log(title + " =", result);
return result;
} catch (e) {
console.error(title + " threw", e);
throw(e);
}
}
}
logMethodCallsOn(Api, 'getResponsePayload');
logMethodCallsOn(Api, 'setResponsePayload');
You could use callbacks. I'm not sure if you whant a callback in the get or the set, this example shows both.
Eric's answer is more elegant and can be used even if Api is an external object. But I think this simpler implementation could be useful for learning purpose.
var Api = (function(getResponsePayloadCallback, setResponsePayloadCallback) {
var requestPayload;
var responsePayload;
return {
getRequestPayload: function() {
return requestPayload;
},
setRequestPayload: function(newPayloadStr) {
requestPayload = JSON.parse(newPayloadStr);
},
getResponsePayload: function() { // <-Function's output I need
getResponsePayloadCallback(responsePayload);
return responsePayload;
},
setResponsePayload: function(newPayloadStr) {
responsePayload = JSON.parse(newPayloadStr);
setResponsePayloadCallback(responsePayload);
}
};
})(getResponsePayloadHandler, setResponsePayloadHandler);
Api.setResponsePayload('{ "foo": "foo value" }');
var requestPayload = Api.getResponsePayload();
function getResponsePayloadHandler(value) {
console.log("getResponsePayload: " + value.foo);
}
function setResponsePayloadHandler(value) {
console.log("setResponsePayload: " + value.foo);
}
You are not passing any parameter to runMe so it logs undefined. Change your getResponsePayload function to:
getResponsePayload: function() {
runMe(responsePayload);
return responsePayload;
}
Anyway be aware that if you don't set responsePayload, you console output will still be undefined cause responsePayload is only declared but never assigned a value (so it will have undefined value)

Trying to understand this code (pub/sub library)

This is Peter Higgins's pub sub library: https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js
(function (d) {
var cache = {};
d.publish = function (topic, args) {
cache[topic] && d.each(cache[topic], function () {
this.apply(d, args || []);
});
};
d.subscribe = function (topic, callback) {
if (!cache[topic]) {
cache[topic] = [];
}
cache[topic].push(callback);
return [topic, callback];
};
d.unsubscribe = function (handle) {
var t = handle[0];
cache[t] && d.each(cache[t], function (idx) {
if (this == handle[1]) {
cache[t].splice(idx, 1);
}
});
};
})(jQuery);
I don't understand the logic and the functionality of publish:
cache[topic] && d.each(cache[topic], function () {
**this.apply(d, args || []);** //what is happening here?
});
What is the purpose of this part? except the fact that it publishes the event
In this context, the && is used as a shorthand for:
if (cache[topic]) {
d.each(cache[topic], function() { … });
}
This is because && (and ||) are short-circuiting, so if the left hand side evaluates to a false-ish value (or true-ish value, in the case of ||), the right hand side does not get evaluated.
For example:
> function foo(result) { console.log("foo"); return result; }
> function bar(result) { console.log("bar"); return result; }
> foo(false) && bar(true);
foo
false
Basically, you call each topic callback (if any) with args (if any arguments are passed). So you can:
$.subscribe('do_something', function(str) { alert(str + ' world!')});
$.subscribe('do_something', function(str) { console.log(str)});
$.publish('do_something', ['Hello']); // will alert Hello world! and output 'Hello' to console
cache[topic] && d.each(cache[topic], function () {
this.apply(d, args || []);
});
Applying for each element of d, if cache[topic] is defined, function, which calls the apply method of it with d argument, and args, or an empty array, if args is not defined.

Functional JavaScript: how to implement Function.prototype.not

I was working on some code earlier today, when I realized, "Hey! This code would be more concise and semantic if I abstracted the idea of a boolean not out of an anonymous function and into a prototype function..."
Consider a predicate generator:
function equalTo(n) {
return function(x) {
return n==x;
};
}
So you can use it like so:
[1,2,3,4,1,2,3,4].filter(equalTo(2)) == [2,2]
Now, my idea is to make a predicate "inverser":
Function.prototype.not = function() {
//???
}
So that you can say:
[1,2,3,4,1,2,3,4].filter(equalTo(2).not) == [1,3,4,1,3,4]
My first stab at the implementation was probably very naive:
Function.prototype.not = function () {
return ! this(arguments);
}
And probably why it didn't work.
How would you implement this function, and why?
I'm just trying to wrap my head around functional ideas, and know JavaScript well enough to know it can be used to do this, but just not how.
Your implementation won't work for several reasons:
You need to return a function, not a boolean.
You should pass the arguments as-is, not wrapped in an array.
You should preserve the context (this keyword) that the function would have been called in.
I would implement it like this:
Function.prototype.not = function (context) {
var func = this;
return function() { return !func.apply(context || this, arguments); };
}
I return an anonymous function (function() { ... })
I call apply to call the original function in the current contexts with the actual arguments.
(EDIT) Free bonus: I added an optional context parameter which will override this for the callback.
I would probably do it like so (but perhaps with some sort of namespacing):
function not (x) {
return !x;
}
function id (x) {
return x;
}
function compose (/*funcs*/) {
var args = arguments.length
? Array.prototype.slice.call (arguments)
: [id]
;
return function () {
var val = args [args.length - 1].apply (null, arguments);
for (var i = args.length - 2; i >= 0; --i) {
val = args [i] (val);
}
return val;
};
}
[1,2,3,4,1,2,3,4].filter (compose (not, equalTo (2)));
Using your idea:
function equalTo(n) {
var fn = function(x) {
return n == x;
};
fn.not = function(x) {
return n != x; // use this for simpler conditions
return !fn.apply(this, arguments); // use this for more complex logic
}
return fn;
}
So your example would work:
[1,2,3,4,1,2,3,4].filter(equalTo(2).not) == [1,3,4,1,3,4]
Edit: You can write a helper function (better name to be found) so not doesn't need to be redefined every time:
function generateFnWithNot(fn) {
return function () {
var f = fn.apply(this, arguments);
f.not = function () {
return !f.apply(this, arguments);
}
return f;
};
}
So when you're defining your functions, you can define them as normal with the exception of wrapping a generateFnWithNot call:
var equalTo = generateFnWithNot(function (n) {
return function (x) {
return n == x;
};
});
equalTo(5) // resolves to function () { return n == 5; }
equalTo(5).not // resolves to function () { return n != 5; }

Categories

Resources