I've constructed a rather useful function to identify data-types; however, while coding happily I was rudely interrupted with a rather worrying dilemma.
As you may know, after calling .bind({foo:'bar'}) on a closure, you cannot access said foo property "externally"; however, inside the closure, this.foo works.
Also, when assigning something in such a way, you often face a throw: intermediary ... blah blah is undefined when you try access a property - directly after defining it. The code below fixes these issues but...
The problem is explained after the code:
"use strict";
if ('undefined' == typeof global)
{
    Object.defineProperty
    (
        window,'global',
        {
            writable:false,
            configurable:false,
            enumerable:false,
            value:window
        }
    );
}
Object.defineProperty
(
    Function.prototype, 'wrap',
    {
        writable:false,
        enumerable:false,
        configurable:false,
        value:function(jsob)
        {
            this.bind(jsob);
            for (var i in jsob)
            { this[i] = jsob[i]; }
            return this;
        }
    }
);
global.typeOf = function(data)
{
    if ((data === null) || (data === undefined))
    { return 'void'; }
    if ((data === true) || (data === false))
    { return 'bool'; }
    var tpof = (({}).toString.call(data).match(/\s([a-zA-Z]+)/)[1].toLowerCase());
    if ((tpof == 'array') || (tpof == 'htmlcollection') || (tpof == 'namednodemap'))
    { return 'list'; }
    if ((tpof == 'global') || (tpof == 'window'))
    { return 'glob'; }
    switch (tpof.substr(0,6))
    {
        case 'number': return 'unit';
        case 'string': return (/[^\x20-\x7E\t\r\n]/.test(data) ? 'blob' : 'text');
        case 'object': return 'jsob';
        case 'functi': return 'func';
        default: return 'node';
    }
}
.wrap
({
    list:'void bool unit text blob list jsob func node glob'.split(' '),
    init:function()
    {
        this.list.forEach(function(item)
        {
            global[(item.toUpperCase())] = item;
            global[('is'+(item[0].toUpperCase() + item.substr(1,item.length)))] = function(data)
            {
                return ((typeOf(data) == this.text) ? true : false);
            }
            .bind({text:item.toLowerCase()}); // <-- ISSUE
        });
        return this;
    }
}).init();
So the little wrapper above takes care of such weirdness; however, have a look on the line where <-- ISSUE is; see, I cannot use wrap() there, I have to use bind(), else - inside the function - this is undefined!!
Let me clarify: If you use the entire code just as it is above in <script> tags inside a brand-spanking-new html file; just change that ISSUE line's bind word to: wrap; then try something like: isText("bite me!");
You will see an error that specifies something like:
cannot read property "text" from undefined ..
so; if you do a console.log(this) inside that function definition there; you will see undefined.
If anyone could help fixing this, or at least explain why this is happening, I'd really appreciate the input.
 
    