npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

proteus-2

v0.0.3

Published

FORK::: A declarative way of creating objects, properties, and classes in ES5 JavaScript

Downloads

14

Readme

proteus

A declarative way of creating objects, properties, and classes in ES5 JavaScript

ˈprōtēəs; ˈprōˌt(y)oōs

In Greek Mythology a minor sea god (son of Oceanus and Tethys) who had the power of prophecy but who would assume different shapes to avoid answering questions.

From the Greek protos "first."

Overview

Proteus is a little library of utility functions that I put together to help manage creating objects and implementing classical inheritance in JavaScript flavors 1.8+.

Object Creation and Modification

Proteus.create(proto, props)

Interface to Object.create, however, the props argument is a plain object of properties to copy over to the newly created object. Getters and setters will be preserved.

Proteus.defineProperty(obj, name, val, [spec])

Utility method for creating 'plain' properties on an object. Plain being {enumerable: true, writable: true, configurable: true}, the passed spec can override these defaults.

Proteus.defineProperty(obj, "propName", 42);

Proteus.defineProperty(
    obj,
    "methodName",
    function () { /*...*/ },
    {enumerable: false}
);

Proteus.defineProperties(obj, list)

Define multiple properties.

Proteus.defineProperties(obj, [
    [obj, "propName", 42],
    [obj, "methodName", function () {
        /*...*/
    }, {
        enumerable: false
    }]
]);

Proteus.defineGetter(obj, name, fn, [spec])

Utility method for creating a getter on an object. The property definition will default to {enumerable: true, configurable: true} unless overridden with the spec object.

Proteus.defineSetter(obj, name, fn, [spec])

Utility method for creating a setter on an object. The property definition will default to {enumerable: true, configurable: true} unless overridden with the spec object.

Proteus.defineGetSet(obj, name, getter, [setter], [spec])

Utility method for creating both a getter and a setter on an object. The property definition will default to {enumerable: true, configurable: true} unless overridden with the spec object.

if setter is not given, then the getter function will be used for both getting and setting

Proteus.getPropertyNames(obj)

Get all property names for an object, all the way up the prototype chain.

Proteus.getPropertyDescriptor(obj, name)

Get a property descriptor for an object where ever it may exist in the prototype chain.

Proteus.copyOwnProperties(hidden = false, overwrite = true, supplier, receiver)

Copy properties from supplier to receiver. This method will preserve the property definitions from supplier to receiver (uses Object.getOwnPropertyDescriptor under the hood).

Proteus.copyAllProperties(supplier, receiver)

Copy all properties from supplier to receiver.

Proteus.applyProperties(supplier, receiver)

Copy all enumerable properties from supplier to receiver only if the property does not exist on the receiver object.

Proteus.applyAllProperties(supplier, receiver)

Copy all properties from supplier to receiver, but do not overwrite existing properties on receiver.

Proteus.merge(receiver, arg1, ..., argN)

Merge enumerable properties from all objects passed as arguments onto receiver.

Proteus.mergeAll(receiver, arg1, ..., argN)

Merge all properties from all objects passed as arguments onto reciever.

Proteus.apply(receiver, arg1, ..., argN)

Merge enumerable properties from all objects passed as arguments onto receiver, only if they do not exist on receiver.

Proteus.applyAll(receiver, arg1, ..., argN)

Merge all properties from all objects passed as arguments onto receiver, only if they do not exist on receiver.

Proteus Utility Methods

Proteus.slice(list, offset = 0, end = list.length)

Return a portion of the array-like object.

Proteus.aliasMethod(name, [scope])

Return a function that is bound to call another function on the current object, or the supplied one.

Proteus.delegateMethod(obj, name, [args, ...])

Delegate a function call to another object. Additional arguments will be prepended to the function call.

Proteus.applyProto(self, [name], args = [])

Apply a method from the self object's prototype chain.

The name argument is optional if the function you are invoking from, and the one up the prototype chain you wish to invoke is named. e.g:

