【读书笔记】JavaScript权威指南 第6版 (三)类型、值和变量

        (1)JavaScript的数据类型分为两类:原始类型和对象类型。

        (2)JavaScript中有两个特殊的原始值:null 和 undefined。

        (3)对象是属性的集合,每个属性都由“名/值对”构成。

        (4)普通的JavaScript对象是“命名值”的无需集合。数组,表示带编号的值的有序集合。

        (5)函数是具有与它相关联的可执行代码的对象,通过调用函数来运行可执行代码,并返回运算结果。对于JavaScript函数来讲,最重要的是,它们都是真值,并且JavaScript可以将它们当做普通的对象来对待。

        (6)每个构造函数定义了一类对象——由构造函数初始化的对象组成的集合。类可以看做对象类型的子类型。除了Array类和Function类之外,JavaScript语言核心定义了其他三种有用的类,Date类、RegExp类、Error类。可以通过自己的构造函数来定义需要的类。

        (7)JavaScript解释器有自己的内存管理机制,可以自动对内存进行垃圾回收。

        (8)JavaScript是一种面向对象的语言。不严格地讲,这意味着我们不用全局的定义函数去操作不同类型的值,数据类型本身可以定义方法来使用值。

        (9)在JavaScript中JavaScript对象、数字、字符串和布尔值都可以拥有自己的方法,只用null和undefined是无法拥有方法的值。

        (10)JavaScript可以自由地进行数据类型转换。

        (11)JavaScript变量是无类型的,变量可以被赋予任何类型的值,同样一个变量也可以重新赋予不同类型的值。

        (12)JavaScript采用词法作用域。不在任何函数内声明的变量称做全局变量,它在JavaScript程序中的任何地方都是可见的。在函数内声明的变量具有函数作用域,并且只在函数内可见。


3.1 数字

        (1)JavaScript不区分整数值和浮点数值,JavaScript中的所有数字均用浮点数值表示。

        (2)JavaScript采用IEEE 754标准定义的64位浮点数格式表示数字,然而值得注意的是,JavaScript中实际操作则是基于32位整数。

    3.1.1 整型直接量

        (1)除了十进制的整型直接量,JavaScript同样能识别十六进制值。

        (2)ECMAScript标准不支持八进制直接量

    3.1.2 浮点型直接量

        (1)浮点型直接量可以使用传统的实数写法,也可以使用指数计数法表示。

    3.1.3 JavaScript中的算术运算

        (1)JavaScript中的算术运算在overflow、underflow或被0整除时不会报错。

        (2)当数字运算结果超过了JavaScript所能表示的数字上限(溢出),结果为一个特殊的无穷大值,在JavaScript中以Infinity表示。负无穷大以-Infinity表示。

        (3)下溢是当运算结果无限接近于0并比JavaScript能表示的最小值还小的时候发生的一种情形。这种情况下,JavaScript将返回0。当一个负数发生下溢时,JavaScript返回一个特殊的值“负零”,负零几乎和正常的零完全一样。JavaScript程序员很少用到负零。

        (4)有一个例外,零除以零是没有意义的,这种整出运算的结果也是一个非数字值,用NaN表示。无穷大除以无穷大、给任意复数作开方运算或者算术运算与不是数字或无法转换成数字的操作数一起使用时都将返回NaN。

        (5)JavaScript预定义了全局变量Infinity和NaN,用来表示无穷大和非数字值。这两个值定义为只读的。

        (6)JavaScript中的非数字值有一点特殊:它和任何值都不相等,包括自身。应当使用x!=NaN来判断,当且仅当x为NaN的时候,表达式的结果为true。

        (7)负零值和正零值是相等的,这意味着这两个值几乎一模一样,除了作为除数之外。

    3.1.4 二进制浮点数和四舍五入错误

        (1)实数有无数个,但JavaScript通过浮点数的形式只能表示其中有限的个数,也就是说,当在JavaScript中使用实数的时候,常常只是真实值的一个近似表示。

        (2)使用大整数进行重要的金融计算。

    3.1.5 日期和时间

        (1)JavaScript语言核心包括Date()构造函数,用来创建表示日期和时间的对象。


