2

谁能解释一下为什么这些代码可以检查数据类型?它们对我来说没有意义。我无法理解代码在幕后做了什么。提前致谢!

var toClass = {}.toString // {} is for what? toString is a method?

alert(toClass); // alert it I get a function? = > function toString() {[native code]}

alert( toClass.call( [1,2] ) )  
alert( toClass.call( new Date ) ) 
4

2 回答 2

5
var toClass = {}.toString;

相当于

var toClass = Object.prototype.toString;

因为

{}

作为表达式Object初始化程序)等价于

new Object()

其中Object是“具有该名称的标准内置构造函数”(ECMAScript 语言规范,5.1 版,第 11.1.5 节;和早期版本)。

所以{}代表对新Object实例的引用。 默认情况下,实例通过原型链(第 15.2.5 节Object)从最初引用的对象继承属性,包括内置属性。属性值最初是对实例的引用,即属性是您可以调用的方法(第 15.2.4.2 节)。Object.prototypeObject.prototype.toStringFunction

alert实际上是window.alert(并且应该这样写)。 window是 ECMAScript 全局对象的一个​​属性;该属性引用的对象是具有该alert方法的作用域链中的宿主对象。这些都没有在 ECMAScript 中指定,但它们由规范(第 15.1 节)允许的某些主机环境(通常由浏览器)提供。

因为它旨在显示警报消息,所以alert主机方法显示其第一个参数的字符串表示形式。对于对象,包括调用它们的toStringorvalueOf方法,以首先支持的为准(第 9.8 节)。Function实例,例如 引用的实例,{}.toString它们自己继承了一个toString方法,该方法返回函数的实现相关表示(第 15.3.4.2 节)。

但是,没有类,ECMAScript 的概念与[[Class]]“数据类型”的概念有些不同(请参阅typeofinstanceof)。这些是使用基于原型的继承的语言(第 4.2.1 节)。

于 2013-02-27T09:07:17.517 回答
1

这相当于:

Object.prototype.toString.call([1, 2]);
Object.prototype.toString.call(new Date);

这里,Object.prototype.toStringtoString所有对象默认继承的默认方法。调用时,它会打印如下内容:

[object XXX]

{}.toString在这里类似,因为{}new Object().

派生对象可以自由地覆盖该toString方法以满足其需要,例如:

> [1, 2].toString()
"1,2"

> (new Date).toString()
"Wed Feb 27 2013 17:03:42 GMT+0800 (Malay Peninsula Standard Time)"

但是,您仍然可以使用“原始”方法,方法是使用.call()onObject.prototype.toString{}.toString其中的第一个参数 to.call()用于定义this您正在调用的方法内部引用的内容。

于 2013-02-27T09:01:57.987 回答