GithubHelp home page GithubHelp logo

jonrandy / turboprop Goto Github PK

View Code? Open in Web Editor NEW
16.0 1.0 1.0 25 KB

Use arrays as property accessors

License: MIT License

HTML 35.26% JavaScript 64.74%
accessor accessors array javascript js metho object properties property string syntax

turboprop's Introduction

Turboprop

Turboprop provides functionality to modify JavaScript arrays so that they can be used as property accessors (both for getting, and setting values). It also lets you define the methods by which the target object's properties are get and set using the accessor array.

That probably seems a lot like gibberish, so the best way to explain is with some sample code:

// Retrieve multiple values from an array
const arr = ['a', 'b', 'c', 'd', 'e']
console.log(arr[[0, 2, 4]])   // ["a", "c", "e"]

// Nested retrieval
console.log(arr[[0, 2, [3,4]]])   // ["a", "c", ["d", "e"]]

// Setting multiple values in an array
arr[[1, 3, 5]] = ['r', 'h', 's']
console.log(arr)   // ["a", "r", "c", "h", "e", "s"]

// combine getting and setting array values
arr[[0,1]] = arr[[2,0]]
console.log(arr)   // ["c", "a", "c", "h", "e", "s"]


// Retrieve multiple object properties
const obj = {a: 5, b: 6, c: 7, d: 8, e: 9}
console.log(obj[['b', 'c', 'e']])   // [6, 7, 9]

// Set multiple object properties
obj[['a', 'e']] = [33, 66]
console.log(obj)   // { a: 33, b: 6, c: 7, d: 8, e: 66 }


// Retrieve multiple characters from a string
const str = "Hello world!"
console.log(str[[0, 4, 7, 10, 11]])   // 'Hood!'
console.log(str[0[to(3)], 6[to(10)]])   // 'Hell world' (using 'to' from metho-number)

// Strings are immutable - hence no setting

// More useful(?) examples
const addr = "123 High Street, My Town, My State"
const address = {}
address[['line1', 'line2', 'line3']] = addr.split(',').map(s=>s.trim())
console.log(address)   // { line1: "123 High Street", line2: "My Town", line3: "My State" }

const obj1 = {type: 'box', col1: 'red', col2: 'blue', col3: 'green'}
const obj2 = {}
obj2[['item', 'colours']] = obj1[['type', ['col1', 'col2', 'col3']]
console.log(obj2)   // {item: 'box', colours:['red', 'blue', 'green']}

If you would like the above standard behaviours to be added to Array.prototype - giving ANY array gaining the ability to behave like this with other arrays, objects, and strings - simply call initialiseGlobally().

Why was this built?

Basically I just wanted to see if it was possible to do it. Ever since I wrote Metho, I've been churning ideas in my head about what other possibilities would be opened up with similar JS syntax hacking. Turboprop is the first useful(?) thing to come out of the ensuing experiments.

How it Works

Turboprop works by modifying the type coercion behaviour of an array so that when JS attempts to convert it to a string for the purpose of using it as a property accessor, the following things happen:

  • Temporary properties (named with a Symbol to avoid name clashes) are set up on predefined 'target' objects - from which the properties of the target will be accessed
  • 'Getter' and 'Setter' methods are defined for these temporary properties. These methods are responsible for retrieving and setting values on the target objects, using the original accessor array in whatever way they choose. After their job is done, they delete the temporary property to avoid clutter
  • Instead of returning a string from the coercion, the Symbol that names the temporary property is returned - which causes the relevant 'getter' or 'setter' method to be triggered on the target, carrying out the property retrieval or assignment as appropriate

Usage

Turboprop defines a few basic functions for its operation:

initialiseGlobally([state], [targetOrTargets])

This is just a convenience function to quickly modify Array.prototype so that all arrays can be used as property accessors for the default targets (see below for an explanation of 'targets'). It takes 2 optional parameters:

  • state - Defaults to true - specifies whether you want to switch functionality on or off
  • targetOrTargets - Specifies a target, or array of targets that may have their properties accessed by arrays. If not specified, this will default to the default Turboprop targets

Important note - because initialiseGlobally modifies the prototype of all arrays, it is possible (although unlikely) that conflicts with other libraries that do similar can occur. Despite this modification, the standard behaviour or arrays has been preserved as far as possible.

initialise([array], [targetOrTargets])

Turns the passed array into a 'Turboprop' array that can be used as a property accessor for the targets provided (see below for an explanation of 'targets'). It takes 2 optional parameters:

  • array - The array to convert. Will default to creating an empty array
  • targetOrTargets - Specifies a target, or array of targets that may have their properties accessed by the array. If not specified, this will default to the default Turboprop targets

The function modifies the passed array, and returns that same array.

isInitialisedArray(array)

Checks if the passed array is already initialised as a 'Turboprop' array. Returns a boolean.console.log(object[property])

Targets and Default Targets

A 'target' in Turboprop is an object that defines the object to be targeted, and the functions that define how 'getting' and 'setting' of properties using an accessor array will work:

const target = {
  object: objectToTarget,
  methods: {
    // logic to 'get' and return properties from targetObject
    getter: (propNamesAr, targetObject) => returnVal,
    // logic to 'set' properties on targetObject (any return value is discarded)
    setter: (propNamesArr, valuesToSet, targetObject) => {}
  }
}

The default targets are [ TARGET_STRING, TARGET_ARRAY, TARGET_OBJECT ] - designed to provide common, hopefully useful functionality. The constants defining each of the defaults are also exported by the library should you wish to use them yourself:

// String target
// Will 'get' a concatenation of chars specified by the indexes defined in the accessor array
const TARGET_STRING = {
  object: String.prototype,
  methods: {
    getter: (indexes, str) => indexes.reduce((newStr, index) => newStr + str[index], ''),
    setter: false
  }
}

// Array target
// Will 'get' an array of values specified by the indexes defined in the accessor array
// Will 'set' the values into the array slots specified by the indexes defined in the accessor array
const TARGET_ARRAY = {
  object: Array.prototype,
  methods: {
    getter: (indexes, arr) => indexes.reduce((newArr, index) => [...newArr, arr[index]], []),
    setter: (indexes, values, arr) => indexes.forEach((index, i) => arr[index] = values[i])
  }
}

// Object target
// Will 'get' an array of values specified by the property names defined in the accessor array
// Will 'set' the object properties specified by the property names defined in the accessor array
const TARGET_OBJECT = {
  object: Object.prototype,
  methods: {
    getter: (keys, obj) => keys.reduce((newArr, key) => [...newArr, obj[key]], []),
    setter: (keys, values, obj) => keys.forEach((key, i) => obj[key] = values[i])
  }
}

turboprop's People

Contributors

jonrandy avatar robinpokorny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

robinpokorny

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.