3.2 文本

        (1)字符串是一组由16位值组成的不可变的有序序列,每个字符通常来自于Unicode字符集。字符串的长度是其所含16位值的个数。

        (2)JavaScript并没有表示单个字符的“字符型”。

    3.2.1 字符串直接量

        (1)在JavaScript程序中的字符串直接量,是由单引号或双引号括起来的字符序列。

        (2)当JavaScript代码和HTML代码混杂在一起的时候,最好在JavaScript和HTML代码中各自使用独立的引号风格。

    3.2.2 转义字符
    3.2.3 字符串的使用

        (1)JavaScript的内置功能之一就是字符串连接。“+”用于字符串,则表示字符串连接。

        (2)在JavaScript中字符串是固定不变的。

    3.2.4 模式匹配

        (1)JavaScript定义了RegExp()构造函数,用来创建表示文本匹配模式的对象。

        (2)JavaScript采用Perl中的正则表达式语法。String和RegExp对象均定义了利用正则表达式进行模式匹配和查找与替换的函数。

        (3)两条斜线“/”之间的文本构成一个正则表达式直接量。


3.3 布尔值

        (1)布尔值只有两个值,保留字truefalse。

        (2)JavaScript程序中的比较语句的结果通常都是布尔值。

        (3)任意JavaScript的值都可以转换为布尔值。所有值包括对象都会转换成true,而这些值会被被转换成falseundefined、null、0、-0、NaN、“”(空字符)。

        (4)布尔值有三个布尔运算符:&&||!


3.4 null和undefined

        (1)对于null执行typeof运算,结果返回字符串“object”,也就是说,可以将null认为是一个特殊的对象值,含义是“非对象”。

        (2)如果要查询对象属性或数组元素的值时,返回undefined则说明这个属性或元素不存在。

        (3)如果函数没有返回值,则返回undefined。

        (4)引用没有提供实参的函数形参的值也只会得到undefined。

        (5)undefined是预定义的全局变量,它和null不一样,它不是关键字,它的值就是“undefined”。

        (6)如果使用typeof运算符得到undefined的类型,则返回“undefined”,表明这个值是这个类型的唯一成员。

        (7)尽管null和undefined是不同的,但它们都表示“值的空缺”,两者往往可以互换。判断相等运算符“==”认为两者是相等的(要使用严格相等运算符“===”来区分它们)。

        (8)如果你想将它们赋值给变量或属性,或将它们作为参数传入函数,最佳选择是使用null。


3.5 全局对象


3.6 包装对象

        (1)存取字符串、数字或布尔值的属性时创建的临时对象称做包装对象。


3.7 不可变的原始值和可变的对象引用

        (1)JavaScript中的原始值:undefined、null、布尔值、数字和字符串。

        (2)JavaScript中的对象:对象、数组和函数。

        (3)原始值是不可更改的;任何方法都无更改或“突变”一个原始值。

        (4)字符串中所有的方法看上去返回了一个修改后的字符串,实际上返回的是一个新的字符串。

        (5)原始值的比较是值的比较:只有在它们的值相等时它们才相等。

        (6)如果比较两个单独的字符串,当且仅当它们的长度相等且每个索引的字符都相等时,JavaScript才认为它们相等。

        (7)对象和原始值不同,首先,它们是可变的——它们的值是可修改的。

        (8)对象的比较并非值的比较:即使两个对象包含同样的属性及相同的值,它们也是不相等的。各个索引元素完全相等的两个数组也不相等。

        (9)对象值都是引用,对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。


