How to run an entire method with one word? - javascript

player.outputChatBox("Test")
Is there anyway I can run the method above with just one word?
For example, var test = player.outputChatBox("Teste")
If I type test wherever on the script it runs it.
Also, consider I'll add multiple of those, so the best option might be an object or something (sorry, I'm new).

Make a function that calls it.
const test = () => player.outputChatBox("Test");
test();
test();
test();
Add parameters if you want.
const test = (string = "Test") => player.outputChatBox(string);
test(); // output: 'Test'
test('foo'); // output: 'foo'
test(); // output: 'Test'

You could declare a helper function:
const helper = () => player.outputChatBox("Test")
This way you could use it sort-of the way you want:
helper();
helper();
helper();
Would call the function 3 times

Related

How to test the result of a curried function in Jasmine?

Use Case:
I have a module of functions, each function is unit tested
I have a factory function that creates a stream of these functions that a third party library requires.
I would like to test that this factory function produces the correct stream. Using #cycle/Time, I am able to create the stream and assert on the stream.
I am able to assert that the functions appear on the stream in the correct order.
However, I am unable to assert on any function that is curried. How would one assert on curried functions?
Currently, I have a hack in place to JSON.stringify the functions and assert on their source.
To simplify the problem, I created a simple test suite so we aren't concerned with using #cycle/Time. It appears that curried functions are new instances of the function. Please see the code below.
I was wondering how would I be able to make the failing test pass? In this case I simulate the curried function by using bind. Is this possible?
const a = () => b
const b = () => {}
const c = (arg) => b.bind(null, arg)
const d = () => () => {}
describe("curried function test", function() {
it('should return a reference to b', () => {
expect(a()).toBe(b)
})
// This test fails because b.bind returns a new function.
it('should return a reference to a curried b', () => {
expect(c('foo')).toBe(b)
})
it('should create a new instance everytime', () => {
expect(d()).not.toBe(d())
})
});
I've setup a jsfiddle here.
"This test fails because b.bind returns a new function."
That's because what you get from c is the result from b.bind(null, arg), which isn't the same as b.
Otherwise, b.bind would be modifying b.
As mdn says:
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
(source, emphasis mine)
Basically, c can't return a reference to b.
What you do have, is the resulting function's name:
const b = () => {};
const c = (arg) => b.bind(null, arg);
const e = c("foo");
console.log(e.name);
console.log(e.name === `bound ${b.name}`);
So, you could test that e.name equals "bound " + b.name.

Javascript function inside functions

Today I observed the following syntax (simplified example):
const test = fn => () => console.log(fn)
test('foo')();
Having a hard time wrapping my head around this but it still remains vague to me. What exactly happens step by step?
Let's rewrite this in a way which maybe more understandable for you
const test = function(fn){
return function (){
console.log(fn);
}
}
test('foo')();
Do you understand it now? If yes this is same as your example just uses normal function instead of arrow functions.
You also need to know what a closure is to understand this.
As the answers already mentioned you are creating a closure.
In my answer, I want to say what it is a closure good for:
Imagin you want to greet three persons and two of them are your frinds and one is your boss. You want to greet your frinds with "Hi" but your boss with "Hello".
const greet = greetingWord => name =>
`${greetingWord}, ${name}`
const greetFrind = greet('Hi')
const greetBoss = greet('Hello')
We create a function greet which takes one arguement an will return a new function with one argument too (greet = greetingWord => name). Once we implement it we can define a greeter for our frinds and for the boss.
const greet = greetingWord => name =>
`${greetingWord}, ${name}`
const greetFrind = greet('Hi')
const greetBoss = greet('Hello')
console.log(greetFrind('Paul'))
console.log(greetFrind('Julia'))
console.log(greetBoss('Mr. Paker'))
So this is basic concept of closure in JavaScript. If you rewrite the code in ES5:
var test = function(fn){
return function(){
console.log(fn);
};
}
test('foo')();
So the inner function has access to the argument that was passed into the outer function. So that's why you are getting "foo"

javascript about AOP

