Object.prototype.toString
... ...事实证明,我们可以。以一个在ES 5的外观规格为Object.prototype.toString ...
- Ø ToObject通过了呼吁的结果作为参数值 。
- 让类的价值[类]]内部属性 Ø。
- 返回字符串值,它是连接三根弦
“对象”
,阶级,和“]”
。
总之,目标函数默认的
toString返回一个字符串,格式如下 ...
[对象[类] ]
... ... [类别]是对象类的属性。
不幸的是,专门的内置
对象的toString的自己的方法
大多是覆盖Object.prototype.toString ...
... ...幸运的是我们可以使用呼叫功能,以
迫使
通用的toString在他们的功能...
1 | Object.prototype.toString.call([1,2,3]); |
3 | Object.prototype.toString.call( 新 日期); |
5 | Object.prototype.toString.call(AZ / /); |
在介绍该toType
功能
我们可以利用这种技术,添加一个正则表达式的下降,并创建一个微小的功能-一个新的和改进的版本typeof
运算操作符 ...
2 | 返回 ({}). toString.call(OBJ)。匹配(/ \ S([A - ZA - Z的]+)/)[ 1]。与toLowerCase() |
(因为一个新的模式,通用对象总是会使用 ToString 函数定义Object.prototype
的,我们可以放心地使用作为
缩写Object.prototype.toString ({}).
的 toString)
让我们来试试... ...
03 | ( 函数 (){(toType的console.log(参数))})(); |
04 | toType( 新 ReferenceError); |
10 | toType( 新 的String( “ABC” )); |
..现在,我们将运行相同的测试与typeof
运算符(尽量不要幸灾乐祸) ... ...
03 | ( 函数 (){的console.log( typeof运算 参数)})(); |
04 | typeof运算 新 ReferenceError; |
10 | typeof运算 新 的String( “ABC” ); |
鸭打字比较
鸭打字检查对一个给定的类型(像鸭子散步,像鸭子的谈判... ...)的已知属性的列表中的对象的特点。由于typeof运算
操作符的作用有限,鸭,打字在JavaScript中很受欢迎。它也容易出错。例如参数
的函数对象都有一个长度属性和数字索引的元素,但它仍然不是一个数组 。
使用toType
是一个可靠和易于的替代鸭打字 。可靠的,因为它直接谈判的对象,这是由浏览器引擎,是不可编辑的内部属性;容易的,因为其三个词检查。
这里的一个例证-一个片段,它定义不符合标准的JSON对象。jsonParseIt
函数接受一个函数作为参数,它可以用它来 测试之前,用它来 解析JSON字符串的JSON对象的真实性... 。
1 | window.JSON = {分析: 函数 (){警报( “我不是真正的JSON -失败 !” )}}; |
3 | 功能 jsonParseIt(jsonTest){ |
5 | 返回 JSON.parse( “{”A“:2}” ); |
7 | 警报( “不符合标准的检测到的JSON对象! “) ; |
让我们运行它,鸭打字第一... ...
jsonParseIt( 函数 (){ 返回 JSON&&( typeof运算 JSON.parse == “功能” )}) |
... ...哎呦... ...现在与toType
测试... ...
jsonParseIt( 函数 (){ 返回 toType(JSON)== “JSON” }); |
toType
可靠保护,对内置的JavaScript对象与冒名顶替的恶意交换?大概不会,因为行为人想必也可以交换toType
功能。一个更安全的测试可能会直接调用({}).的toString ...
函数 (){ 返回 ({}). toString.call(JSON)的indexOf( “JSON” )> -1} |
..但即使这会失败,如果Object.prototype.toString本身就是恶意重新编写的。静止每个额外的防御帮助。
比较到的instanceof
instanceof 运算符测试的原型链中的第一个操作数为原型属性的第二个操作数(第二个操作数预计将是一个构造函数,如果它不是一个函数,将抛出一个TypeError)存在:
3 | [1,2,3] 的instanceof 阵列; |
6 | 新 CustomType 的instanceof CustomType; |
在它面前,这似乎是一个不错的类型检查器的内置插件举行的承诺,但也有碰壁,这种方法至少有两个:
1。不具有关联的几个内置对象(数学
,JSON
和参数
)构造函数的对象-所以他们不能与类型检查的instanceof
运算符。
2。作为@ kangax和其他人指出,一个窗口可以包括多个帧,这意味着全球多个上下文和每种类型的,因此多个构造。在这样一个环境,一个给定对象的类型是不保证的instanceof
是一个给定的构造... 。
1 | VAR 的iFrame = document.createElement( “IFRAME” ); |
2 | document.body.appendChild(IFRAME); |
4 | VAR = window.frames [1]的数组。 |
5 | VAR 阵列= 新 IFrameArray(); |
8 | 阵列 的instanceof IFrameArray; |
类型检查主机对象
主机对象是浏览器的ES5标准不指定创建的对象 。所有DOM元素和全局函数的宿主对象。ES5下降到指定返回值typeof运算
,适用于主机对象时,它也不建议值[类]主机对象的财产。其结果是,跨浏览器的主机对象的类型检查一般是不可靠的:
07 | toType(document.createElement( 'A' )); |
元素的最可靠的跨浏览器测试,可能是检查了存在的
nodeType属性 ...
... ...但是,鸭打字,所以没有任何保证 ![;-)](https://i-blog.csdnimg.cn/blog_migrate/9178444501232b7305d2acdc0c3e2d3c.gif)
一个toType
功能应该在哪里生活?
为了简便起见,我的例子中定义toType
,作为一个全球性的的功能。扩展Object.prototype的将你抛出的龙 -我的喜好将直接扩展对象,它反映ES5(和建立该公约的Prototype.js在这之前)。
1 | Object.toType = 功能 (OBJ){ |
2 | 返回 ({}). toString.call(OBJ)匹配(/ \ S([AZ |排列]+)/)[ 1]与toLowerCase(); |
另外,你可以选择,
UTIL一个属于自己的命名空间,如
添加toType的功能。
我们可以得到一个小聪明(窗口
Chrome的使用“全局”的启发。[[类
]) 。,包装在一个全球性的的模块中的功能,我们可以找出全局对象:
1 | Object.toType =( 功能 toType(全球){ |
6 | 返回 ({}). toString.call(OBJ)匹配(/ \ S([AZ |排列]+)/)[ 1]与toLowerCase(); |
让我们来试试... ...
2 | Object.toType([1,2,3]); |
没有做什么toType
toType功能不能保护从未知类型的投掷ReferenceErrors ...
更确切地说,它是调用
toType抛出的错误,而不是函数本身 。反对,唯一的后卫(如与任何函数调用),养成良好的代码卫生... ...
window.fff&Object.toType(FFF); |
总结
我胡说在更长的时间比我打算 - 那么恭喜,如果你这里,我希望你觉得它有用。我介绍了很多地面和可能犯了一些错误 - 请随时让我知道他们。此外,我很乐意听到其他人的冒险类型检查。