Is it possible to test myInnerFunction below?
var val = function() {
var myInnerfunction = function(input) {
return input + ' I ADDED THIS';
};
return myInnerfunction('test value');
}();
Because myInnerFunction is essentially a private member of the anonymously executed outer function, it doesn't seem like it is testable from the outside.
You could intentionally expose a testing hook to the outside world, like possibly this:
var val = function() {
var myInnerfunction = function(input) {
return input + ' I ADDED THIS';
};
/* START test hook */
arguments.callee.__test_inner = myInnerFunction;
/* END test hook */
return myInnerfunction('test value');
}();
now, once val has been run at least once, you can reference val.__test_inner and call it with testable inputs.
The benefits to this approach:
1. you choose what is exposed and not (also a negative 'cause you have to REMEMBER to do so)
2. all you get is a copy-reference to the private method, so you can't accidentally change it, only use it and see what it produces
The drawbacks:
1. if the private member changes (or relies on) state of its host/parent function, it's harder for you to unit test around that, since you have to recreate or artificially control the host/parent state at the same time
2. As mentioned, these hooks have to be manually added
If you got really clever, you could have your build process look for blocks of comments like the above and remove the test hooks when creating your production build.
afaik unit testing does not concern about internal workings of things you test. The point is that you test the functionality ie: it does what it's supposed to do, not how it does it.
So if it uses an internal private member, it should not be testable...
You can test the external behavior that is observable. In this simple case you returned just the value of the inner function, but in a real world example you might combine the result of that inner function with something else. That combination is what you would test, not the direct outputs of the private method.
Trying to test the private method will make your code difficult to change and refactor, even when the external behavior is preserved. That said, I like to view unit tests not as extensive tests of your code, but simply providing an example of the API and how it behaves to different conditions. ;)
I think my answer for this is (like so many things) that I'm doing it wrong. What I've defined as a 'private' function is really something that needs to be tested. It was only private because I didn't want to expose it within a utilities api or something like that. But it could still be exposed through my application namespace.
So within the anonymous function that is executed on-dom-ready, I just attach my pre-defined functions as event handlers to the proper DOM hooks. The functions themselves, while not stored with my more open utilities functions, are still stored publicly within a package in my namespace associated with the DOM structure they are dealing with. This way I can get at them and test them appropriately.
Related
For closures which main goal it's to create another functions, I was wondering if in modern javascript, it's better to just use classes in modern javascript.
// Closure way private counter
const countPlusOne = () => {
let count = 0;
return () =>{
count++;
console.log(count);
}
}
let demoAdd = countPlusOne();
demoAdd(); // 1
demoAdd(); // 2
demoAdd(); // 3
To be honest, I never liked the use of closures in that way (but I think they're great for things like middlewares) as are hard to read.
So, should I refactor closures like the one up, to classes? Their behavior seem more analogous to typical Objects from other languages.
// Class way private counter
class countPlusClass{
count = 0;
add(){
this.count++;
console.log(this.count)
}
}
const demo = new countPlusClass();
demo.add(); // 1
demo.add(); // 2
demo.add(); // 3
No, classes aren't always better. They're just different. I'd say the main differences are
the interface of the thing returned by the constructor/factory function. A class instance has properties and methods, and usually multiple of them, whereas a closure is simply a function that you can call - with a single functionality. The syntax to invoke them is different, the extra method name is sometimes superfluous and sometimes beneficial.
In OOP, objects are expected to have an identity and a state. In FP, functions are expected to be pure. Sure, you don't need to follow a specific paradigm, and stateless objects are fine as are impure functions (though maybe call them "procedures" then), but keep these conventions in mind when arguing about readability and maintainability.
So choose wisely. Do you (possibly in the future) need multiple methods? Do you encapsulate state? Then use a class to create objects. Do you only need a function to call? Then create a closure.
A closure has a significant advantage over a class the way you're imagining: with a class, if you use a public class field like you are, any code with access to the instance can modify its value. This is usually undesirable - scope should generally be constrained as possible and you don't want the correctness of your class to depend on consumers of the class not modifying it (whether accidentally or deliberately).
class countPlusClass{
count = 0;
add(){
this.count++;
console.log(this.count)
}
}
const demo = new countPlusClass();
demo.add(); // 1
demo.add(); // 2
// some code elsewhere in the codebase that has access to the demo instance:
demo.count = 55555;
demo.add(); // not 3...
Closures, in contrast, are completely private (barring strange, exceptional circumstances).
If you were to use a class, and you wanted to emulate the privacy of closures, make sure to use private class fields instead, so they can't be modified outside the class.
class countPlusClass{
#count = 0;
add(){
this.#count++;
console.log(this.#count)
}
}
const demo = new countPlusClass();
demo.add(); // 1
demo.add(); // 2
// some code elsewhere in the codebase that has access to the demo instance
// cannot modify the private field
demo.count = 55555;
demo.add(); // not 3...
As for which is better, a closure-based object or a class? That's up to each individual developer.
Classes are not always better. It really depends upon the circumstances. Each has their place in your programming toolset.
A class has the following advantages:
There's defined syntax in the language
You can sub-class a class to extend it
You can more easily have many properties and many methods.
Methods are automatically non-enumerable and run in strict mode.
The syntax in the code that uses a class somewhat self-describes what is happening since new countPlusClass() makes it clear you're creating an object that will then have methods and probably state. That's not as obvious with the closure you show.
For object with a lot of methods there's some space-savings benefit to the prototype that a class uses.
Developer tools will recognize an instance of a class and know how to display it, auto-complete when typing code for it, how to represent it in the debugger, how to use it in error messages, etc...
A closure has these advantages:
The data in the closure is complete private. Nobody can get to it from outside the closure.
In some circumstances, the caller may find it takes less code to use the closure since you make one function call (sometimes passing arguments) and you get back another function that then implements the one thing this is supposed to do (your mention of middleware comes to mind).
So, I'd say that if you want or need or value any of the benefits of the class, then use the class.
If you don't want or need any of the benefits of the class and the simpler interface of the closure meets your needs or if you really need the privacy of the closure, then you can choose the closure.
I'd say that for a given circumstance, one of these tools may be a better "fit" for the problem at hand.
As has been mentioned in the comments, you can also have factory functions that may be closures (retain private state in a closure) and may return an object with methods and/or properties that can even be an object created by instantiating a class. So, these concepts can all be combined too to get some of the benefits of both.
I'm looking for something that will import the contents of an object to the global scope:
var y = {}
y.x = 5
//do some magic here
console.log(x); //5
I want to do this is so I can make an easy to use module with memorable function names without having to worry about things accidentally getting overridden by other modules.
Consider this example:
funModule = {};
funModule.washClothes = function(clothes){...}
funModule.walkDog = function(dogName){...}
//etc
funModule.UNITED_STATES_DEFICIT = ...;
Here I've created a module that has some useful functions and constants (implementations and values were replaced with "...").
I don't want my users to have to type out the module name every time they call function or use a constant. That would result with really messy code:
funModule.walkDog(funModule.UNITED_STATES_DEFICIT);
I could try it again by defining everything globally:
washClothes = function(clothes){...}
walkDog = function(dogName){...}
//etc
UNITED_STATES_DEFICIT = ...;
but if a different module has also defined the commonly named function washClothes we've got trouble. (in my actual case the commonly named function is run)
Removed from technical context, here is the problem I'm faced with:
Firstly I want to use simple and memorable names to make the module easy to learn and fun to use.
Secondly I don't want the easy names to make the module impossible to use with others. Especially as it grows, a lot of common names will be used. It would be great if the users could decide whether or not import the names directly.
Thirdly I realized as I'm typing this that what I'm describing is something that definitely already exists, in python. See http://effbot.org/zone/import-confusion.htm for more detail.
tl;dr How can python-like imports be done with javascript?
EDIT:
It seems there is not a universal way to do this.
Using Window won't work in all environments (but will work in any common browser).
Apparently ES6 Modules are not available to web browsers directly.
This question is different from this one because its not about Node.js. I was looking for a universal way to do it, but that doesn't seem possible, so I'll limit it to web browsers, (namely chrome, firefox, safari, opera, and maybe ie)
EDIT:
This general article about Scope could be useful for anyone with a similar question as mine: https://toddmotto.com/everything-you-wanted-to-know-about-javascript-scope/
Object.prototype.makeglobal=function(){
for(key in this){
if(window[key]){//replace window if youre not in a browser
//already exist, error handling
console.error(key+' already exist in window');
}else{
window[key]=this[key];
}}};
Use like this:
funModule.makeglobal();
//now you can
washClothes();
But this is bad as it pollutes the global object.
2.Your user should create his own namespace:
function(){
this.washClothes();
//more of his content
}.call(funModule);
3.You could also add a loader:
funModule.load=function(func){
console.log(func);
console.log(this);
func.call(this,this);
};
Now you can do:
funModule.load(function(fun){
this.washClothes();
fun.washClothes();
});
4.If youre concerned about readability you may use function chaining (?):
funModule.washClothes=function(){
//your code
return this;
}
now you can do:
funModule.washClothes("tshirts").washClothes("trousers").washClothes();
ES6 Modules are what you want.
If you will define your object as es6 module you could do this (using the names in your example):
import { washClothes } from "fun-module";
and then washClothes will be globally available on the file that imported it, just like you want.
Read about it here.
If you really want a magic solution like in the comment in your post and don't want to use ES6 and you run in the browser you can put it on the window object:
window.x = 5
In JavaScript, at least in a browser, global variables are properties of the window object: that is, window.x and x (where x is global) reference the same value. So, in theory, you could use Object.assign() to copy your object's properties to the window object making them global variables. This is roughly equivalent to globals().update(myobj.__dict__) in Python.
But just as import * is usually a bad idea in Python, so too this sounds like a bad idea, except even worse because window has a lot of other properties that you probably don't want to clobber.
After some additional research I found a way, without polluting the global namespace, to allow users to directly access module contents.
This solution allows the user to:
Write code that directly references the module's functions/properties
Define precedence if there are multiple modules written in this same style
Still access the module's functions/properties by module name*
*This feature comes with a catch
Here's the code
Module
funModule = {};
//This stuff is the arbitrary contents of the module:
funModule.washClothes = function(clothes){...}
funModule.walkDog = function(dogName){...}
//etc
funModule.UNITED_STATES_DEFICIT = ...;
//etc
//This part is necessary:
funModule.run(userApp)
{
for(key in this){
eval(key + " = " + this[key] + ";");
}
userApp();
}
The only way (that I could find) to dynamically define functions both in funModule.run's scope and in funModule is to use Eval. Using call, apply, or bind to manipulate scope would still require use of the this keyword and the whole point of this unusual style is to make client code as simple and non-repetitive as possible.
Client Code 1
function myApp()
{
washClothes(UNITED_STATES_DEFICIT);
}
funModule.run(myApp);
Here in the client code it is possible to directly access everything except for funModule.run. So the global namespace is kept clean but the user's code does not need unnecessary repetition.
Client Code 2
function myApp()
{
washClothes(UNITED_STATES_DEFICIT);
}
funModule.run( otherModule.run.bind({},myApp) ); //otherModule has precedence here
Assume otherModule is a different module that features the same run function. funModule will load its contents then call its first argument. The first argument will load otherModule's contents, overriding anything from funModule with the same name.
Client Code 3
function myApp()
{
//directly access stuff from funModule
walkDog()
var big = UNITED_STATES_DEFICIT * 3.14;
//explicitly access stuff from specific modules
clothes = new otherModule.Clothes();
funModule.washClothes(otherModule.washClothes(clothes));
}
funModule.run(myApp)
This is the feature that makes use of eval necessary. The user can opt out of ambiguity of direct access. They can still access properties/methods by naming the module they come from.
But Why?
Some StackOverflow users were understandably concerned about the unusual set of constraints in the question, so I figured I would answer the following question:
Why don't you use a short alias for your module.
I tried to answer that question in this article, which pulls from this question and answer.
Edit: I found this interesting library which looks like it can do exactly what I was describing at the bottom: https://github.com/philbooth/check-types.js
Looks like you can do it by calling check.quacksLike.
I'm fairly new to using javascript and I'm loving the amount of power it offers, but sometimes it is too flexible for my sanity to handle. I would like an easy way to enforce that some argument honors a specific interface.
Here's a simple example method that highlights my problem:
var execute = function(args)
{
executor.execute(args);
}
Let's say that the executor expects args to have a property called cmd. If it is not defined, an error might be caught at another level when the program tries to reference cmd but it is undefined. Such an error would be more annoying to debug than explicitly enforcing cmd's existence in this method. The executor might even expect that args has a function called getExecutionContext() which gets passed around a bit. I could imagine much more complex scenarios where debugging would quickly become a nightmare of tracing through function calls to see where an argument was first passed in.
Neither do I want to do something on the lines of:
var execute = function(args)
{
if(args.cmd === undefined || args.getExecutionContext === undefined ||
typeof args.getExecutionContext !== 'function')
throw new Error("args not setup correctly");
executor.execute(args);
}
This would entail a significant amount of maintenance for every function that has arguments, especially for complex arguments. I would much rather be able to specify an interface and somehow enforce a contract that tells javascript that I expect input matching this interface.
Maybe something like:
var baseCommand =
{
cmd: '',
getExecutionContext: function(){}
};
var execute = function(args)
{
enforce(args, baseCommand); //throws an error if args does not honor
//baseCommand's properties
executor.execute(args);
}
I could then reuse these interfaces amongst my different functions and define objects that extend them to be passed into my functions without worrying about misspelling property names or passing in the wrong argument. Any ideas on how to implement this, or where I could utilize an existing implementation?
I don't see any other way to enforce this. It's one of the side effects of the dynamic nature of JavaScript. It's essentially a free-for-all, and with that freedom comes responsibility :-)
If you're in need of type checking you could have a look at typescript (it's not JavaScript) or google's closure compiler (javascript with comments).
Closure compiler uses comments to figure out what type is expected when you compile it. Looks like a lot of trouble but can be helpful in big projects.
There are other benefits that come with closure compiler as you will be forced to produce comments that are used in an IDE like netbeans, it minifies your code, removes unused code and flattens namespaces. So code organized in namespaces like myApp.myModule.myObject.myFunction will be flattened to minimize object look up.
Cons are that you need to use externs when you use libraries that are not compiler compatible like jQuery.
The way that this kind of thing is typically dealt with in javascript is to use defaults. Most of the time you simply want to provide a guarentee that certain members exist to prevent things like reference errors, but I think that you could use the principal to get what you want.
By using something like jQuery's extend method, we can guarentee that a parameter implements a set of defined defaults.
var defaults = {
prop1: 'exists',
prop2: function() { return 'foo'; }
};
function someCall(args) {
var options = $.extend({}, defaults, args);
// Do work with options... It is now guarentee'd to have members prop1 and prop2, defined by the caller if they exist, using defaults if not.
}
If you really want to throw errors at run time if a specific member wasn't provided, you could perhaps define a function that throws an error, and include it in your defaults. Thus, if a member was provided by the caller, it would overwrite the default, but if it was missed, it could either take on some default functionality or throw an error as you wish.
When I'm creating controllers, I always add functions to the $scope object, like so:
function DummyController($scope) {
$scope.importantFunction = function () { /*...*/ };
$scope.lessImportantFunction = function () { /*...*/ };
$scope.bussinessLogicFunction = function () { /*...*/ };
$scope.utilityFunction = function () { /*...*/ };
}
Of course I'm keeping my controllers encapsulated nicely, making sure that business logic lies in appropriate components (injected via DI) or services. So the controller is focused on orchestrating things between UI and Backend.
However, as you can see - there are still plenty of different kinds of functions. I like to keep more of them, as it improves readability IMHO.
The question
Is that a good practice to have lots of functions attached to $scope object? Does it have performance overhead? I know that $scope is a special kind of object, being constantly evaluated in Angular's digest cycle, so am I doing this right or will I ask for trouble by sticking to my approach?
(Please note: I'm not looking for alternative approaches. I'm looking for some well thought analysis of people who know Angular's internals.)
Thx!
UPDATE:
The answer from Anders is very good and shows you some paths to follow. Today I ran into this beauty, a chrome extension for Angular Js debugging and performance monitoring. It shows you all the scopes and assigned variables, along with some interesting performance graph. A must have for any Angular developer!
Update:
Should I add all of my functions and variables to the scope?
No, you should only add functions and variables to your scope if you need to access them in your template. A variable that is only accessed in the controller function shouldn't be on the scope, it should be local to the controller function.
Will if affect performance if I add a lot of functions to the scope?
Generally, no. Functions on your scope that are executed like ng-click="myFunction()" should not affect performance in a noticeable way. But if your function is executed like this: {{myFunction()}} it will get executed for every digest as Angular needs to know if the return value of it has changed so it can update the UI.
Will it affect performance if I add a lot of variables to the scope?
It can affect performance if you use them in places where Angular will dirty check them. Those cases are where you print them out like {{myVariable}}, if you use them in ng-model="myVariable", ng-show="myVariable", etc. Directives like ng-click does not perform dirty checks, so that doesn't slow things down. The guys behind Angular recommends you not to use more than 2000 expressions on one page that will require repaints/dirty checks, as your performance will start do degrade after that. The limit of 2000 is something they've found while researching performance in Angular.
Note that just because you add a property on the scope, it doesn't mean that Angular will perform dirty checks on it. They have to be used in your template for dirty checks to be performed (but not for ng-click).
If I want maximum performance in my Angular app, what should I be aware of?
Like I mentioned above, try to keep the number of bound template expressions below 2000. And if you implement watches on your scope, make sure that the expression for the watch executes really quickly. This is an example of how you shouldn't do it:
$scope.items = [];
for (var i = 0; i < 1000; i++) {
$scope.items.push({prop1: 'val1', prop2: 'val2', prop3: 'val3'});
}
$scope.$watch('items', function() {
}, true);
By adding the true as the third argument to $watch, you're telling Angular to loop through $scope.items for every digest cycle to check if any property of the thousand items have changed, which will be costly both in time and memory.
What you should do instead is:
$scope.items = [];
for (var i = 0; i < 1000; i++) {
$scope.items.push({prop1: 'val1', prop2: 'val2', prop3: 'val3'});
}
$scope.$watch('items.length', function() {
});
That is, only check when $scope.items.length have changed. That expression will execute very quickly.
Original post:
If your question is "is it better to expose functions to the template than objects" then yes, you should be using functions as much as you can. That way you encapsulate the logic inside the controller instead of letting it bleed into your template. Take this example:
<div ng-show="shouldShow">Toggled div</div>
<button ng-click="shouldShow = !shouldShow">Toggle<button>
Here the template has a little too much knowledge about what's happening. Instead, this should be solved like this:
// controller
var shouldShow = false;
scope.toggle = function() {
shouldShow = !shouldShow;
}
scope.shouldShow = function() {
return shouldShow;
}
<!-- template -->
<div ng-show="shouldShow()">Toggled div</div>
<button ng-click="toggle()">Toggle<button>
By doing it like this it's trivial to expand the logic in the controller without touching the template. While your requirements right now might be to just toggle the div when you press the button, tomorrows requirements might be to update some other part of the application when that happens. And if you use a function instead, it's easy to add that logic inside the function without changing the template.
Functions on your scope have a bit more overhead than using properties, but that overhead probably won't be what's slowing down your app when that day comes. So use functions when they make sense.
But you should still try to keep your controllers as small as possible. If they grow to contain tons of functions/functionality, you should probably split up your controller into reusable directives.
Encapsulation is the core tenent of OO programming.
However, if you make a function private and then you return it so that you can use it, does this to anything effectively.
I would think not, that b.c. if you return a function , you are not returning a copy of it...you are returning a reference. That is the core of the question. When you return a function is it a copy or is it a reference to the actual function.
Does the code below keep func1 private and safe as good practice OO programming would like.
Or does encapsulation / data hiding not really pertain to functions?
var A = (function(){
var func1 = function(param){
// do stuff
},
publik;
publik.retFunc(){
return func1;
}
return publik;
}())
A.retFunc()(arg1);
I'm really not sure where you're going with this...
But, to further the cause:
var Class = (function () {
var private_data = 1234,
private_method = function (x) { private_data += x; },
public_method = function (x) { private_method(x); },
other_method = function () { return private_data; },
public_interface = {
add : public_method,
toString : other_method
};
return public_interface;
}());
I have now programmed to an interface.
This particular interface would be .add and .toString.
The private values are safe from tampering, as they've been enclosed.
add has the ability to access private_method so long as add isn't modified.
See, if you try to do something like this, after the fact:
Class.add = function (x) { steal(private_data + x); };
It's not going to work.
The new function doesn't have a reference to the private data.
So while an external person or program might tamper with the public interface, the internal state is still fine.
Your program will likely still break if it's been tampered with, or other, less protected classes might get compromised, but this one will sit happily, and any internal calls it needs to make (like if it updated a screen, on a timer), will still happen perfectly.
The other point of encapsulation is to choose the interface that you want to present to people.
You could have 30 helper functions inside of a class, but you probably only want to give the external application access to a few of them.
And those public methods will have access to the private data/methods, and the ability to do whatever it is you want the clients to be able to do, and nothing more.
That's an Application Programming Interface.
If I wanted to have a BlogManager class, it might be huge.
Maybe I want it to be able to get stuff from the database, to sort, to set up templates, or to communicate with a view... I want it to be able to filter, I want it to do all kinds of stuff...
But I don't want the end-user to do all of that.
What I want the end user to do is .request(options); or .create(blog_post); or .update(blog_post); or .delete(blog_post);.
If I give the end-user those four methods then nobody can touch the dozens of other things going on inside of the BlogManager to make everything work as expected.
That's programming to an interface.
In the future, when I figure out a better way to filter my results, or when I change my database, or when I change the structure of the data-storage, it isn't going to matter what I do on the inside of my class, because the outside will still look and act the same.
If it has the same public methods, the same input-types, the same return-types... ...then you can do anything you want inside.
There aren't a lot of immediate cases for returning the actual constructor-function, instead of an instated object, though.
Much like there aren't a lot of cases for returning the function, instead of the function's return-value.
Aside from asynchronous programming.