diff --git a/README.md b/README.md index 4887b8c..6b48d58 100755 --- a/README.md +++ b/README.md @@ -137,13 +137,18 @@ class B extends A { - [`parentProperty(..)`](#parentproperty) - [`parentCall(..)`](#parentcall) - [`parentOf(..)` / `childOf(..)` / `related(..)`](#parentof--childof--related) + - [`RawInstance(..)`](#rawinstance) + - [`Constructor(..)` / `C(..)`](#constructor--c) - [`mixin(..)`](#mixin) - [`mixins(..)`](#mixins) - [`hasMixin(..)`](#hasmixin) - [`mixout(..)`](#mixout) - [`mixinFlat(..)`](#mixinflat) - - [`RawInstance(..)`](#rawinstance) - - [`Constructor(..)` / `C(..)`](#constructor--c) + - [`Mixin(..)`](#mixin-1) + - [`(..)`](#mixin-2) + - [`.mode`](#mixinmode) + - [`.mixout(..)`](#mixinmixout) + - [`.isMixed(..)`](#mixinismixed) - [Utilities](#utilities) - [`normalizeIndent(..)` / `normalizeTextIndent(..)` / `doc` / `text`](#normalizeindent--normalizetextindent--doc--text) - [`deepKeys(..)`](#deepkeys) @@ -319,6 +324,8 @@ case. ### Mix-ins + + Prototype-based mixin... ```javascript var utilityMixin = { @@ -735,6 +742,77 @@ related(, ) These are similar to `instanceof` but will test if the two objects are in the same prototype chain and in case of `parentOf(..)`/`childOf(..)` in what order. + +### `RawInstance(..)` + +Make a raw (un-initialized) instance +``` +RawInstance(, , ..) + -> +``` + +`RawInstance(..)` will do the following: +- Create an instance object + - get result of `.__new__(..)` if defined, or + - if prototype is a function or `.__call__(..)` is defined, create a + wrapper function, or + - if constructor's `.__proto__` has a `.__rawinstance__(..)` use it + to create an instance, or + - if constructor's `.__proto__` is a function (constructor) use it + to create an instance, or + - use `{}`. +- Link the object into the prototype chain + + +_Un-initialized_ means this will not call `.__init__(..)` + + +`RawInstance(..)` can be called with and without `new`. + + +### `Constructor(..)` / `C(..)` + +Define an object constructor +``` +Constructor() +Constructor(, ) +Constructor(, , ) +Constructor(, , , ) +Constructor(, , ) + -> +``` + +`Constructor(..)` essentially does the following: +- Creates a _constructor_ function, +- Sets constructor `.name` and `.toString(..)` for introspection, +- Creates `.__rawinstance__(..)` wrapper to `RawInstance(..)` +- Sets constructor `.__proto__`, `.prototype` and `.prototype.constructor`, +- Mixes in _constructor-mixin_ if given. + +The resulting _constructor_ function when called will: +- call constructor's `.__rawinstance__(..)` if defined or `RawInstance(..)` + to create an instance, +- call instance's `.__init__(..)` if present. + + +Note that `Constructor(, )` is intentionally set as default +instead of having the _parent-constructor_ as the last argument, this is +done for two reasons: +- The main cause to inherit from a constructor is to extend it, +- In real code the `Constructor(, )` is more common than + empty inheritance. + + +Shorthand to `Constructor(..)` +``` +C(, ..) + -> +``` + + +`Constructor(..)` / `C(..)` can be called with and without `new`. + + ### `mixin(..)` _Mixin_ objects into a prototype chain @@ -816,76 +894,113 @@ Also like `Object.assign(..)` this _will_ overwrite attribute values in ``. -### `RawInstance(..)` +### `Mixin(..)` -Make a raw (un-initialized) instance +Create a mixin wrapper. ``` -RawInstance(, , ..) - -> +Mixin(, , ..) + -> ``` -`RawInstance(..)` will do the following: -- Create an instance object - - get result of `.__new__(..)` if defined, or - - if prototype is a function or `.__call__(..)` is defined, create a - wrapper function, or - - if constructor's `.__proto__` has a `.__rawinstance__(..)` use it - to create an instance, or - - if constructor's `.__proto__` is a function (constructor) use it - to create an instance, or - - use `{}`. -- Link the object into the prototype chain +This will create a more convenient `` object. +The following two are the same +```javascript +var mixin = { + // ... +} -_Un-initialized_ means this will not call `.__init__(..)` - - -`RawInstance(..)` can be called with and without `new`. - - -### `Constructor(..)` / `C(..)` - -Define an object constructor +var obj = mixinFlat({ + // ... +}, mixin) ``` -Constructor() -Constructor(, ) -Constructor(, , ) -Constructor(, , , ) -Constructor(, , ) - -> +and +```javascript +var mixin = Mixin('mixin', { + // ... +}) + +var obj = mixin('flat', { + // ... +}) ``` -`Constructor(..)` essentially does the following: -- Creates a _constructor_ function, -- Sets constructor `.name` and `.toString(..)` for introspection, -- Creates `.__rawinstance__(..)` wrapper to `RawInstance(..)` -- Sets constructor `.__proto__`, `.prototype` and `.prototype.constructor`, -- Mixes in _constructor-mixin_ if given. +The former approach is better suited for inline mixing in, where one could +use `Object.assign(..)` while the later is more convenient for working with +library and reusable _mixin_ object as it is more readable and more centralized. -The resulting _constructor_ function when called will: -- call constructor's `.__rawinstance__(..)` if defined or `RawInstance(..)` - to create an instance, -- call instance's `.__init__(..)` if present. +This also makes combining mixins simpler +```javascript +var A = Mixin('A', { + // ... +}) +var B = Mixin('B', { + // ... +}) -Note that `Constructor(, )` is intentionally set as default -instead of having the _parent-constructor_ as the last argument, this is -done for two reasons: -- The main cause to inherit from a constructor is to extend it, -- In real code the `Constructor(, )` is more common than - empty inheritance. - - -Shorthand to `Constructor(..)` -``` -C(, ..) - -> +// this is a combination of A and B... +var C = Mixin('C', A, B, { + // NOTE: this "block" is optional... + // ... +}) ``` - -`Constructor(..)` / `C(..)` can be called with and without `new`. +Note that for multiple mixins used in `Mixin(..)` as well as in +[`mixin(..)`](#mixin)/[`mixinFlat(..)`](#mixinflat), mixins from right to +left, e.g. in the above example `B` will overwrite intersecting data in `A`, +... etc. +### `(..)` + +Mixin into `` as a prototype +``` +() +('proto', ) + -> +``` + +Mixin into `` as directly (flatly) +``` +('flat', ) + -> +``` + +These are similar to using [`mixin(..)`](#mixin) or [`mixinFlat(..)`](#mixin) +respectively. + + +### `.mode` + +Sets the default mode for `(..)`. + +Can be: +- `proto` + mix into prototype objects, like [`mixin(..)`](#mixin) +- `flat` + mix into object directly, like [`mixinFlat(..)`](#mixinflat) + + +### `.mixout(..)` + +Remove `` from `` +``` +.mixout() + -> +``` + +This is the same as [`mixout(..)`](#mixout) + +### `.isMixed(..)` + +Check if `` is mixed into `` +``` +.isMixed() + -> +``` + +This is the same as [`hasMixin(..)`](#hasmixin) ## Utilities diff --git a/object.js b/object.js index c8fbc39..6c913aa 100755 --- a/object.js +++ b/object.js @@ -1195,7 +1195,7 @@ Constructor('Mixin', { __init__: function(name, ...data){ // NOTE: .defineProperty(..) is used because this is a function // and function's .name is not too configurable... - // XXX do we need to configure this better??? + // XXX do we need to configure this prop better??? Object.defineProperty(this, 'name', { value: name }) this.data = mixinFlat({}, ...data.map(function(e){ diff --git a/package.json b/package.json index 1e1a719..c29d826 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-object", - "version": "5.4.2", + "version": "5.4.3", "description": "", "main": "object.js", "scripts": {