《JavaScript核心概念及实践》——第2章 基本概念 2.1 数据类型

第2章 基本概念

本章将聚焦于JavaScript中的基本概念,这些概念与传统语言有比较大的不同,因此单独列出一章来做专门描述。理解本章的概念对书中后续章节的概念,代码的行为等会有很大的帮助,读者不妨花比较多的时间阅读本章,即使你对JavaScript已经比较熟悉,也建议通读本章。

本章主要讲述JavaScript中的数据类型(基本类型与引用类型)、变量(包括变量的作用域)、操作符(主要是一些较为常见,但是不容易从字面上理解的操作符)。由于JavaScript中的“一切皆对象”,在掌握了这些基本的概念之后,读者就可以较为轻松地理解诸如作用域、调用对象、闭包等较难理解的概念了。

2.1 数据类型

有程序设计经验的读者肯定知道,在C或者Java这样的语言中,数据是有类型的。比如用以表示用户名的属性是字符串,而一个雇员的年龄则是一个数字,表示UI上的一个开关按钮的数据模型则为布尔值等,对数字可能还可以细分为浮点数、整型数,整型数又可能分为长整型和短整型,总而言之,它们都表示语言中的数据的值的类型。

JavaScript中的数据类型分为两种:基本数据类型和对象类型。其中对象类型包含对象、数组以及函数,基本数据类型在必要时会被隐式地转换为对象。

2.1.1 数据类型
在JavaScript中,包含6种数据类型、字符串(string)、数值(number)、布尔值(boolean),undefined、null及对象(object)。下面是一些简单的例子。

var str = "Hello, world";//字符串
var i = 10;//整型数
var f = 2.3;//浮点数

var b = true;//布尔值

我们可以分别查看变量的值及变量的类型:

print(str);
print(i);
print(f);
print(b);

print(typeof str);
print(typeof i);
print(typeof f);
print(typeof b);
print(typeof x);

注意,在此处使用的print()函数为Rhino解释器的顶层对象的方法,可以用来打印字符串。通常情况下,在客户端,程序员多使用alert()进行类似的动作,alert()是浏览器中JavaScript解释器的顶层对象(window)的一个方法。

Hello, world
10
2.3
true

string
number
number
Boolean
undefined

在JavaScript中,所有的数字,不论是整型、浮点型,都属于“数字”基本类型。typeof是一个一元的操作符,在本章的另外一个小节会专门讲到。

2.1.2 对象类型
这里提到的对象不是对象本身,而是指一种类型,我们在第3章会对对象进行详细的讨论,此处的对象包括:对象(属性的集合,即键值的散列表)、数组(有序的列表)、函数(包含可执行的代码)。

对象类型是一种复合的数据类型,其基本元素由基本数据类型组成,当然不限于基本类型,比如对象类型中的值可以是其他的对象类型实例,我们通过例子来说明。

var str = "Hello, world";
var obj = new Object();
obj.str = str;
obj.num = 2.3;

var array = new Array("foo", "bar", "zoo");

var func = function(){
    print("I am a function here");
}

可以看到,对象具有属性,如obj.str、obj.num,这些属性的值可以是基本类型,事实上还可以更复杂,我们来看看它们的类型。

print(typeof obj);
print(typeof array);
print(typeof func);

//将打印出
object
object
function

读者可能会对print(typeof array)打印出object感到奇怪,事实上,对象和数组的界限并不那么明显(事实上它们是属于同一类型的),但是它们的行为却非常不同,本书的后续章节将两个重要的数据类型做了分别介绍。

2.1.3 基本类型与对象间的转换
类似于Java中基本数据类型的自动装箱拆箱,JavaScript也有相应的动作,基本数据类型在做一些运算时,会临时包装一个对象,做完运算后,又自动释放该对象。我们可以通过几个例子来说明。

var str = "JavaScript Kernal";
print(str.length);//打印17
print(typeof str);//打印string

str为一个字符串,通过typeof可以得知其type为"string",而:

var str2 = new String("JavaScript Kernal");
print(typeof str2);//打印object

两次的typeof操作的结果来看,这两者并不相同,那么为什么可以使用str.length来得到str的长度呢?事实上,当使用str.length时,JavaScript会自动包装一个临时的String对象,内容为str的内容,然后获取该对象的length属性,最后,这个临时的对象将被释放。

