Javascript accessing inner function from outside - javascript

I have the following json object
{
....
....
data: function() {
var x = 10;
function isBig() {
return x>6;
}
return x;
}
}
I want the isBig to be a function inside data.
When I call data.isBig I am getting undefined and data.isBig() gives me an error saying isBig is not a function.

First of all, that is not JSON. It is an object.
The way your object is structured currently, isBig is only accessible from inside data. If you want to access it outside data, the simplest way is to make it a property of the outer object:
{
data: function()
{
var x = 10;
return x;
}
isBig: function(x)
{
return x > 6;
}
}
If you don't want to do that, then an alternative would be this:
{
data: function()
{
var x = 10;
this.isBig = function(x)
{
return x > 6;
}
return x;
}
}
Calling data() works normally (returns 10), whereas calling new data() returns an object with a property isBig which corresponds to the function. This allows you to do this:
new myObj.data().isBig()

obj = {
data: function(){
var x = 10;
return this.isBig(x);
},
isBig: function(x){
return x > 6;
}
};
And if you want to reproduce the function but useally your better off with an contructor add that point.
f = {
isSmall: function(){},
isBig: function(x){
return x > 6;
}
};
obj = {
data: function(){
var x = 10;
return this.isBig(x);
},
isBig: f.isBig
};
obj.data();
obj.isBig(2);
f.isBig(2);

Related

how to concatenate function with javascript closure and object

