I want to set up a manager with a handler object that provides a specific function for each request. Why is only syntax a) working in other sample code I saw syntax b)
a)
my.manager.requesthandler.create();
.
b)
my.manager.requesthandler [create]();
.
// my manager-modul
(function(){
my.manager = (function(){
var requesthandler = {
create: function () {
//do something
}
};
return {
requesthandler : requesthandler
};
})();
})();
my.manager.requesthandler.create
is equivalent to
my.manager.requesthandler["create"]
(notice the quotation marks)
what you wrote as b
my.manager.requesthandler[create]
means looking up a variable named create and getting
my.manager.requesthandler["whatever string create's value is"]
Related
Say I have some code like this:
function a(...numbers) {
return numbers.map(n => b(n));
}
function b(n) {
return n+1;
}
I've been looking at ways I would test like code like this, specifically to test the functionality of a without actually calling b.
One option is to use dependency injection, and to pass function b as a parameter.
ie.
function a(...numbers, _b=b) {
return numbers.map(n => _b(n));
}
But of course, the rest operator won't allow me to tack an argument on the end.
And I don't want to put the function argument first - because then the developer is having to have to pass function b in every time, or whatever, or pass a null value or similar.
Is there a way you could achieve this functionality?
rest parameters can only work as the last argument accepted by a function, it captures all argumets that were not declared in the function parameter. You can actually let go of the rest parameter and pass in an array
function a(numbers, _b = b) {
return numbers.map(n => _b(n));
}
function b(n) {
return n+1;
}
console.log(a([1,2,3,4], f => f * 1));
Function.prototype.bind() (kinda) solves this!
//The convention we will use here is that developers shouldn't use the
// _underscore methods in production.
export const _a = function(_b, ...numbers) {
return numbers.map(n => _b(n));
};
export const b = function(n) {
return n+1;
}
export const a = _a.bind(null, b);
console.log(a(1,2,3)) //[2,3,4]
This also has the advantage of that you're hiding the injected function from the developer.
Now how would you test this?
You have to test the _underscore method, so something like:
import { _a } from "../functions";
describe("_a", () => {
it("_a(1,2,3) calls _b three times.", () => {
const mockFn = jest.fn();
const a = _a.bind(null, mockFn);
a(1, 2, 3);
expect(mockFn.mock.calls).toHaveLength(3);
})
});
If you're interested - I've started a Github repo with a more fleshed out example of this approach here.
If anyone has a tidier way of doing this - I'm all ears.
Is it possible to create a hook system in javascript as like as php ?
for an example ----
function myjsfunction(){
call_my_function('handle_name');
}
now whatever function people add with 'handle' name it should get executed there.
like
add_to_function('handle_name', function(){alert('hi')});
add_to_function('handle_name', function(){alert('hello')});
both these functions should execute
var hooks = {};
function add_to_function(name, func) {
if(!hooks[name]) hooks[name] = [];
hooks[name].push(func);
}
function call_my_function(name, ...params){
if(hooks[name])
hooks[name].forEach(func => func(...params));
}
As functions are first class in js you can simply store them in an object.
Usecase:
add_to_function("log", console.log.bind(console, "this will log "));
call_my_function("log", "sth cool!");
Implementation with an IIFE:
http://jsbin.com/joxigabeyi/edit?console
I imagine it would look like the following.
Server(C#):
public class MyHub : Hub {
...
public int DoSomething(Func<int> fn) {
var res = fn();
return res;
}
...
}
Client(TS/JS):
myHub.invoke('DoSomething', () => 2 + 2).then(res => console.log(res));
However, with this code fn is null on the server.
Seems this is impossible as your parameters should be serializable. So all you can - serialize parameters in known structure and generate invocation function based on deserialization result.
You could write the function in c# and pass it back to the server as a string, then compile and run it - this might help with compiling:
http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime
well i'm confuse about the line witch says "$.Recup ..." I don't know why it is named the same as the plugin name and what it's for.
(function ($) {
$.fn.Recup = function () {
var parametros = {
};
var tsic = true;
$.Recup = function (opciones) {
var Metodos = {
};
return Metodos;
};
$.Recup.anterior = function () {
};
$.Recup.siguiente = function () {
}
})(jQuery);
I'm refering to this code, What does $.Recup exactly do?it would be perfect if someone gives me an example please
$.Recup = function (opciones) {
var Metodos = {
};
return Metodos;
};
In this case it appears to be a questionable plugin design - especially since $.Recup is not assigned until $.fn.Recup is first called.
However, if it is "appropriately and/or well written" is another question that requires context of (intended) usage. For what it is worth, I would reject this code as written as it smells of misunderstood design and widely scoped side-effects.
Anyway, the way the function is assigned determines how the method can be called.
// let $ be jQuery, then:
$.fn.foo = function () { console.log("foo") }
$.bar = function () { console.log("bar") }
$.foo() // TypeError: $.foo is not a function
$.bar() // -> "bar"
$("sel").foo() // -> "foo"
$("sel").bar() // TypeError: $(..).bar is not a function
That is, $.fn.foo is like .each() - it does something based on the currently selected elements (which are represented by this). On the other hand, $.bar is like jQuery.each() - it provides a way to iterate over a general collection but is not related to a specific set of (previously) selected elements.
In general, a plugin should only add a single entry to $.fn, but directly adding to $ may be useful to expose utility functions - it should definitely be done with care.
Here are two approaches that fix the issue of incorrectly leaked data:
$.fn.Recup = function () {
var parametros = ..
var tsic = true;
// Most trivial change; then use recup in this scope
// (or child scopes) only. There is no $.Recup - yay!
var recup = function (opciones) {
};
// ..
}
Or, just expose as local methods:
$.fn.Recup = function () {
var parametros = ..
var tsic = true;
function anterior () {
}
function siguiente () {
}
// Just use simple functions in scope
}
This is a jQuery plugin.
jQuery.fn is an alias to jQuery's prototype. So this line lets you call the Recup function on instances of jQuery :
$('#myid').Recup();
Here's the documentation on creating jQuery plugins.
I'm trying to create a simple, small and basic javascript framework just for learning purposes.
But the thing is that i'm allready stuck at the very basics.
I'm trying to do something like this:
$('testdiv').testFunction();
And the code i've written for that:
var elementID;
var smallFramework = {
$:function(id) {
this.elementID = id;
},
testFunction:function() {
alert(this.elementID);
}
};
window.$ = smallFramework.$;
But in return I get:
$('testdiv) is undefined
Can anyone help me with this small and hopefully easy question?
To get the behavior you're expecting, you need the $ function to return an object with a method named testFunction.
Try:
var smallFramework = // an object for namespacing
{
$:function(id) // the core function - returns an object wrapping the id
{
return { // return an object literal
elementID: id, // holding the id passed in
testFunction: function() // and a simple method
{
alert(this.elementID);
}
};
}
};
Of course, there are many other ways to achieve the behavior you desire.
If you're trying to add methods to an HTML element you could do something along these lines.
$ = function( elementId ) {
var element = document.getElementById( elementId );
element.testFunction = function(){
alert( this.id );
return this; // for chaining
}
return element;
}
$('test').testFunction();
Try
smallFramework.$('testdiv');
instead. According to the code you posted, that's where your $ function ended up.
Or alternatively, it looks like you're trying to replicate something like jQuery. You might want to try something like this.
var $ = smallFramework = (function () {
var f =
{
find:function(id) {
f.elementID = id;
return f; //every function should return f, for chaining to work
},
testFunction:function() {
alert(f.elementID);
return f;
}
}
return f.find //the find function will be assigned to $.
//and also assigned to smallFramework.
//the find function returns f, so you get access to testFunction via chaining
// like $("blah").testFunction()
})() //note this function gets called immediately.
this code may look confusing to someone new to JavaScript because it depends heavily on the concept of closures. I suggest that if this doesn't make sense, spend some time at Douglas Crockford's JavaScript website. This is important because the code above will bite if you happen to use this in the find function because this won't be bound to f, as you may expect it to be when you use it from $ or smallFramework.