而将对象转换为基本类型则是通过这样的方式:通过调用对象的valueOf()方法来取得对象的值,如果和上下文的类型匹配,则使用该值。如果valueOf取不到值的话,则需要调用对象的toString()方法,而如果上下文为数值型,则又需要将此字符串转换为数值。由于JavaScript是弱类型的,所以JavaScript引擎需要根据上下文来“猜测”对象的类型,这就使得JavaScript的效率比编译型的语言要差一些。valueOf()的优先级要高于toString()。

valueOf()的作用是,将一个对象的值转换成一种合乎上下文需求的基本类型,toString()则名副其实,可以打印出对象对应的字符串,当然前提是你已经“重载”了Object的toString()方法。

事实上,这种转换规则会导致很多的问题,比如,所有的非空对象,在布尔值环境下,都会被转成true,比如下面这个例子。

function convertTest(){
    if(new Boolean(false) && new Object() &&
     new String("") && new Array()){
        print("convert to boolean")
    }
}

convertTest();//convert to Boolean

初学者容易被JavaScript中的类型转换规则搞晕,很多情况下会觉得那种写法看着非常别扭,其实只需要掌握了规则,这些古怪的写法会大大提高代码的性能。我们通过例子来学习这些规则。

var x = 3;
var y = x + "2";// => 32
var z = x + 2;// => 5

print(y);
print(z);

通常可以在JavaScript代码中发现这样的代码:

if(datamodel.item){
    //do something...
}else{
    datamodel.item = new Item();
}

这种写法事实上具有更深层次的含义。

应该注意到,datamodel.item是一个对象(字符串、数字等),而if需要一个boolean型的表达式,所以这里进行了类型转换。在JavaScript中,如果上下文需要boolean型的值,则引擎会自动将对象转换为boolean类型。转换规则为:如果该对象非空,则转换为true,否则为false。因此我们可以采取这种简写的形式。

而在传统的编程语言(强类型)中,我们则需要:

if(datamodel.item != null){
    //do something...
}else{
    datamodel.item = new Item();
}

2.1.4 类型的判断
前面讲到JavaScript特性的时候,我们说过,JavaScript是一个弱类型的语言,但是有时我们需要知道变量/参数在运行时的类型,比如,一个函数接受的参数类型为函数类型。

function handleMessage(message, handle){
    return handle(message);
}

当调用handleMessage的函数传递的handle不是一个函数则JavaScript引擎会报错,因此我们有必要在调用之前进行判断。

function handleMessage(message, handle){
    if(typeof handle == "function"){
        return handle(message);
    }else{
        throw new Error("the 2nd argument should be a function");
    }
}

但是,typeof并不总是有效的,比如下面这种情况。

var obj = {};
var array = ["one", "two", "three", "four"];

print(typeof obj);//object
print(typeof array); //object

运行结果显示,对象obj和数组array的typeof值均为"object",这样我们就无法准确判断了,这时候,可以通过调用instanceof来进行进一步的判断。

print(obj instanceof Array);//false
print(array instanceof Array);//true

第一行代码返回false,第二行则返回true。因此,我们可以将typeof操作符和instanceof操作符结合起来进行判断。

时间: 2024-08-03 09:29:30

《JavaScript核心概念及实践》——第2章 基本概念 2.1 数据类型的相关文章

Javascript核心读书有感之语句

 这篇文章主要介绍了Javascript核心读书有感之语句,需要的朋友可以参考下     在javascript中,表达式是短语,那么语句(statement)就是整句或命令.正如英文语句以句号结尾,javascript以分号结尾. 表达式计算出一个值,但语句使某件事发生. "使某件事发生"的一个方法是计算带有副作用的表达式.诸如赋值和函数调用这些有副作用的表达式,是可以作为单独的语句的.这种把表达式当做语句的用法也称做表达式语句(expression statement).类似的语句

Javascript核心读书有感之表达式和运算符

这篇文章主要介绍了Javascript核心读书有感之表达式和运算符,十分详细,需要的朋友可以参考下     表达式是javascript中的一个短语,javascript解释器会将其计算出一个结果.程序中常用量是最简单的一类表达式就是变量.变量名也是一种简单的表达式,它的值就是赋值给变量的值. 复杂的表达式是由简单的表达式组成的.比如数组访问表达式是由一个表示数组的表达式,方括号.一个整数表达式构成.它们所组成新的表达式运算结果是该数组特定位置的元素值.同样的函 数调用表达式由一个表示函数对象的

Javascript核心读书有感之语言核心_基础知识

