[从jQuery看JavaScript]-数据类型和对象(Type and Object)(一)

jQuery片段:

   在这一节,我们将讨论同一段jQuery片段的另一个知识点:数据类型和对象。为了让我们更好地理解代码,我们必须对这一部分内容深入了解。没有牢固的基础,是不可能构筑起坚实的堡垒的。

  • 内置数据类型

      内置数据类型,也称作固有数据类型,也就是JS的基本的数据类型。首先,让我们的大脑热一下身:回想一下,我们所有编程语言中实际可能运用到的数据都有些什么?
      基本如你所想,但实质上我们需要的只是有意义的文字而已。但对于电脑来说,它能认识的不是文字,而是逻辑电路中电平的高低。为此,我们在程序语言中,将这些高低电平转换成0和1,并使用这些二进制的数字串构造成人类更加好理解的数字逻辑。这些数字逻辑实际上就是所谓的数据类型了。(我承认我在胡说八道……)
      现在让我们看看JS是怎么理解这些数字逻辑,来让我们更好地使用它的(至少JS的设计者初衷是这样)。
     
    1. undefined

        我们第一个看到的数据类型是undefined。或许很多人都会怀疑到——你没有搞错吧?undefined也是一种数据类型?!然后,我可以很镇定的告诉你,我没搞错……

        看到上面的例子后,你还有疑问吗?
        联系一下我们前面所说的内容,如果调用一个没有声明的变量被直接调用,应该是会报错的,但上例没有,这就证明了undefined是JS里固有的变量。而且,根据typeof的结果,这个变量的数据类型是undefined。但它不是一个Object。而且不能用instanceof来判断他是不是undefined实例。
        那么,让我们来小结一下:undefined是一种类似单态的数据类型,他在全局作用域中以变量标识undefined存在,并且拥有唯一值undefined。
        除了上面所说的以外,还有一些需要注意的地方,请看下例:

        所以,如果你需要判断一个变量是否已声明,请使用typeof运算符,再和"undefined"这个字符串比较。如果你看得仔细,你或许会产生一个疑问:在上一节中不是说,如果在作用域链中找不到变量标识的时候,不是会创建空值标识吗?如果你有此一问,那么我得赞你一下,你真的用心思考了!这个问题将在稍后解答。

        另外,别以为undefined和字符串"undefined"是相等的,undefined不是字符串,而是另一种数据类型。
       
    2. null

        相信看完undefined后,你已经不再怀疑null也是一种数据类型了吧。可是null又有何特别呢?请看:

        你有感到奇怪了么?奇怪在哪里呢?嗯。我也觉得奇怪:为啥typeof的运算结果会是“object”,但instanceof判断又为false呢?但对于这个问题,能找到的唯一解答是如此描述的:
        “这点潜在的混淆是为了向下兼容。”
        但怎么向下兼容,我已经不能考究也不想考究下去了。我能告诉大家的是typeof null的返回值“object”是ECMA-262中规定的内容。并且这规定只是为了兼容性,实际上null并不是一个Object的实例。
        至此,我们再小结一下:null和undefined很相似,只是我们从根本上还是属于两种不同的数据类型。但是他们真的“不同”吗?让我们再来看看下面的例子:

        那么,看来JS解释器一般认为null和undefined是相等的了,虽然在严格等于运算时结果是false。(据说这是为了兼容以往的浏览器中没有undefined而设的。)
        由此引起了我们另一个思考:他们到底有何异同呢?实际上,导致他们严格等于运算返回false的是typeof的运算——在运算符节再详细解释吧。但他们其实还有一个语言规范层级的区别:undefined是作为Global对象的属性存在的,而null则是ECMA规范中设定的一个字面值。换句话说,undefined是存放在Global中的属性(所以像单态),而null是解释执行时产生的值。然而对他们的值作强制转换还是相同的,如:

        还值得注意的是,和其他语言不同,他们和0值是不相等的,除非转换成布尔值:

        另外,它们都不带属性的:

        最后,提一点我在项目中经常看到的,某些程序员喜欢将一些控件的属性是否定义的判定交给字符串"undefined"和null,但实际上只有null在起作用呢。
       
    3. boolean

        下一个我们看到的类型是boolean,也就是我们常用来判断真假的布尔型。它的值只有两个:true和false。让我们来看看它的特点:

        从上例我们可以看到,true和1相等,false和0相等,但是他们不能转换成1和0。并且,因为JS的弱数据类型,所以当x被赋予true和false以外的值后,他们的数据类型将会改变。
        布尔型的使用通常是在分支控制上,是JS中很关键的数据类型之一。
       
    4. number

        接着我们遇到的数据类型是number。顾名思义,number型就是指存放数字的类型。在其他语言中,我们遇到的数字型变量可能很多,分得很细,例如:short,int,long,float,double等等。但在JS中,所有的数字都被归纳成数字型的数据。回想一下如果我们对整型数据作不能整除的运算后会有什么结果?嗯,不能整除的部分将被截断。但在JS,结果会变得不一样:

        为什么会这样呢?因为JS实际上会把所有数字型的数据解释成浮点数。也就是无论你使用的数字是不是整数也好,JS的解释器都会把他看成浮点数的特例。
        虽然在数据类型上没有其他语言的复杂,但是我们仍然需要面对的是他能解释的数值范围。请看:

        可以看到,当数字超过2的1024次方减1后,该值就变为无限大(Infinity)了。我们可以用类似的方法再测出JS可以判定的数值范围,但我在这里就先省去了(其实也就是正负的21024)。我们跟着规范走:JS遵守的浮点标准是IEEE 754,换成具体的数字来说,如果把科学计数法算上,JS的数字运算能力最大可以到±1.7976931348623157x10308,最小到±5x10-324。然而,在我们实际运算中,大多运算符都不能支持这么高位的运算,请看:

        上例很明显可以看出,当数位超过15位时,计算精度就可以丢失。那么,究竟这个有效精度范围是怎样的呢?

        这次我们就可以明确了,加减运算精度是控制在253内的。也就是说,如果我们要处理253以外的数字运算的话,我们必须使用另外的方法了——例如数位拆分运算(名字我乱起的,实际意思就是将精度不可控的数位拆分成两个精度可控的小数去计算,最后由两个小数生成计算结果)。虽然要使用这种大数运算的机会几乎为零。

        虽然JS并不细分数字的数据类型,但是它对各种进制的数字还是有一定支持的。但就初始化用的字面值来说,数字型能支持的有八进制,十进制和十六进制。先看一下示例:

        字面值中表示十进制的数字无须任何修饰,而且能定义小数。
        表示八进制的数字需以0开头,但必须注意的是,后续的数字不能大于7,不然还是会被判断为十进制数字面值的。八进制数能表示负值,但不能表示小数。论坛中曾经有朋友遇到的问题就是因为八进制字面值引起的。因为他拿到的文本值是固定二位数,而单一数位大于7的字面值将被判断为十进制而正常运作,但进位后则变为8进制数,所以实际值与预期值就不相等了。
        表示十六进制的数字需要以0x或0X开头,后续数字为符合十六进制表示法的0-9或a-f的大小写字母。同样地,十六进制数能表示负值,但不能表示小数。
        从上例中,我们还能看到,无论我们用哪种进制的字面值,经过JS解释后,还是将会返回十进值值的 ——虽然内部存储必定还是二进制。我们也可以用方法转换其的进制显示。
        下面,我们看一下JS中的一些典型的字面值和可能产生误会的字面值:
      数字描述等价十进制数
      .0001, 0.0001, 1e-4, 1.0e-4四个相等的浮点数。0.0001
      3.45e2浮点数。345
      42整数。42
      0378整数。虽然看起来是八进制数(以0开头),但是8不是有效的八进制数字,所以为十进制数。378
      0377八进制整数。注意它虽然看起来比上面的数只小1,但实际数值有很大不同。255
      0.0001浮点数。虽然以零开头,但由于带有小数点所以不是八进制数。0.0001
      00.0001错误。两个零开头表示为八进制,但八进制数不能带有小数部分。N/A (编译错误)
      0Xff十六进制整数。255
      0x37CF十六进制整数。14287
      0x3e7十六进制整数。注意‘e’并不被认为指数。999
      0x3.45e2错误。十六进制数不能有小数部分。N/A (编译错误)
        另外,对于数字型的数据,有以下几个特殊值:
        a)NaN(not a number),意思不是一个数,但它却是数字型的一个值,当对不适当的数据进行数学运算时,例如字符串或未定义值,它将会作为运算结果返回。NaN不与任何值相等,包括它自己,但我们可以使用方法isNaN来判定一个值得是否NaN。
        b)Infinity,意思是无穷大,相对地,有负无穷大-Infinity。当一个数大于等于21024或小于等于21024,会分别用他们的正负形式来表示。所有Infinity是相等的,当然,区分正负地相等。
        PS:或许在规范中还有一个负零,字面值为-0。但是实际上,当其输出时,只是简单的0而已。不过我没对低版本的浏览器测试过。猜差要不就是低版本中会有所区分,要不就是存储时的二进制码有所区分。

        在这里说一个实用技巧:我们常会碰到需要把文本框中的数字的小数部分多余的0去掉。这个时候,我们可以使用数字型的特性:

        利用减0把字符强制转换成数字型后,尾数的0自然就去掉了。

        最后,要提醒一下,JS的浮点运算真的不怎么样,很容易就会有精度丢失的:

        解决方法有二:1)放大到整数来运算;2)对计算结果进行精度控制。
       
    5. string

        string,也就是我们最需要的字符串类型。任何其他类型,其实都是为了最终转换成字符串中人类可以理解的语言而服务的。那么这个令人着迷的数据类型又有何特别呢?我们先来看看如何定义一个字符串:

        是不是很简单呢?我也觉得也是。那么我们再来看点复杂的:

        这次是不是看到眼花缭乱呢?字符串里最“复杂”的应用莫过于引号的使用和转义符了。
        由于JS没有单字符的数据类型——如Java中的char,所以单双引号的成对使用时基本不存在区别——Java中单引号里的是单字符。而且单双引号能互相嵌套使用,但单(双)引号必须包含所有双(单)引号,并且双(单)引号中不能再出现单(双)引号。另一种可以使单(双)引号都能嵌套自身的方法是使用转义符“/”。
        另外,string支持unicode字面值,他们以并且只能以“/u”开头,后面跟四位的unicode编码(不区分大小写)。在定义后,所有的string都将按UTF16储存,所以不用担心输出的时候JS没有为你转码——当然,可以转码的是unicode字面值。
        最后提一下,string实际上是存放在有序数列中的。
       
    6. object

        呼呼!总算来到最后一个内置数据类型了。它的大名就是object!在Java中,Object类是所有类的基类,那么声称Java~Script的JS到底把object做了怎样的定位呢?
        由于JS中没有类的概念,所以就没有了继承。啊!等等,JS是存在继承的,而它是依赖prototype而存在的。至于这一部分的内容,我们放到prototype节里去讨论。我们现在先来关心一下object这个数据类型有何特别。

        object实际上是属性与方法的集合。在ECMA规范对其类型进行划分如下:
        本地对象(Native Object):指独立于宿主环境存在的对象,它可能是内置对象,也可能是在运行时由构造函数创建的对象,标准的本地对象是Global,Math,Object,Function,Number,Boolean,String,Array,Date,Math,RegExp和Error,非标准的本地对象则是指自建对象;
        内置对象(Build-in Object):指独立于宿主环境存在的对象,它们从JS进入运行时就能访问,标准的内置对象包括Global,Math,Object,Function,Number,Boolean,String,Array,Date,Math,RegExp和Error,也就是和标准的本地对象是一样的。非标准的内置对象则如JScript实现中的Enumerator等。但无论它是否标准的内置对象,所有内置对象都是本地对象
        宿主对象(Host Object):指依赖于宿主环境存在的对象,例如所有浏览器中的window(BOM)和document(DOM)对象。所有不是本地对象的对象都是宿主对象。

        下面我们来看一下如何才能得到一个object:

        虽然这个例子可能看不出区别,但是可以说得到一个Object的关键是关键字new。但在typeof运算中,遇到Function对象还是会返回"function"的。这个在稍后运算符节再讨论。
        从上面的例子,我们可以看到,JS中获取对象的方式和Java很相象。但实际上,它们的差别可大呢。这个留待对象中一一解说。

 

  • 内部数据类型

      除了在代码中我们可以使用的数据类型以外,JS中实际上还存在为了内部运行机制而设的三种数据类型:Reference、List和Completion。

    1. Reference

        Reference是一种内部数据类型,它是作为运算中间值存在的。它的内部有两个属性:base object和property name。而它的内部也有一些对应的方法去获取这两个属性。一般来说,base object里存放的是值,而property name里存放的是需要返回的标识。
        前面曾经提及作用域链找不到标识时,返回的是一个空值标识,其返回形式就是以Reference为数据类型传输的。所赋予的null值是存放于base object中的。而因为typeof的特性,在运算返回结果的时候,会判定base object值为null的Reference的最终typeof运算结果为"undefined"。而直接判定null的时候,因为null为一种数据类型,不需要经过Reference,所以返回的值是规范中定义的"object"。
    2. List

        List也是一种内部数据类型,也是作为运算中间值存在的。它具体作用于new运算符或函数调用时的参数列表。这些参数列表是简单的有序数列,而且可以是任意长的。PS:它和ArrayList是两种东西——一种是数据类型,另一种是对象。
        
    3. Completion

        和前面两个内部数据类型一样,Completion也是作为中间值存在的。它是运作于终结返回操作的,例如return, break, continue和throw。它的内部由三个要素构成:type, value, target。每一个要素都分别有其可以指定的值,这些值如下表:

      属性名

      可能值

      type

      normal, break, continue, return, throw

      value

      JS中的任何数据类型的值或者emtpy

      target

      JS中的标识或者emtpy

        

  由于担心篇幅太长难以维护的关系,我不得不在这里将此将此节截断,后面的内容将会继续于下篇更新。谢谢支持!

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
jsp内置对象 定义:可以不加声明就在JSP页面脚本(Java程序片和Java表达式)中使用的成员变量   JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应):    1.request对象    客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。    序号 方 法 说 明    1 object getAttribute(String name) 返回指定属性的属性值    2 Enumeration getAttributeNames() 返回所有可用属性名的枚举    3 String getCharacterEncoding() 返回字符编码方式    4 int getContentLength() 返回请求体的长度(以字节数)    5 String getContentType() 得到请求体的MIME类型    6 ServletInputStream getInputStream() 得到请求体中一行的二进制流    7 String getParameter(String name) 返回name指定参数的参数值    8 Enumeration getParameterNames() 返回可用参数名的枚举    9 String[] getParameterValues(String name) 返回包含参数name的所有值的数组    10 String getProtocol() 返回请求用的协议类型及版本号    11 String getScheme() 返回请求用的计划名,如:http.https及ftp等    12 String getServerName() 返回接受请求的服务器主机名    13 int getServerPort() 返回服务器接受此请求所用的端口号    14 BufferedReader getReader() 返回解码过了的请求体    15 String getRemoteAddr() 返回发送此请求的客户端IP地址    16 String getRemoteHost() 返回发送此请求的客户端主机名    17 void setAttribute(String key,Object obj) 设置属性的属性值    18 String getRealPath(String path) 返回一虚拟路径的真实路径    2.response对象    response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。    序号 方 法 说 明    1 String getCharacterEncoding() 返回响应用的是何种字符编码    2 ServletOutputStream getOutputStream() 返回响应的一个二进制输出流    3 PrintWriter getWriter() 返回可以向客户端输出字符的一个对象    4 void setContentLength(int len) 设置响应头长度    5 void setContentType(String type) 设置响应的MIME类型    6 sendRedirect(java.lang.String location) 重新定向客户端的请求    3.session对象    session对象指的是客户端与服务器的一次会话,从客户端连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.    序号 方 法 说 明    1 long getCreationTime() 返回SESSION创建时间    2 public String getId() 返回SESSION创建时JSP引擎为它设的惟一ID号    3 long getLastAccessedTime() 返回此SESSION里客户端最近一次请求时间    4 int getMaxInactiveInterval() 返回两次请求间隔多长时间此SESSION被取消(ms)    5 String[] getValueNames() 返回一个包含此SESSION中所有可用属性的数组    6 void invalidate() 取消SESSION,使SESSION不可用    7 boolean isNew() 返回服务器创建的一个SESSION,客户端是否已经加入    8 void removeValue(String name) 删除SESSION中指定的属性    9 void setMaxInactiveInterval() 设置两次请求间隔多长时间此SESSION被取消(ms)    4.out对象    out对象是JspWriter类的实例,是向客户端输出内容常用的对象    序号 方 法 说 明    1 void clear() 清除缓冲区的内容    2 void clearBuffer() 清除缓冲区的当前内容    3 void flush() 清空流    4 int getBufferSize() 返回缓冲区以字节数的大小,如不设缓冲区则为0    5 int getRemaining() 返回缓冲区还剩余多少可用    6 boolean isAutoFlush() 返回缓冲区满时,是自动清空还是抛出异常    7 void close() 关闭输出流    5.page对象    page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例    序号 方 法 说 明    1 class getClass 返回此Object的类    2 int hashCode() 返回此Object的hash码    3 boolean equals(Object obj) 判断此Object是否与指定的Object对象相等    4 void copy(Object obj) 把此Object拷贝到指定的Object对象中    5 Object clone() 克隆此Object对象    6 String toString() 把此Object对象转换成String类的对象    7 void notify() 唤醒一个等待的线程    8 void notifyAll() 唤醒所有等待的线程    9 void wait(int timeout) 使一个线程处于等待直到timeout结束或被唤醒    10 void wait() 使一个线程处于等待直到被唤醒    11 void enterMonitor() 对Object加锁    12 void exitMonitor() 对Object开锁    6.application对象 application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动, 直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性 的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。    序号 方 法 说 明    1 Object getAttribute(String name) 返回给定名的属性值    2 Enumeration getAttributeNames() 返回所有可用属性名的枚举    3 void setAttribute(String name,Object obj) 设定属性的属性值    4 void removeAttribute(String name) 删除一属性及其属性值    5 String getServerInfo() 返回JSP(SERVLET)引擎名及版本号    6 String getRealPath(String path) 返回一虚拟路径的真实路径    7 ServletContext getContext(String uripath) 返回指定WebApplication的application对象    8 int getMajorVersion() 返回服务器支持的Servlet API的最大版本号    9 int getMinorVersion() 返回服务器支持的Servlet API的最大版本号    10 String getMimeType(String file) 返回指定文件的MIME类型    11 URL getResource(String path) 返回指定资源(文件及目录)的URL路径    12 InputStream getResourceAsStream(String path) 返回指定资源的输入流    13 RequestDispatcher getRequestDispatcher(String uripath) 返回指定资源的RequestDispatcher对象    14 Servlet getServlet(String name) 返回指定名的Servlet    15 Enumeration getServlets() 返回所有Servlet的枚举    16 Enumeration getServletNames() 返回所有Servlet名的枚举    17 void log(String msg) 把指定消息写入Servlet的日志文件    18 void log(Exception exception,String msg) 把指定异常的栈轨迹及错误消息写入Servlet的日志文件    19 void log(String msg,Throwable throwable) 把栈轨迹及给出的Throwable异常的说明信息 写入Servlet的日志文件    7.exception对象    exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象    序号 方 法 说 明    1 String getMessage() 返回描述异常的消息    2 String toString() 返回关于异常的简短描述消息    3 void printStackTrace() 显示异常及其栈轨迹    4 Throwable FillInStackTrace() 重写异常的执行栈轨迹    8.pageContext对象    pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本类名也叫pageContext。    序号 方 法 说 明    1 JspWriter getOut() 返回当前客户端响应被使用的JspWriter流(out)    2 HttpSession getSession() 返回当前页中的HttpSession对象(session)    3 Object getPage() 返回当前页的Object对象(page)    4 ServletRequest getRequest() 返回当前页的ServletRequest对象(request)    5 ServletResponse getResponse() 返回当前页的ServletResponse对象(response)    6 Exception getException() 返回当前页的Exception对象(exception)    7 ServletConfig getServletConfig() 返回当前页的ServletConfig对象(config)    8 ServletContext getServletContext() 返回当前页的ServletContext对象(application)    9 void setAttribute(String name,Object attribute) 设置属性及属性值    10 void setAttribute(String name,Object obj,int scope) 在指定范围内设置属性及属性值    11 public Object getAttribute(String name) 取属性的值    12 Object getAttribute(String name,int scope) 在指定范围内取属性的值    13 public Object findAttribute(String name) 寻找一属性,返回起属性值或NULL    14 void removeAttribute(String name) 删除某属性    15 void removeAttribute(String name,int scope) 在指定范围删除某属性    16 int getAttributeScope(String name) 返回某属性的作用范围    17 Enumeration getAttributeNamesInScope(int scope) 返回指定范围内可用的属性名枚举    18 void release() 释放pageContext所占用的资源    19 void forward(String relativeUrlPath) 使当前页面重导到另一页面    20 void include(String relativeUrlPath) 在当前位置包含另一文件    9.config对象    config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)    序号 方 法 说 明    1 ServletContext getServletContext() 返回含有服务器相关信息的ServletContext对象    2 String getInitParameter(String name) 返回初始化参数的值    3 Enumeration getInitParameterNames() 返回Servlet初始化所需所有参数的枚举

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值