Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Provides .extend()
convenience function with argument stubbing, always retaining the prototypal inheritance chain making instanceof
work.
npm install inher --save
var inher = require('inher');
// Create a child from the base Constructor.
var Child = inher.extend();
Child.prototype.add = function(a, b) {
return a + b;
};
// Create a grand child from the child using a Constructor.
var GrandChild = Child.extend(function(a, b){
this.a = a;
this.b = b;
});
GrandChild.prototype.getAddition = function() {
return this.add(this.a, this.b);
};
// instantiate a GrandChild
var grandChild = new GrandChild(4, 5);
console.log(grandChild.getAddition());
// prints: 9
inher.extend(...args=, Constructor=)
Any Type
Optional :: Any number of any type of arguments to use for stubbing the Parent Constructor. This is an advanced topic, more on that at Stubbed Arguments.Function
Optional :: Optionally pass a Constructor.Function
A new Constructor.Extend will create a new Constructor that inherits from the Ctor it was called from. Optionally you can define your own Constructor that will get invoked as expected on every new instantiation.
Extend uses the Pseudo Classical pattern, the same exact mechanism that is used by util.inherits
.
Check out the tests relating to extend()
and inheritance.
Using your own constructor when invoking extend()
is a good practise for properly initializing your instances. Your constructor may accept any number of arguments as passed on instantiation. All Parent constructors will receive the same exact arguments, unless you use Argument Stubbing...
Argument Stubbing is providing arguments to the extend()
function with the intend of passing them to the Parent constructor. Consider this case:
var Model = inher.extend(function(name) {
this._modelName = name;
});
Model.prototype.getName = function() {
return this._modelName;
};
var Model = require('./base.model');
// "user" is a stubbed argument, it will be passed to the
// Model Constructor as the first argument.
var UserModel = Model.extend('user', function(firstName, lastName){
this.firstName = firstName;
this.lastName = lastName;
});
var user = new UserModel('John', 'Doe');
console.log(user.getName());
// prints "user"
Argument Stubbing can be infinitely nested and inherited, Inher keeps track of each Constructor's Stubbed Arguments and applies them no matter how long the inheritance chain is.
Beware While Inher does a good job at not confusing passed functions as your Constructor, the last argument of the
extend()
method if it's of typefunction
is will always be used as the new constructor.
// can stub arguments without a constructor
var GrandChild = Child.extend(1, 2, 3);
// If last argument is a function it will be the Constructor
var GreatGrandChild = GrandChild.extend(4, 5, 6, function(){/* ctor */});
Check out the tests relating to argument stubbing.
Inher uses your constructor's arity to determine the exact amount of arguments to pass. This means that the constructor will get as many arguments as are defined, as long as they are available by the instantiation.
Static methods and properties are the ones that are defined on the Constructor directly vs using the prototype
. Static functions and properties do not get inherited by subsequent children. A good use for static properties is to define consts or enums that relate to your module.
var UserModel = Model.extend(function(userType) {
/** @type {UserModel.Type} Store the user type in the instance */
this._userType = userType;
});
/** @enum {string} The types of users */
UserModel.Type = {
ADMIN: 'admin',
MODERATOR: 'moderator',
USER: 'user',
};
// ...
var moderator = new UserModel(UserModel.Type.MODERATOR);
The inheritance pattern Inher uses dictates that all instances are created using the new
keyword.
var Thing = inher.extend();
var thing = new Thing();
Inher itself is a constructor that can be instantiated and has a prototype
that you can mingle with, but we don't want to go there now, do we? Be responsible.
Ctor.mixin(Constructor, [Ctor, Ctor])
...Function|Array.<Function>
:: Any number of Constructors passed as separate arguments or in an Array.void
Nothing.The mixin()
method will merge the prototype of the mixed in Ctors and ensure their constructors are invoked. The full inheritance chain of a Mixin is honored along with their respective Stubbed Arguments, if any. The Mixin's constructor will be invoked in the same context and therefore you can easily interact with internal properties and methods.
var Human = inher.extend(function() {
this.firstName = null;
this.lastName = null;
});
var Woman = inher.extend(function() {
this.favoriteColor = null;
});
var Man = inher.extend(function() {
this.favoriteChannel = null;
});
var Developer = inher.extend(function() {
this.programmingLanguages = [];
this.email = null;
});
var Designer = inher.extend(function() {
this.colors = [];
this.email = null;
});
// ...
var Unicorn = Human.extend();
Unicorn.mixin(Woman, Man, Developer, Designer);
// now that isn't quite a Unicorn, but you get the picture...
Array.isArray(Unicorn.colors); // true
Array.isArray(Unicorn.programmingLanguages); // true
null === Unicorn.favoriteChannel; // true
Mixin constructors will be invoked before the Constructor that mixed them in, so for the following case:
var Core = inher.mixin();
var MixinOne = Core.extend();
var MixinTwo = inher.extend();
var MixinThree = inher.extend();
var MixinFour = inher.extend();
var Child = inher.extend();
Child.mixin(MixinOne);
var GrandChild = Child.extend();
GrandChild.mixin(MixinTwo, MixinThree);
var GreatGrandChild = GrandChild.extend();
GreatGrandChild.mixin(MixinFour);
When GreatGrandChild
will be instantiated this will be the sequence of Constructor invocations:
Ctor.getInstance()
Object
An instance of Ctor.Use the getInstance()
for getting a singleton of the Constructor.
var UserController = Controller.extend(function(app) {
this.app = app;
});
// Get the singleton
UserController.getInstance();
// ... someplace else far far away ...
// This will return the same exact instance
var UserController = require('../../controllers/user.ctrl');
var userController = UserController.getInstance();
inher.wrap(VanillaCtor)
Function
:: A vanilla constructor.Function
:: A clone copy of the VanillaCtor augmented with Inher's static properties and functions.The wrap()
method is only available from the Inher module, it will add all the static methods that every Inher ctor has. wrap()
is used by Inher itself to create the new ancestors.
// Use EventEmitter as the base Constructor.
var EventEmitter = require('events').EventEmitter;
var inher = require('inher');
var IeventEmitter = inher.wrap(EventEmitter);
var Thing = IeventEmitter.extend();
var newThing = new Thing();
newThing instanceof IeventEmitter; // true
newThing instanceof EventEmitter; // true
inher.isInher(Ctor)
Function
:: A constructor.boolean
The isInher()
method is only available from the Inher module, it determines if a constructor has Inher properties.
var inher = require('inher');
var Thing = inher.extend();
inher.isInher(Thing); // true
wrap()
Now does not muttate the Ctor passed.getInstance()
will not accept arguments, it's an anti-pattern.Copyright (c) 2014 Thanasis Polychronakis. Licensed under the MIT license.
FAQs
Pseudo-classical Inheritance at its best
The npm package inher receives a total of 0 weekly downloads. As such, inher popularity was classified as not popular.
We found that inher demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.