I have a file called something.js with this code:
exports.run = (args) => {
function foo() {
console.log("foo");
}
}
Now I want to call foo from another file.
My code looks like this with errors attached as comments:
const something = require("./something.js");
module.exports = {
callFoo: function() {
something.foo(); //TypeError: something.foo is not a function
something.run.foo(); //TypeError: something.run.foo is not a function
}
Is it possible to call such a function which is apparently not a function?
You assign an arrow function to exports.run and in that function, you define the foo function, but this function is not reachable from outside of the arrow function. Yur code is nearly equivalent to:
exports.run = function(args) {
function foo() {
console.log("foo");
}
}
You most likely want to write:
exports.run = {
foo() {
console.log("foo");
}
}
Or
exports.run = {
foo : function() {
console.log("foo");
}
}
Related
export default {
one: () => {
//some codes
},
two: () => {
//some codes
one(); // error
this.one(); // error
}
}
I have module like that, and I want to call function one() inside function two().
But I got error like this : TypeError: Cannot read property 'one' of undefined.
How can I fix it? I want to know the cause.
What about extracting them out into separate functions and then include them in the export?
const one = () => {
//some codes
};
const two = () => {
//some codes
one();
};
export default {
one,
two
}
You shouldn´t use arrows function if you want to give a new context to the this keyword.
Look this example, it uses an arrow function in the two method. It would return error since the this keyword is not related to the object, but mantains the context from the last function.
let obj = {
one: function() {
console.log("one");
},
two: () => { // Arrow function
this.one();
}
}
obj.two();
If you use a normal function, the this keyword would be related to the object:
let obj = {
one: function() {
console.log("one");
},
two: function() { // Normal function
this.one();
}
}
obj.two();
This is the main difference between arrow functions and normal functions
I have to use an external js file in my TS component that it's like this:
var myObj;
function setObj(newObj) {
myObj= newObj;
return myObj;
}
function my_object() {
this.getA= function () {
return this.A;
}
this.getB= function () {
return this.B;
}
this.getC = function () {
return this.C;
}
}
I am able to call the function setObj after declaring it this way in my .ts file:
declare function setObj(obj: MyObj);
But I need to call also the other functions (getA, getB, getC), but I don't know how.
I've tried returning the object when calling setObj and then call the function, like this:
let objReturned = setObj(myObj);
objReturned.getA()
but it tells me that getA is not a function.
How can I call these nested functions inside the js?
You'll want something like:
declare interface SetObjC {
getC: () => void;
}
declare interface SetObjB {
getB: () => SetObjC
}
declare interface SetObjA {
getA: () => SetObjB;
}
declare function setObj(obj: MyObj): SetObjA;
I am reviewing some Javascript code and stumbled upon a syntax that I didn't knew. The application is a React and Redux one, though I think this is plain Javascript.
The syntax I'm concerned with is the { f1(), f2(), ... } argument of combineReducers().
This is the syntax:
combineReducers({
Reducer1,
Reducer2,
...
});
ReducerN is a function, i.e.:
const Reducer1 = (state = INITIAL_STATE, action) => {
// ...
};
I get { f1(), ... } creates an object where the function name is the key and the function itself is the value, so in a browser console I tried the following:
a = () => { console.log(1) }
b = () => { console.log(2) }
o = {a, b}
and if I print o:
{a: ƒ, b: ƒ}
a: () => { console.log(1) }
b: () => { console.log(2) }
__proto__: Object
But if I try to initialize o in a single operation:
o = { () => return 1 }
or
o = { function y() { return 1 }}
they both give a syntax error.
It's the first time I see an object created with that syntax: What kind is that? Where can I find its reference?
As said previously,
combineReducers({
Reducer1,
Reducer2,
...
});
is equivalent to this in plain ES5:
combineReducers({
Reducer1: Reducer1,
Reducer2: Reducer2,
...
});
and combineReducers is concerned only with the values of the object passed in. The first form is just a shorthand for defining properties with the same name as the value. This is the reason you cannot use anonymous functions in this form. To define function members on classes and objects, you can use the following form:
class Foo {
foo() { console.log('foo'); }
bar = () => console.log('bar')
}
const a = new Foo();
a.foo();
a.bar();
const b = {
foo() { console.log('foo'); }
bar: () => console.log('bar')
};
b.foo();
b.bar();
When transpiling to plain ES5, this will generate the following:
"use strict";
var Foo = /** #class */ (function () {
function Foo() {
this.bar = function () { return console.log('bar'); };
}
Foo.prototype.foo = function () { console.log('foo'); };
return Foo;
}());
var a = new Foo();
a.foo();
a.bar();
var b = {
foo: function () { console.log('foo'); },
bar: function () { return console.log('bar'); }
};
b.foo();
b.bar();
{ f1() } is very different than { f1 }.
The latter is a shorthand of { f1: f1 } which is an object having the key 'f1' (a string) associated to the value f1 (a function). The function is not executed.
In the first example f1() is a function call. The function f1 is executed and the value it returns is used instead. But because you didn't provide a key to associate the value with and because f1() is a value that does not have a name (it is an expression that needs to be evaluated in order to get its value), JS cannot produce an object out of it.
{ f1 } can be evaluated at the compile time and turned into { f1: f1 }.
{ f1() } cannot be evaluated at the compile time. The value of f1() is available only at the run time.
This is why { f1() } is invalid code.
If you need to call f1 and use the value it returns to create an object you can do it this way:
const x = { f1: f1() }
This is the same thing as:
const v = f1();
const x = { f1: v }
I have a really simple JS lib (called trysinon.js) that looks like this:
export function foo() {
bar();
}
export function bar() {
return 2;
}
And I have the following test
import expect from 'expect';
import sinon from 'sinon';
import * as trysinon from 'trysinon';
describe('trying sinon', function() {
beforeEach(function() {
sinon.stub(trysinon, 'bar');
});
afterEach(function() {
trysinon.bar.restore();
});
it('calls bar', function() {
trysinon.foo();
expect(trysinon.bar.called).toBe(true);
});
});
And the test is failing. How can I ensure the test passes?
Because in foo(), you called bar() which is inner function of trysinon.js. This bar() is different with the bar() you stubbed which is exported. The best way is to change trysinon to class, or called exported bar() in foo() as following.
function bar() { return 2; }
module.exports.bar = bar;
function foo() {
module.exports.bar();
}
module.exports.foo = foo;
then you can stub bar() with sinon.stub(trysinon, 'bar').returns(2)
Hope this can help you.
I use arrow function instead, and it works.
export const foo = () => {
bar();
}
export const bar = () => {
return 2;
}
I have a construcrtor simply like
function foo() {
this.bar = function() {
return "fubar";
}
}
here no problem when i call new foo().bar();
But if I wanna make something like this
function foo() {
this.bar = function() {
function subbar() {
return "subbar";
};
}
}
I've tried the versions below but none of them works.
function foo() {
this.bar = function() {
this.bar.subbar() {
return "subbar";
};
}
}
function foo() {
this.bar = function() {
this.bar.prototype.subbar() {
return "subbar";
};
}
}
How can i reach subbar like new foo().bar().subbar()
Just return an object with the inner most function:
function foo() {
this.bar = function() {
return { subbar: function subbar() {
return "subbar";
};
}
}
}
Alternatively, you could just return the function without the object:
function foo() {
this.bar = function() {
return function subbar() {
return "subbar";
};
}
}
Then you would call it like this: this.bar()() The second set of parens calls the returned subbar() function
Since functions are objects, when you call bar(), the return value will be the function subbar()
What you want is to return an object with a function attached to it.
function foo() {
this.bar = function() {
return {
subbar: function() {
return 'subbar';
}
};
};
}