`
kongxiantao
  • 浏览: 108060 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

辩:javascript 的数据类型

 
阅读更多

关于“javascript 的数据类型”,几个大神有声精彩的辩论,重要的观点记录如下。

 

看了这个辩论后,感觉以前清楚的又不清楚了,以前不清楚有清楚了,乱乱的。都了两三遍,感觉有有点清楚。后面有自己的认识。

 

=================================================

http://aimingoo.wordpress.com/2009/09/23/从“装b被雷劈”讲起/

 

 

我认为继续之前我们先理清几个术语

type:这个词也就是我们所说的类型

class:这个词也就是我们所说的类

好了,我认为js里面可分为这么几个type:number,boolean,undefined,null,string,object,除了object剩下的便是primitive type,而object可以认为是一种复合类型

 

1、函数是不是类型?是什么类型?

函数不是类型,函数是函数,是类型(type)为object的一个分类(class),一种特殊的object,可以执行(实现了内部属性[[call]])

2、为什么说JavaScript中的函数是“第一型”的?

这句话也时常听说,但是不知道出自何处,这个“第一型”不知道指的是type还是class,不过这里从强调函数在js中的重要性的角度来说是没问题的,

不过据我了解js被发明时借鉴了Scheme(函数式语言),所以有了first class这个特点,

关于js的诞生请参见http://www.ruanyifeng.com/blog/2011/06/birth_of_javascript.html,

我想您说的“第一型”,可能存在理解上的偏差,也许是翻译的有问题导致的,总之是first class没错,函数之于js确实重要

ps:type更强调种类,class更强调级别,有高低之分

 

3、undefined如何“包装成object”?即使你所说的是笔误,那么对于“一切都是对象”的JavaScript,undefined是什么?

 

这个问题我确实不知道怎么回答好,不过既然提出来了我就说下我的理解

先从简单的来吧,”undefined是什么?” undefined在概念上是类型为undefined值为undefined的这么一个东西;

权威指南上如是说:undefined is a predefined global variable (not a language keyword like null) that is initialized to the undefined value.(参见,第六版 3.4 null and undefined)

 

“一切都是对象”的JavaScript”,这句话我认为不能说一定正确,比如一个字面量并非是什么对象,1就是一个数值,只有1通过某种方式成为一个object的时候才是对象,比如new Number(1);

undefined如何“包装成object”? 不能,他本来就不是个object,也无法包装成object;

 

 

4、true与Boolean(true)在类型上有什么不同?

true 是boolean类型的一个值,Boolean是一个build-in Object,并且是个函数(特殊的可调用object);

 

当这些字面量在进行某些表达式运算时可能会转换成其对应的某类object,这个没有深究过。

 

您最后的强调我是认可的,存在着值类型和引用类型,并且值类型在某些情况下可以转换到引用类型,比如var one=new Number(1);

 

 

 

 

 

 

 

我是无意间看到这篇文章的,然后就发表了下自己的看法。

 

经过前面的讨论,有些地方我确实表述的有些偏差,比如我所有的地方都用小写,您也指出了:

“最后强调一下你的用词问题:Undefined是类型,undefined是值,’undefined’是类型的名称。”,今后我会注意这一点,描述类型(type)首字母大写。

 

在您刚才的回复中提出了两套类型系统,对于这个两套类型系统不知道您的依据是什么?不管是出于对其类型系统理解起来方便的考虑还是别的什么角度,在此我也不想做对与错的讨论了。

不过我还是坚持一下几个观点:

 

1、javascript 语言类型(language type)只有六种:Number,Boolean,String,Undefined,Null,Object,

您打开ecma规范,看其目录,点开8 Types,可以看到从8.1到8.6列出了这些类型,但是types里面没有function,也没有Function,更没有Function()。

 

2、函数是一种特殊的object,Object类型的一个分类(class),尽管typeof 对一个函数的运算结果是function,但仍不能作为一种type。

对于您提到instanceof的问题,我认为type是type,instance是instance完全不是一个概念,倒是作为识别某个对象属于某种对象分类的手段似乎更合理。

 

3、“一切都是对象”这句话我也一度将其奉为经典过,但现在至少我认为是不严谨的,甚至是错误的,容易误导人。我很想知道其出处。

 

4、first class 只能说强调了函数的重要性,将其译作作“第一型”本身就有问题,容易误导,我也曾经被误导过,如果撇开计算机,

撇开程序再去理解first class 也许能更好的理解其语言含义:”头等的“,跟类型完全没关系,我只想说 first class not first type.

 

5、对与我前面提到的primitive type(基本类型)的叫法,也并非我自己臆造的词,主要依据如下:

 

a)、

ECMA-262 5.1 Edition / June 2011 ——-9.1 ToPrimitive

The abstract operation ToPrimitive takes an input argument and an optional argument PreferredType. 

The abstract operation ToPrimitive converts its input argument to a non-Object type. If an object is capable of converting to more than one primitive type,

it may use the optional hint PreferredType to favour that type. Conversion occurs according to Table 10:(表省略,可自行查看).

 

期中提到primitive type

 

b)、你已经列出的那段关于property的引用,不在重复,相见 ECMA-262 5.1 Edition / June 2011 ——-4.2 Language Overview

 

c)、Javascript The Definitive Guide 6th Edition——–Chapter 3. Types,Values,and Variables,第二段:

JavaScript types can be divided into two categories: primitive types and object types.

JavaScript’s primitive types include numbers, strings of text (known as strings), and

Boolean truth values (known as booleans). A significant portion of this chapter is dedicated

to a detailed explanation of the numeric (§3.1) and string (§3.2) types in Java-

Script. Booleans are covered in §3.3.

The special JavaScript values null and undefined are primitive values, but they are not

numbers, strings, or booleans. Each value is typically considered to be the sole member

of its own special type. §3.4 has more about null and undefined.

 

当然这里并没说null and undefined是属于primitive types,而是说成 special type,从这个地方来看,您前面提到的朱先生的书中的内容”

JavaScript 语言只有 3 种最原始的数据类型:数值型、字符串型和布尔型……JavaScript 还定义了几个特殊的数据类型,如空类型(null)和未定义类型(undefined)。

基本数据类型按值传送,而复杂数据类型按引用传送。“

也并非完全无根无据的瞎说,至少不至于像您说的|

 

“这样的写法不但是“错”,而且还相当可笑。” 那么严重。

 

最后说明下我把primitive type叫做基本类型,也有叫做原始类型的,我现在也说不好哪个叫法更复合逻辑些。

我前面也提过,我的这些观点是基于 某些参考+实践 得出的,也许会存在错误,但至少目前我认为这些观点是合理的,对某些像”一切皆对象“、”第一型“之类的看似正确的说法的评价也是不为过。

 

另外,这里顺便提一下,我对所谓的”预编译“一词也不甚理解?不知道是谁第一个提出这样的说法?编译就编译,何来预编译?莫非指的预处理,不过也不像,

也许用这个词可以解释某些语言现象,不过在概念上确实让人迷糊。这里请爱民老师给指点下^_^

 

aiming答:其实,重要的是ECMAScript并不是强调语言类型的分类,也不强调JavaScript/ECMAScript是多范型语言这一事实。所以以它的定义来讨论一些问题,会有点讲不清。

关于预编译,一般是指预处理。不过很多编译器是采用“多道编译”的方案,也就是并非一次就生成了二进制代码。往往的,会有中间代码,

或者处理交叉链接(库)的情况,所以往往三次、更多次的编译都有。这些情况下,确实不好说哪一次或哪几次才是“预编译”。这一点应该视编译器而定。

最后,我不是权威,尽可质疑得;另外也不算老呵。

 

 

 

 

 

 

http://blog.csdn.net/aimingoo/article/details/6634977

再谈JavaScript的数据类型问题

 

aiming 观点:

 

1、函数是不是类型?是什么类型?

2、为什么说JavaScript中的函数是“第一型”的?

3、undefined如何“包装成object”?即使你所说的是笔误,那么对于“一切都是对象”的JavaScript,undefined是什么?

4、true与Boolean(true)在类型上有什么不同?

 

声明:

Undefined是类型,undefined是值,’undefined’是类型的名称。

 

 

体会:

其一,JavaScript不是纯粹的面向对象语言,它是混合语言,所以所谓“一切面向对象”既是宣传用语,也是一种语言处理技巧。

仅从“面向对象”来理解这个语言的类型,会犯很多错误。

其二,ECMAScript的描述总是很准确而又迟滞于这门语言的发展。所以要理解一些现象,既要从JavaScript的历史中去找,也要考虑到JavaScript现在的发展。

ECMAScirpt是一个标准的、规范化的参考,但不是全部。

 

 

JavaScript既是过程式语言,也是面向对象的语言。这一定程度上,也表现为:它事实上有两套类型系统。

第一套类型系统是用typeof来识别,这是这个语言的基本类型系统,只有六种类型,即undefined、number、boolean、string、object与function。我一般也称之为基础类型系统。

之所以称为“基础”,是因为第二套类型系统是以它为基础,从object这一种类型中发展起来的。

第二套类型系统即对象类型系统。对象类型系统用instanceof来识别。

 

 

对象类型系统与基础类型系统存在映射关系

例如基础类型的string影射到对象系统中的String。但这只是影射,所以本质上来说string类型不是String类型。两者本质上不同。

具体来说,undefined,string、number和boolean是“值类型”;

object与function是“引用类型”。

由于String、Number与Boolean在基础类型中都属于object类型,是Object()的子类,因此是引用类型。Function()也是引用类型。

所有引用类型都可以看着Object()的子类,所以任意函数也是Object()的子类。例如"<匿名函数> instanceof Object"返回true。

 

 

undefined 和 null

undefined是值类型,它没有对应的对象类型——我们通常可以称之为Undefined类型,但它没有对应的构造器。undefined只有一个值,即undefined。

准确地说,undefined表明声明(或产生)了但没有值的变量。

而Null也是一个类型,null是它的惟一值(按照语言规则,null也是一个关键字)。Null类型是对象类型,亦即是引用类型。

所以Null与Undefined本质的不同,是它们分属在不同的类型系统中,解释着不同类型系统中的“无”的概念。

一般来说,DOM中的某个属性或成员如果无值,应该使用null;而JavaScript运算过程中如果出现无值,应该使用undefined。

 

 

两个类型系统在JavaScript中是可以混用的,实现这一特性的技术被称为“类包装”。

JavaScript中的类包装过程出现然属性存取中,即“.运算符”或“[]运算符”。当这两个运算符发现左操作数x是一个“值类型”数据时,将隐式地调用Object(x)过程将它转为对象,因此

'abc'.length这个运算实际上就等效于Object('abc').length

 

 

 

结论:

aiming观点:JavaScript 里面有6种基本类型,对象是其中一种,各种对象是“对象(object)”这一种类型中的子类(类型)。

观点二:JavaScript 语言只有 3 种最原始的数据类型:数值型、字符串型和布尔型

JavaScript 还定义了几个特殊的数据类型,如空类型(null)和未定义类型(undefined)。

基本数据类型按值传送,而复杂数据类型按引用传送。

 

 

 

函数不是类型,函数是函数,是类型(type)为object的一个分类(class)

 

 

在回复里的讨论:

 

一、ECMAScript是标准,JavaScript是实现。举个不一定准确的例子来讲:

国家规定的铅笔型号有H、B两种,生产厂家非要做出个C型来也并没有什么不可以的。国标没有规定自动铅笔的笔芯大小,生产厂家自行规定了0.8mm到1.5mm不等的几种,

这也没什么不可以。而且,对于上面这个问题最关键的地方在于:这些“不标准”的铅笔事实上都有人用,而且还用得很好,很受称赞。

这跟ECMAScript是一个标准,但没法实用;而JScript与JavaScript作为具体的实现,有很多不标准的细节,但实用于不同的浏览器环境是一样的。

 

二、我写程序时会考虑null、0、false以及空字符串等等情况。某些时候,我甚至需要写test case以应对不同引擎中的处理。

 

三、在基本类型中,{} 是object类型;它是Object()类的一个实例。所有Object()及其子类的实例都是object类型。反之则不一定。例如null。

 

四、在基本类型中,var o = null;这种情况下o是object类型。如上面所说,它并不是Object()或其子类的一个实例。

 

五、在基本类型中,o = oSuck; 这种情况下o是function类型(你的示例中有个小笔误)。

在对象类型系统中,o是FunctionI()的一个实例,FunctionI()是Object()的子类,所以o也是一个对象。

 

六、上例证明了JavaScript是动态类型系统,它的变量与其类型并不是静态的、严格绑定的。

 

七、不存在“没有类型”的数据。这也是Undefined和Null类型出现的原因。此外,脚本的宿主环境可能扩展JS引擎的类型系统,这会导致一些例外。

ECMAScript的一部分价值在于使这些例外不自相矛盾,而不是限制它们不存在。

 

八、预编译的事情与这里的讨论无关。

 

 

 

 

http://blog.csdn.net/aimingoo/article/details/6636961

三谈类型问题:ECMAScript为什么错了?

 

 

错误的标准也是标准,在它“被纠正”之前,它就是严格正确的。

 

 

如果一个typeof(x)为true,其实只表明它是对象,可以使用对象存取运算符(.和[]),

以及可以使用for..in、with等等语句,但并不一定表明x.toString()就成功,或者x.constructor属性就存在。

因为typeof只决定了它是对象,并不决定它是Object()的子类实例。

 

 

 

1、两套类型系统是“创举”吗?

 

其实不是。最早一些JavaScript书籍在讲类型系统的时候,都是从typeof开始讲的。

 

2、为什么要有多套类型系统?

 

因为JavaScript是多范型的。

 

3、为什么JavaScript是这样的?

 

这其实很好。只是一些从应用角度讨论JavaScript的书,把这些问题讲乱了。

 

4、JavaScript中除了六种基本类型,还会出现其它“基本类型”吗?

 

会。一些具体的JavaScript的实现中,typeof可能会返回其它的值,例如JScript中就可能返回unknow。

 

5、ECMAScript正确吗?

 

它正确地描述了JavaScript的实现过程,以及在这个实现过程中的类型规范。但是对于类型在语言定义上的规范,却没有明显地提及。

 

6、什么是primitive value?又什么是primitive types?

 

你可以这样理解:

原始值(primitive value)是指一个语言在它存在之前应该存在的、可以用于实现该语言的值;

原始类型(primitive types)是不管这个语言自身对外表达的类型若何,但是在实现该语言是所必须的那些原始值的类型。

 

^^. 这个解释有点粗暴了。其实我的意思是想强调:千万不要用一个实现规范却讨论语言设计。

 

7、JavaScript的语源真的与C--没关系吗?

 

真的。没什么关系。我回头再发那篇考证文章出来。

 

 

==============================================================

在以上大神辩的基础上,我的认识和理解:

 

 

 

关于类型的表述方式:Undefined是类型,undefined是值,’undefined’是类型的名称。

 

基本类型系统,只有六种类型,即'undefined'、'number'、'boolean'、'string'、'object'与'function'。

对象类型系统:'object','null'

 

对象类型:String,Boolean,Number,Object,Null

值类型:string,boolean,number,undefined

 

说明:1.'function'是一种特殊的'object',Object类型的一个分类;

 2.Infinity和NaN是值类型,这个值是'number'的一个成员

 

 3.undefined 和 null 区别

undefined是值类型,它没有对应的对象类型——我们通常可以称之为Undefined类型,但它没有对应的构造器。undefined只有一个值,即undefined。

准确地说,undefined表明声明(或产生)了但没有值的变量。

而Null也是一个类型,null是它的惟一值(按照语言规则,null也是一个关键字)。Null类型是对象类型,亦即是引用类型。

所以Null与Undefined本质的不同,是它们分属在不同的类型系统中,解释着不同类型系统中的“无”的概念。

一般来说,DOM中的某个属性或成员如果无值,应该使用null;而JavaScript运算过程中如果出现无值,应该使用undefined。

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics