$injector
, where they are awaited by a rather entertaining construct, which I would like to talk about today. return new (Function.prototype.bind.apply(ctor, args))();
bind
, apply
, new
and ()
functions. Let's figure it out. I suggest starting from the reverse, namely: let us have a certain parameterized constructor, an instance of which we want to create: function Animal(name, sound) { this.name = name; this.sound = sound; }
var dog = new Animal('Dog', 'Woof!');
. The new
operator is the first thing we need to get an instance of a call to the Animal
constructor. A small digression on how new works:When new Foo (...) is executed, the following happens:
1. A new object is created that inherits Foo.prototype.
2. The constructor is called - the function Foo with the specified arguments and this, bound to the newly created object. new Foo is equivalent to new Foo (), that is, if no arguments are specified, Foo is called without arguments.
3. The result of the expression new is the object returned by the constructor. If the constructor does not explicitly return an object, the object from item 1 is used. (Usually, constructors do not return a value, but they can do it if you need to override the normal process of creating objects.)
Read more
Animal
constructor in a function so that the initialization code is common to all the required calls: function CreateAnimal(name, sound) { return new Animal(name, sound); }
bind
function helps us perfectly).$injector.instantiate
, the second path was chosen: function Create(ctorFunc, name, sound) { return new (ctorFunc.bind(null, name, sound)); } console.log( Create(Animal, 'Dog', 'Woof') ); console.log( Create(Human, 'Person') );
bind
works:The bind () method creates a new function that, when invoked, sets the value provided as the execution context for this. The method also passes a set of arguments that will be set before the arguments passed to the bound function when it is called.
Read more
null
as context. we plan to use the new bind
function with the new operator, which ignores this
and creates an empty object for it. The result of the bind function is the new function with the arguments already attached to it (i.e. return new fn;
where fn
is the result of the bind
call).name
and sound
parameters. “But after all, not all the arguments that are required for animals will be necessary for people,” you will say and you will be right, two problems are brewing:Create
function and the instance creation string return new (ctorFunc.bind(null, name, sound ))
;apply
(or its analog call
, if the number of arguments is known in advance).The apply () method calls a function with the specified value this and the arguments provided as an array (or an array-like object).
Although the syntax of this function is almost completely identical to the call () function, the fundamental difference between them is that the call () function accepts a list (s) of arguments, while the apply () function takes an array of arguments (with a single parameter).
Read more
bind
function to our constructor (similar to ctorFunc.bind
), and as arguments to the bind
function (not forgetting that the first argument is the context to be set), pass the array of constructor parameters shifted one position to the right using ctorArgs.unshift(null)
.bind
function is not available in the execution context of Create
, since it is the window
object, but it is accessible through the function prototype Function.prototype
. function Create(ctorFunc, ctorArgs) { ctorArgs.unshift(null); return new (Function.prototype.bind.apply(ctorFunc, ctorArgs )); } console.log( Create(Animal, ['Dog', 'Woof']) ); console.log( Create(Human, ['Person', 'John', 'Engineer', 'Moscow']) );
Animal
and Human
, for example, constructors of factories or other types act, and arrays of arguments ['Dog', 'Woof']
are dependencies found (split) by name: angular .module('app') .factory(function($scope) { // constructor });
angular .module('app') .factory(['$scope', function($scope) { // constructor }]);
$injector.instantiate
method is to find the constructor function and get the necessary arguments and create it :)Source: https://habr.com/ru/post/330214/
All Articles