3.8 类型转换

        (1)null和undefined属于例外,当将它们用在期望是一个对象的地方都会造成一个类型错误异常,而不会执行正常的转换。

    3.8.1 转换和相等性

        (1)需要特别注意的是,一个值转换为另一个值并不意味着两个值相等。

    3.8.2 显式类型转换

        (1)Object()函数在转换null和undefined的情况下不会抛出异常:它仅简单地返回一个新创建的空对象。

        (2)除了toString(),Number类为这种数字到字符串的类型转换场景定义了三个方法:toFixed(),toExponential(),toPrecision()。

        (3)parseInt()和parseFloat()是全局函数,不从属于任何类的方法。

    3.8.3 对象转换为原始值

        (1)对象到布尔值的转换非常简单:所有的对象对转换为ture。

        (2)对象到字符串和对象到数字的转换是通过调用待转换对象的一个方法来完成的:toString()和valueOf()。

        (3)值得注意的是,这里提到的字符串和数字的转换规则只适用于本地对象。宿主对象根据各自的算法可以转换成字符串和数字。

        (4)“+”和“==”应用的对象到原始值的转换包括日期对象的一种特殊情形。

        (5)日期类是JavaScript语言核心中唯一的预先定义类型,它定义了有意义的向字符串和数字类型的转换。


3.9 变量声明

        (1)如果未在var声明语句中给变量指定初始值,那么虽然声明了这个变量,但在给它存入一个值之前,它的初始值就是undefined。

    重复的声明和遗漏的声明

        (1)如果重复声明带有初始化器,那么这就和一条简单的赋值语句没什么两样。

        (2)如果你试图读取一个没有声明的变量的值,JavaScript会报错。

        (3)在ECMAScript5严格模式中,给一个没有声明的变量赋值也会报错。

        (4)在非严格模式下,如果给一个未声明的变量赋值,JavaScript实际上会给全局对象创建一个同名属性,并且他工作起来像(但并不完全一样)一个正确声明的全局变量。


3.10 变量作用域

        (1)一个变量的作用域是程序源代码中定义这个变量的区域。

        (2)在函数体内部,局部变量的优先级高于同名的全局变量。

    3.10.1 函数作用域和声明提前

        (1)JavaScript的函数作用域是指在函数内声明的所有变量 在函数体内始终是可见的。这意味着变量在声明之前甚至已经可用,这被称为声明提前,即JavaScript函数内声明的所有变量(但不涉及赋值)都被“提前”至函数体的顶部。“声明提前”这步操作是在JavaScript引擎的“预编译”时进行的,是在代码开始运行之前。

    3.10.2 作为属性的变量

        (1)当声明一个JavaScript全局变量时,实际上是定义了全局对象的一个属性。

        (2)当使用var声明一个变量时,创建的这个属性是不可配置的,也就是说这个变量无法通过delete运算符删除。

        (3)如果你没有使用严格模式并给一个未声明的变量赋值的话,JavaScript会自动创建一个全局变量。以这种方式创建的变量是全局对象的正常的可配值属性,并可以删除它们。

        (4)JavaScript全局变量是全局对象的属性,这是在ECMAscript规范中强制规定的。对于局部变量则没有如此规定,但我们可以想象得到,局部变量当做跟函数调用相关的某个对象的属性。

        (5)JavaScript可以允许使用this关键字来引用全局对象,去没有方法可以引用局部变量中存放的对象。这种存放局部变量的对象的特有性质,是一种对我们不可见的内部实现。

    3.10.3 作用域链

        (1)每一段JavaScript代码(全局代码或函数)都有一个与之关联的作用域链。这个作用域链是一个对象列表或者链表,这组对象定义了这段代码“作用域中”的变量。当JavaScript需要查找变量x的值的时候(这个过程称做“变量解析”),它会从链中的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个属性的值,如果第一个对象中不存在名为x的属性,JavaScript会继续查找链上的下一个对象,以此类推。如果作用域链上没有任何一个对象含有属性x,那么就认为这段代码的作用域链上不存在x,并最终抛出一个引用错误异常。

        (2)在JavaScript的最顶层代码中(也就是不包含在任何函数定义内的代码),作用域链由一个全局变量组成。

        (3)在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数和局部变量的对象,第二个是全局对象。

        (4)在一个嵌套的函数体内,作用域链上至少有三个对象。

        (5)当定义一个函数时,它实际上保存一个作用域链。当调用这个函数时,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的那个作用域链上,同时创建一个新的更长的表示函数调用作用域的“链”。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值