读此书之前,感谢淘宝技术团队对此javascript核心的翻译,感谢弗拉纳根写出此书.感谢你们无私的分享,仅以此笔记献给你们的辛勤付出. 一:javascript语言核心 本章之后,我们将主要关注javascript的基础知识.第二章我们讲解javascript的注释,分号和unicode字符集:第三章会更有意思,主要讲解javascript的变量和赋值 这里有一些实例代码说明前两章的重点内容. 复制代码 代码如下: <script type="text/javascript"&

JavaScript 设计模式与开发实践读书笔记

JavaScript 设计模式与开发实践读书笔记 最近利用碎片时间在 Kindle 上面阅读<JavaScript 设计模式与开发实践读书>这本书,刚开始阅读前两章内容,和大家分享下我觉得可以在项目中用的上的一些笔记. 我的 github 项目会不定时更新,有需要的同学可以移步到我的 github 中去查看源码: https://github.com/lichenbuliren/design-mode-notes 1.currying 函数柯里化 currying 又称 部分求值 .一个 cu

《C++多线程编程实战》——第1章 C++概念和特性简介1.1 介绍

第1章 C++概念和特性简介 C++多线程编程实战 本章介绍以下内容: 创建一个C++项目 程序结构.执行流.运行时对象 结构编程方法 理解面向对象编程方法 解释继承.重载和覆盖 理解多态 事件处理器和消息传递接口 链表.队列.栈示例 1.1 介绍 系统所执行的程序的进程或抽象是所有操作系统的核心概念.现在,绝大多数的操作系统在同一时间内都可以进行多项操作.例如,计算机在用户编辑Word文档时,还可以打印该文档.从硬盘缓冲区读数据.播放音乐等.在多任务操作系统中,中央处理单元(CPU)在程序中快

《混合云计算》——第一部分 理解概念和构成 第1章 发现你的计算环境的基础1.1 解构云计算的概念

第一部分 理解概念和构成 第1章 发现你的计算环境的基础 本章内容 解构云的概念 发现资源池/云计算模式和服务 评估数据中心的作用 发现公共云和私有云分别适合什么场景 事情变化得很快.云计算已经从一个危险和混乱的概念,发展成为大小机构都开始采用并作为其整体计算战略的一部分.几年前,当Hurwitz&Associates公司编写<云计算傻瓜书>时,还有很多的怀疑.企业会真正愿意采用云计算吗?云计算到底是什么,它如何帮助企业变得更有效呢? 在很短的时间内,市场已经走过了很长的路.今天,越来

《Git学习指南》——第1章 基本概念 1.1分布式版本控制,有何过人之处

第1章 基本概念 在本章中,我们将介绍一个分布式版本控制系统的设计思路,以及它与集中式版本控制系统的不同之处.除此之外,我们还将带你了解分布式版本库的具体工作方式,以及为什么我们会说,在Git中创建分支和合并分支不是个大不了的问题. 1.1 分布式版本控制,有何过人之处 在具体探讨分布式版本控制的概念之前,让我们先来快速回顾一下传统的集中式版本控制架构. 图1.1中所显示的就是一个集中式版本控制系统(例如CVS或Subversion)的典型布局.每个开发者都在他或她自己的计算机上有一个包含所有项

JavaScript核心参考教程--内置对象

博学,切问,近思--詹子知 (https://jameszhan.github.io) JavaScript 是根据 "ECMAScript"标准制定的网页脚本语言.这个标准由 ECMA 组织发展和维护.ECMA-262 是正式的 JavaScript 标准.这个标准基于 JavaScript (Netscape) 和 JScript (Microsoft).Netscape (Navigator 2.0) 的 Brendan Eich 发明了这门语言,从 1996 年开始,已经出现在

《社会调查数据管理——基于Stata 14管理CGSS数据》一第3章 概念与术语3.1 和计算机及软件有关的术语

第3章 概念与术语 社会调查数据管理--基于Stata 14管理CGSS数据 在开始讲解数据管理每个流程的工作内容之前,需要简单介绍一下和数据管理相关的概念. 在讲解相关概念和术语之前,首先需要了解一下什么是数据.很多耳熟能详.天天挂在嘴边的词,不见得人人都能对其做出精准的解释. 数据:在人类历史很长一段时期中,数据指的就是数字.当计算机诞生后,得益于数据处理技术的飞速发展,数据的外延不断扩大,而今,信息时代的数据除了包含数字数据外,还包括文本.图片.录音.录像等,数据的表现形式变得多样化,数据