review my code make it print expected result thax
var Obj = (function () {
var b = 'b',
_f = function () {
// print arguments
Array.prototype.push.call(arguments,b);
console.log(arguments,b);
}
return {
f:_f
};
})();
//rewrite Obj.f
Obj.f = function () {
// add parameters dynamically
Array.prototype.push.call(arguments,333);
// it dose not work
Obj.f.apply(Obj.f,arguments);
}
//when I rewrite Obj.f how to make it print result below
// expected result print 111 333 'b'
Obj.f(111);
// expected result print 666 333 'b'
Obj.f(666);
// expected result print 444 333 'b'
Obj.f(444);
If you want the new version of f() to be able to call the original version of f() that was overwritten then you need to save a reference to the original version. Here's one way to do that:
//rewrite Obj.f
Obj.f = (function() {
var originalF = Obj.f;
return function () {
// add parameters dynamically
Array.prototype.push.call(arguments,333);
// Call original:
originalF.apply(this,arguments);
}
})();
That is, use an IIFE to give you some private scope for the originalF variable and then use that variable from within the new function. (This structure is similar to what you were already using to create your Obj in the first place.)
Note also that the first argument to .apply() sets the value of this within the function being called, so you probably just want to pass this through rather than passing Obj.f, so that the original function gets the same this as the new function. (It doesn't actually matter in your specific example, because your function doesn't use this at all, but still for future reference that's the most logical approach.)

Jasmine SpyOn on function calls

Hello I got a question regarding mocking JS code with Jasmine.
Imagine having the following situation:
function Test(){
var a = 5;
var b = 3;
Test2(a,b);
}
function Test2(a,b){
var result = a + b;
console.log("result of function Test2: ", result);
}
I want to mock my Test2 function call with Jasmine. I tried the following thing:
describe("1# Test Mocking", function () {
it("test: Mocking Example", function () {
var myMock = new Test();
spyOn(myMock, "Test2").and.returnValue(10,10);
expect(Test2.result).toEqual(20);
});
});
But Jasmine keeps saying: Error: Test2() method does not exist
Does anyone knows why this is and how I could solve this?
Your code doesn't make a lot of sense I'm afraid:
you're telling Jasmine to spy on a method of myMock called Test2, yet it doesn't have such a method (as Jasmine is telling you); Test2 is just a regular function;
even if it did had a method called Test2, you're spying on it after new Test(), at which point the original Test2 would already have been called and the spy would be declared too late;
the original Test2 doesn't return a value, yet you are telling the spy that it should return 10, 10 (it seems to me that you want to call it with those two values, not have it return them);
Test2 doesn't have any side-effects (like returning a value or setting an instance variable or something) apart from creating a local variable (result) and logging it, which makes it pretty untestable;
I think you need to go back to the drawing board to formulate what exactly it is you want the class to do. To help you on your way, here's a possible implementation, including a test to see a) if Test2 gets called with the proper arguments and b) if its return value gets stored properly (again, I don't know what you want the class to do, so I'm just providing some examples):
function Test() {
var a = 5;
var b = 3;
this.result = this.Test2(a, b);
}
Test.prototype.Test2 = function(a, b) {
var result = a + b;
return result;
}
describe("1# Test Mocking", function () {
it("test: Mocking Example", function () {
spyOn(Test.prototype, 'Test2').and.returnValue(20);
var myMock = new Test();
expect(myMock.Test2.calls.argsFor(0)).toEqual([ 5, 3 ]);
expect(myMock.result).toEqual(20);
});
});

Simplest way to pass value back from anonymous callback?

I'm still trying to understand javascript scoping. What is the simplest way to return a value from an anonymous callback function? For instance,
var test = 'outside';
callsFunction(function() { test = 'inside'; });
console.log(test);
where callsFunction calls the anonymous function. I would like this to print 'inside'.
I'm a little bit confused, but I believe this is what you're after
function callsFunction( fn )
{
fn();
}
var test = 'outside';
callsFunction(function() { test = 'inside'; });
console.log(test);
Note that any function can be invoked via the usage of (). However, there are special methods for invoking functions from different contexts, such as Function.call() and Function.apply()
At the risk of pointing out the obvious, the simplest way to have something done after a callback is to simply include it in the callback (and this is, in fact, the way to go):
var test = 'outside';
callsFunction(function() {
test = 'inside';
console.log(test);
});
A real example: let's say you want to update a div with the contents of a file from an Ajax call.
Ajax('file.html', function (data) {
// Update the div here
document.getElementById('d').innerHTML = data;
});
// Not here
Maybe what you are wanting to research is closures in JavaScript?
You didn't define callsFunction in your question, but if you make it a self-invoking anonymous function, you can return the new 'test' value:
var test = 'outside';
(function() { test = 'inside'; })();
console.log(test); // returns 'inside'
If you do define callsFunction:
var test = 'outside';
var callsFunction = function() {
test = 'inside';
return test;
};
console.log(callsFunction()); // returns 'inside'
You can get more complicated with closures.

Categories