我构建了一个非常有用的函数来识别数据类型;然而,在愉快地编码时,我被一个相当令人担忧的困境粗暴地打断了。
如您所知,在关闭时调用.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
。
如果有人可以帮助解决这个问题,或至少解释为什么会发生这种情况,我真的很感激你的意见。
答案 0 :(得分:1)
我认为这个wrap
函数绝对没有用处。实际上,没有理由对此用例使用this
或bind
。只是做
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;
}
});