@@ -804,48 +804,54 @@ function createInjector(modulesToLoad, strictDi) {
804804 }
805805 }
806806
807- function invoke ( fn , self , locals , serviceName ) {
808- if ( typeof locals === 'string' ) {
809- serviceName = locals ;
810- locals = null ;
811- }
812807
808+ function injectionArgs ( fn , locals , serviceName ) {
813809 var args = [ ] ,
814- $inject = createInjector . $$annotate ( fn , strictDi , serviceName ) ,
815- length , i ,
816- key ;
810+ $inject = createInjector . $$annotate ( fn , strictDi , serviceName ) ;
817811
818- for ( i = 0 , length = $inject . length ; i < length ; i ++ ) {
819- key = $inject [ i ] ;
812+ for ( var i = 0 , length = $inject . length ; i < length ; i ++ ) {
813+ var key = $inject [ i ] ;
820814 if ( typeof key !== 'string' ) {
821815 throw $injectorMinErr ( 'itkn' ,
822816 'Incorrect injection token! Expected service name as string, got {0}' , key ) ;
823817 }
824- args . push (
825- locals && locals . hasOwnProperty ( key )
826- ? locals [ key ]
827- : getService ( key , serviceName )
828- ) ;
818+ args . push ( locals && locals . hasOwnProperty ( key ) ? locals [ key ] :
819+ getService ( key , serviceName ) ) ;
829820 }
821+ return args ;
822+ }
823+
824+
825+ function invoke ( fn , self , locals , serviceName ) {
826+ if ( typeof locals === 'string' ) {
827+ serviceName = locals ;
828+ locals = null ;
829+ }
830+
831+ var args = injectionArgs ( fn , locals , serviceName ) ;
830832 if ( isArray ( fn ) ) {
831- fn = fn [ length ] ;
833+ fn = fn [ fn . length - 1 ] ;
832834 }
833835
834836 // http://jsperf.com/angularjs-invoke-apply-vs-switch
835837 // #5388
836838 return fn . apply ( self , args ) ;
837839 }
838840
841+
839842 function instantiate ( Type , locals , serviceName ) {
840843 // Check if Type is annotated and use just the given function at n-1 as parameter
841844 // e.g. someModule.factory('greeter', ['$window', function(renamed$window) {}]);
842- // Object creation: http://jsperf.com/create-constructor/2
843- var instance = Object . create ( ( isArray ( Type ) ? Type [ Type . length - 1 ] : Type ) . prototype || null ) ;
844- var returnedValue = invoke ( Type , instance , locals , serviceName ) ;
845-
846- return isObject ( returnedValue ) || isFunction ( returnedValue ) ? returnedValue : instance ;
845+ var ctor = ( isArray ( Type ) ? Type [ Type . length - 1 ] : Type ) ;
846+ var args = injectionArgs ( Type , locals , serviceName ) ;
847+ // Empty object at position 0 is ignored for invocation with `new`, but required.
848+ args . unshift ( { } ) ;
849+ /*jshint -W058 */ // Applying a constructor without immediate parentheses is the point here.
850+ return new ( Function . prototype . bind . apply ( ctor , args ) ) ;
851+ /*jshint +W058 */
847852 }
848853
854+
849855 return {
850856 invoke : invoke ,
851857 instantiate : instantiate ,
0 commit comments