i'm trying to find a solution to this exercise:
Implement the calculate function that adds an object that gives the ability to do the four
mathematical operations (addition, subtraction, multiplication and division) on the same number and finally print out the result.
function calculate() {
}
const calculator = calculate();
calculator.add(2).add(4).multiply(3).sub(1).sub(3).divide(2).printResult(); // result will be: 7
console.log(calculator)
so, what is the right way to solve this (and if you can add comment will be appreciated
no need to put so many this and function...
in this way you have a closure value.
=> calc_00.val = 20;
will not change the result (it just add a new property if jso is not freeze )
or throw an error in strict mode
"use strict";
function calculate( initVal = 0 ) // default value is zero
{
let
val = initVal // closure value
, jso =
{ add(v) { val += v; return this }
, sub(v) { val -= v; return this }
, multiply(v) { val *= v; return this }
, divide(v) { val /= v; return this }
, printResult() { return val }
}
Object.freeze(jso)
return jso
}
const
calc_00 = calculate()
, calc_10 = calculate(10)
;
// calc_00.yop = ()=>null; // Uncaught TypeError: can't define property "yop": Object is not extensible
// calc_00.sub = ()=>null; // Uncaught TypeError: "sub" is read-only
// calc_00.val = 20; // Uncaught TypeError: can't define property "val": Object is not extensible
calc_00.add(2).add(4).multiply(3).sub(1).sub(3).divide(2);
calc_10.add(10).multiply(3);
console.log( calc_00.printResult(), calc_10.printResult() ) // 7 , 60
You can return the object itselft.
function calculate() {
return {
result: 0,
add: function(num) {
this.result += num;
return this;
},
sub: function(num) {
this.result -= num;
return this;
},
multiply: function (num) {
this.result *= num;
return this;
},
divide: function (num) {
this.result /= num;
return this;
},
printResult: function () {
return this.result;
}
}
};
const calculator = calculate();
const result = calculator.add(2).add(4).multiply(3).sub(1).sub(3).divide(2).printResult(); // result will be: 7
console.log(result);
Make sure to understand how this works in JavaScript. For instance, using functions is different than using arrow functions.
Reference: JavaScript this
Alternative solution using closure
function calculate() {
let result = 0;
return {
add: function(num) {
result += num;
return this;
},
sub: function(num) {
result -= num;
return this;
},
multiply: function (num) {
result *= num;
return this;
},
divide: function (num) {
result /= num;
return this;
},
printResult: function () {
return result;
}
}
};
const calculator = calculate();
const result = calculator.add(2).add(4).multiply(3).sub(1).sub(3).divide(2).printResult(); // result will be: 7
console.log(result);

Can one property value be passed as a argument to another property whose value is computed via a function ? (in Javascript ES6 with classes)

class A {
constructor(inval){
this.c = inval;
}
b() {
return this.c + 1;
}
e(z) {
return z+ Math.floor(Math.random()*10);
}
d() {
let x = {
x1: this.b(),
x2: this.e(this.b()),
}
return x;
}
}
var inst = new A(5);
var instret = inst.d();
console.log(instret);
Question: in method d() statement "let x" is it possible to use the x1 property as a argument to x2:this.e() call like this:
let x = {
x1: this.b(),
x2: this.e(x1),
}
tried several combinations none worked. Basically is there a better way than to repeatedly type "this.b()" as parameter to this.e() when what I clearly want as parameter is x1 ?
Set key2 as a function and use this to access another key from the same object.
var obj = {
key1: 5,
key2: function() {
return this.key1 + 10;
}
};
alert(obj.key2()); // 15
You can use IIFE or what #Adeel recommended
class A {
constructor(inval) {
this.c = inval;
}
b() {
return this.c + 1;
}
e(z) {
return z + Math.floor(Math.random() * 10);
}
d() {
let x = ((x1) => ({
x1,
x2: this.e(x1),
}))(this.b());
return x;
}
}
var inst = new A(5);
var instret = inst.d();
console.log(instret);

How to call a function right before object is called

Is it possible to call a function at the second an object is being called?
I have following object:
var z;
var a = {
b: function(){
return z * 2;
}
c: function(){
return z * 3;
}
d: function(){
return z * 4;
},
e: function(){
return z * 5;
}
}
var onObjectInvoke = function(){
z = (new Date()).getTime();
}
I want to reset the value of z before a.d() is being called, here's the flow I mean, when a.d() is called:
call onObjectInvoke.
call a.d();
I'm looking for some kind of constructor, is there any way?
Why can't you just call onObjectInvoke() before calling a.d()? Your life will be a lot easier if you allow your functions to be stateless and operate on given parameters rather than using a global z variable.
var z;
var a = {
d: function(x){
return x * 4;
}
}
var onObjectInvoke = function(){
return (new Date()).getTime();
}
z = a.d(onObjectInvoke());
var z;
var a = {
b: 2,
c: 3,
d: function(){
onObjectInvoke();
return z * 4;
}
}
var onObjectInvoke = function() {
z = (new Date()).getTime();
}
console.log(a.d());
One simple way is to add one more layer and then access onObjectInvoke() in that layer first and return the functions from that layer as object and call the desired function on return value
a.defaultFunc().d()
var z;
var a = {
defaultFunc: function() {
onObjectInvoke()
return {
b: function() {
return z * 2;
},
c: function() {
return z * 3;
},
d: function() {
return z * 4;
},
e: function() {
return z * 5;
}
}
}
}
var onObjectInvoke = function() {
console.log('reseting z')
z = (new Date()).getTime();
}
console.log(a.defaultFunc().d())
console.log(a.defaultFunc().e())
In such a case you most certainly don't want to use z directly but invoke a function that returns the value for you. And in that function, you will either reset z or return it depending on your current use case.
Having external code that heavily modifies the behavior/outcome of a function is always a bad idea with regard to maintainability and readability.
var z;
var resetZ = true;
var a = {
getZ: function() {
if (resetZ) {
z = (new Date()).getTime();
}
return z;
},
b: function() {
return this.getZ() * 2;
}
c: function() {
return this.getZ() * 3;
}
d: function() {
return this.getZ() * 4;
},
e: function() {
return this.getZ() * 5;
}
}
a.d()
You for sure should not use a global resetZ, but as it is not clear how exactly you use your code it is not clear how to structure the code. Or maybe getZ should be a free function, instead of a function belonging to the object.

Why am I getting undefined on this module pattern in javascript?

Why am I getting undefined on the x.test()? It's an anonymous function.
var Calculator = function () {
// private stuff
var x = 55;
return {
// public members
y: x,
test: function () {
console.log(x);
}
};
};
var x = new Calculator();
console.log(x.y);
console.log(x.test());
You're logging the return value of x.test which is implicitly undefined:
console.log(x.y); // Logs 55
var x = x.test(); // Logs 55 (because of the console.log call in x.test)
console.log(x); // Logs undefined (because that's what x.test returned)
Did you mean to return the "private" x from the test method?
// ...
return {
y: x,
test: function () {
return x;
}
}
Because you are printing (console.log) the return of a function that doesn't return anything.
Just return the x value in your test function:
var Calculator = function () {
// private stuff
var x = 55;
return {
// public members
y: x,
test: function () {
return x;
}
};
};

Javascript oop-like fail(?!?)

Consider this:
function f2(x) {
return x+1;
};
X = function(){
this.f1=function (x) {
return 2*f2(x);
}
return this;
};
then x = new X(); x.f1(1) works fine.
But when i want to do this:
X = function(){
this.f2 = function(x) {
return x+1;
};
this.f1=function (x) {
return 2*f2(x);
}
return this;
};
The same statement will complain that it can't find f2.
In, for example c#, you can say
class X {
int f2(int x){return x+1;}
int f1(int x){return 2*f2(x);}
}
and this will work
X x=new X();
x.f1(1)
Why?
You need to reference the f2 with the this keyword explicitly.
X = function(){
this.f2 = function(x) {
return x+1;
};
this.f1=function (x) {
return 2*this.f2(x);
}
return this;
};
because you forgot this.f2. Javascript don't see class variables without this
To reference f2 in your second code block, you'll need to use this.f2. this references the context in which the function is being executed. Since you call f1 in the following way:
x.f1();
... the context is set to the instance, x.
JavaScript does not make instance variables available to the scope in the same way as scope variables, i.e. those directly available:
X = function(){
var f2 = 123;
this.f2 = function(x) {
return x+1;
};
this.f1=function (x) {
console.log(f2); // => 123
console.log(this.f2); // => function(){}
return 2 * this.f2(x);
};
return this;
};
Javascript doesn't have the implicit this that you get in C#. You need to add the this in:
X = function(){
this.f2 = function(x) {
return x+1;
};
this.f1=function (x) {
return 2*this.f2(x);
};
return this;
};
X = function(){
this.f2 = function(x) {
return x+1;
};
this.f1=function (x) {
return 2*this.f2(x); // <-- Need this here since it is not implicit
}
return this;
};

Categories