var Proteus = require("proteus"),
    objA = {
        someMethod: function someMethod () {
            console.log("I'm object A");
        }
    },
    objB = Proteus.create(objA, {
        someMethod: function someMethod () {
            Proteus.applyProto(this, arguments);
            console.log("I'm object B");
        }
    })
;

objB.someMethod();

// => I'm object A
// => I'm object B

Proteus.callProto(self, name, [arg1], [...], [argN])

Call a method name from the self object's prototype chain passing the remaining arguments as arguments.

Note: the name parameter is not optional.

Proteus.Class

Proteus.Class starts off the Proteus inheritance chain (itself is a descendent of Object). From there you can derive new classes from Proteus.Class (or any classes that are derived from Proteus.Class) to develop your class hierarchy.

var MyClass = Proteus.Class.derive({
        // props for MyClass
    }),
    MySubClass = MyClass.derive({
        // props for MySubClass
    })
;

Deriving Inheritance

ProteusClass.derive(props)

As shown above, use the static methods on the core Proteus.Class, or the Constructor functions returned by derive, to derive new subclasses.

In addition, Proteus allows you to define static properties on your subclass' Constructor function. Simply provide a property self in the passed properties for your class, and those will be copied to the Constructor function instead of the Constructor's prototype.

var MyClass = Proteus.Class.derive({
        self: {
            // Static properties for 'MyClass'
            myStaticMethod: function () {
                return true;
            }
        },
        // All other properties are put on the prototype
        instancePropA: "somevalue"
    });
    
MyClass.myStaticMethod(); // => true
(new MyClass()).instancePropA === "somevalue"; // => true

The Inherited Event

When one class is derived from another, and the superclass possesses a function property named inherited, the function will be called and passed the newly created Constructor function (i.e: the new subclass).

var MyBaseClass = Proteus.Class.derive({
        self: {
            inherited: function (subclass) {
                subclass.superParent = "MyBaseClass";
            }
        }
    }),
    MySubClass = MyBaseClass.derive({/* ... */})
;

MySubClass.superParent === "MyBaseClass"; // => true

ProteusClass.__super__ Property

Every class derived from Proteus.Class has a __super__ property that points to its super class' prototype.

var MyBaseClass = Proteus.Class.derive({
        someMethod: function () {
            // ...
        }
    }),
    MySubClass = MyBaseClass.derive({
        someMethod: function () {
            MySubClass.__super__.someMethod.call(this);
        }
    })
;

Including Instance Functionality

ProteusClass.include(obj1, ..., objN)

You can mix-in functionality from other Constructor function prototype's, or plain objects, into Proteus derived classes with the include method.

If passed a Constructor function, Proteus will copy the function's prototype properties to your Class' prototype. If passed a plain object, it will copy over those properties to the prototype of the class.

// Copy 'OtherClass' prototype properties to 'MyClass' prototype.
MyClass.include(OtherClass);

// Merge the passed object into 'MyClass'
MyClass.include({
    // Additional properties for MyClass.prototype
});

The Included Event

When an object, or Constructor function, is included into a Proteus Class its included function will be called and given the object that it was included into (the Proteus Class Constructor).

var MyModule = Proteus.Class.derive({
        self: {
            decorators: [],
            included: function (includee) {
                includee.decorators = this.decorators.slice();
            }
        }
    }),
    MyClass = Proteus.Class.derive({/* ... */})
;

MyClass.include(MyModule);
MyClass.decorators; // => []

Extending Your Class

ProteusClass.extend(obj)

You can use a ProteusClass's extend method to extend another object with its functionality.

var MyClass = Proteus.class.derive({
        self: {
            someMethod: function () {
                // ...
            }
        }
    });
    
// elsewhere
MyClass.extend(obj);
typeof MyClass.someMethod; // => "function"

The Extended Event

Instantiation

Report an Issue

License

Copyright (c) 2012 Jerry Hamlet [email protected]

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

The Software shall be used for Good, not Evil.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.