JavaScript - 在(闭包)之后访问属性.bind()

时间:2016-05-10 01:54:06

标签: javascript

我构建了一个非常有用的函数来识别数据类型;然而,在愉快地编码时,我被一个相当令人担忧的困境粗暴地打断了。

如您所知,在关闭时调用.bind({foo:'bar'})后,您无法在外部访问所述foo属性;但是,在封闭内部,this.foo有效。

此外,在以这种方式分配内容时,当您尝试访问属性时,通常会在定义之后直接抛出:intermediary ... blah blah is undefined。下面的代码修复了这些问题,但是......

问题在代码后解释:

"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();

所以上面的小wrapper照顾这种奇怪;但是,请查看<-- ISSUE所在的行;看,我不能在那里使用wrap(),我必须使用bind(),否则 - 在函数内部 - this未定义!!

让我澄清一下:如果您使用整个代码就像上面的<script>标签内的品牌打击新的html文件一样;只需将ISSUE行的bind字词更改为:wrap;然后尝试类似:isText("bite me!");

您将看到一个错误,指定的内容如下:

  

无法从undefined中读取属性“text”。

如此;如果你在那个函数定义中做console.log(this);你会看到undefined

如果有人可以帮助解决这个问题,或至少解释为什么会发生这种情况,我真的很感激你的意见。

1 个答案:

答案 0 :(得分:1)

我认为这个wrap函数绝对没有用处。实际上,没有理由对此用例使用thisbind。只是做

global.typeOf = function(data) {
    if (data == null) return 'void';
    switch (typeof data)
        case "boolean": return 'bool';
        case "number": return 'unit';
        case "string": return /[^\x20-\x7E\t\r\n]/.test(data) ? 'blob' : 'text';
    }
    switch (Object.prototype.toString.call(data).slice(8, -1).toLowerCase()) {
        case "array":
        case "htmlcollection":
        case "namednodemap": return 'list';
        case "global":
        case "window": return 'glob';
        case "object": return 'jsob';
        case "function": return 'func';
        default: return 'node';
    }
};
global.typeOf.list = 'void bool unit text blob list jsob func node glob'.split(' ');

global.typeOf.list.forEach(function(item) {
    global[item.toUpperCase()] = item;
    global['is'+item[0].toUpperCase()+item.slice(1)] = function(data) {
        return typeOf(data) == item;
    }
});