Skip to content

Commit 1355096

Browse files
committed
added function declaration and hoisting examples
1 parent 10edacd commit 1355096

File tree

1 file changed

+170
-2
lines changed

1 file changed

+170
-2
lines changed

README.md

Lines changed: 170 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,79 @@ While this guide explains the *what*, *why* and *how*, I find it helpful to see
404404
vm.title = 'Sessions';
405405
```
406406
407+
- **Function Declarations to Hide Implementation Details**: Use function declarations to hide implementation details. Keep your bindable members up top. When you need to bind a function in a controller, point it to a function declaration that appears later in the file. This is tied directly to the seciton Bindable Members Up Top.
408+
409+
*Why?*: Placing bindable members at the top makes it easy to read and helps you instantly identify which members of the controller can be bound and used in the View. (Same as above.)
410+
411+
*Why?*: Placing the implementation details of a function later in the file moves that complexity out of view so you can see the important stuff up top.
412+
413+
*Why?*: Function declaration are hoisted so there are no concerns over using a function before it is defined (as there would be with function expressions).
414+
415+
*Why?*: You never have to worry with function declarations that moving `var a` before `var b` will break your code because `a` depends on `b`.
416+
417+
*Why?*: Order is critical with function expressions
418+
419+
```javascript
420+
/**
421+
* avoid
422+
* Using function expressions.
423+
*/
424+
function Avengers(dataservice, logger) {
425+
var vm = this;
426+
vm.avengers = [];
427+
vm.title = 'Avengers';
428+
429+
var activate = function() {
430+
return getAvengers().then(function() {
431+
logger.info('Activated Avengers View');
432+
});
433+
}
434+
435+
var getAvengers = function() {
436+
return dataservice.getAvengers().then(function(data) {
437+
vm.avengers = data;
438+
return vm.avengers;
439+
});
440+
}
441+
442+
vm.getAvengers = getAvengers;
443+
444+
activate();
445+
}
446+
```
447+
448+
- Notice that the important stuff is scattered in the preceeding example.
449+
- In the example below, notice that the important stuff is up top. For example, the members bound to the controller such as `vm.avengers` and `vm.title`. The implementation details are down below. This is just esier to read.
450+
451+
```javascript
452+
/*
453+
* recommend
454+
* Using function declarations
455+
* and bindable members up top.
456+
*/
457+
function Avengers(dataservice, logger) {
458+
var vm = this;
459+
vm.avengers = [];
460+
vm.getAvengers = getAvengers;
461+
vm.title = 'Avengers';
462+
463+
activate();
464+
465+
function activate() {
466+
return getAvengers().then(function() {
467+
logger.info('Activated Avengers View');
468+
});
469+
}
470+
471+
function getAvengers() {
472+
return dataservice.getAvengers().then(function(data) {
473+
vm.avengers = data;
474+
return vm.avengers;
475+
});
476+
}
477+
}
478+
```
479+
407480
- **Defer Controller Logic**: Defer logic in a controller by delegating to services and factories.
408481
409482
*Why?*: Logic may be reused by multiple controllers when placed within a service and exposed via a function.
@@ -449,7 +522,6 @@ While this guide explains the *what*, *why* and *how*, I find it helpful to see
449522
*Why?*: Pairing the controller in the route allows different routes to invoke different pairs of controllers and views. When controllers are assigned in the view using [`ng-controller`](https://docs.angularjs.org/api/ng/directive/ngController), that view is always associated with the same controller.
450523
451524
```javascript
452-
453525
/* avoid - when using with a route and dynamic pairing is desired */
454526

455527
// route-config.js
@@ -542,7 +614,7 @@ While this guide explains the *what*, *why* and *how*, I find it helpful to see
542614
543615
- Note: [All AngularJS services are singletons](https://docs.angularjs.org/guide/services).
544616
545-
- **Public Members Up Top**: Expose the callable members of the service (it's interface) at the top, using a technique derived from the [Revealing Module Pattern](http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript).
617+
- **Accessible Members Up Top**: Expose the callable members of the service (it's interface) at the top, using a technique derived from the [Revealing Module Pattern](http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript).
546618
547619
*Why?*: Placing the callable members at the top makes it easy to read and helps you instantly identify which members of the service can be called and must be unit tested (and/or mocked).
548620
@@ -595,6 +667,102 @@ While this guide explains the *what*, *why* and *how*, I find it helpful to see
595667
596668
![Factories Using "Above the Fold"](https://raw.githubusercontent.com/johnpapa/angularjs-styleguide/master/assets/above-the-fold-2.png)
597669
670+
- **Function Declarations to Hide Implementation Details**: Use function declarations to hide implementation details. Keep your acessible members of the factory up top. Point those to function declarations that appears later in the file.
671+
672+
*Why?*: Placing accessible members at the top makes it easy to read and helps you instantly identify which functions of the factory you can access externally.
673+
674+
*Why?*: Placing the implementation details of a function later in the file moves that complexity out of view so you can see the important stuff up top.
675+
676+
*Why?*: Function declaration are hoisted so there are no concerns over using a function before it is defined (as there would be with function expressions).
677+
678+
*Why?*: You never have to worry with function declarations that moving `var a` before `var b` will break your code because `a` depends on `b`.
679+
680+
*Why?*: Order is critical with function expressions
681+
682+
```javascript
683+
/**
684+
* avoid
685+
* Using function expressions
686+
*/
687+
function dataservice($http, $location, $q, exception, logger) {
688+
var isPrimed = false;
689+
var primePromise;
690+
691+
var getAvengers = function() {
692+
// implementation details go here
693+
};
694+
695+
var getAvengerCount = function() {
696+
// implementation details go here
697+
};
698+
699+
var getAvengersCast = function() {
700+
// implementation details go here
701+
};
702+
703+
var prime = function() {
704+
// implementation details go here
705+
};
706+
707+
var ready = function(nextPromises) {
708+
// implementation details go here
709+
};
710+
711+
var service = {
712+
getAvengersCast: getAvengersCast,
713+
getAvengerCount: getAvengerCount,
714+
getAvengers: getAvengers,
715+
ready: ready
716+
};
717+
718+
return service;
719+
}
720+
```
721+
722+
```javascript
723+
/**
724+
* recommended
725+
* Using function declarations
726+
* and accessible members up top.
727+
*/
728+
function dataservice($http, $location, $q, exception, logger) {
729+
var isPrimed = false;
730+
var primePromise;
731+
732+
var service = {
733+
getAvengersCast: getAvengersCast,
734+
getAvengerCount: getAvengerCount,
735+
getAvengers: getAvengers,
736+
ready: ready
737+
};
738+
739+
return service;
740+
741+
////////////
742+
743+
function getAvengers() {
744+
// implementation details go here
745+
}
746+
747+
function getAvengerCount() {
748+
// implementation details go here
749+
}
750+
751+
function getAvengersCast() {
752+
// implementation details go here
753+
}
754+
755+
function prime() {
756+
// implementation details go here
757+
}
758+
759+
function ready(nextPromises) {
760+
// implementation details go here
761+
}
762+
}
763+
```
764+
765+
598766
**[Back to top](#table-of-contents)**
599767
600768
## Data Services

0 commit comments

Comments
 (0)