《JavaScript高级程序设计》:引用类型

389 阅读25分钟

前言

本系列是在学习JS的过程中所做的读书笔记,将重点知识提取出来在闲暇时刻翻阅,如果你看过这本书,那收藏起来当复习用;如果你没看过这本书,那还犹豫啥,收藏起来抱佛脚用的啦~~~

注:内容摘抄或总结自《JavaScript高级程序设计》第三到七章


引用类型是一种数据结构, 用于将数据和功能组织在一起。

对象是某个特定引用类型的实例。新对象是使用 new操作符后跟一个构造函数来创建的。

构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。

一、基本引用类型

1.Object 类型

创建 Object实例的方式有两种。

  • 第一种是使用 new 操作符后跟 Object 构造函数。
//var person = {};与 new Object()相同
var person = new Object();
person.name = "Nicholas"; 
person.age = 29; 
  • 另一种方式是使用对象字面量表示法。
var person = {     
    name : "Nicholas",     
    age : 29,
    5 : true //5会自动转换为字符串
};  
  • 在通过对象字面量定义对象时,实际上不会调用 Object 构造函数。
  • 对象字面量是向函数传递大量可选参 数的首选方式,这种传递参数的模式适合需要向函数传入大量可选参数的情形。
  • 一般来讲,命名参数虽然容易处理,但在有多个可选参数的情况下就会显示不够灵活。好的做法是对那些必需值使用命名参数,而使用对象字面量来封装多个可选参数。

2.Array 类型

  • 数组的每一项可以保存任何类型的数据
  • 数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据。
  • 在使用 Array 构造函数时也可以省略 new 操作符。如果传递的是数值,则会按照该数值创建包含给定项数的数组;而如果传递的是其他类型的参数,则会创建包含那个值 的只有一项的数组。
  • 与对象一样,在使用数组字面量表示法时,也不会调用 Array 构造函数。
  • 数组的 length属性很有特点—— 它不是只读的。因此,通过设置这个属性,可以从数组的末尾移 除项或向数组中添加新项。
  • 数组多可以包含 4 294 967 295个项。如果想添加的项数超过这个上限值,就会发生异常。而创建一个初始大小与这个上限值 接近的数组,则可能会导致运行时间超长的脚本错误。

检测数组

if (value instanceof Array){     
//对数组执行某些操作 
} 
  • instanceof操作符的问题在于,它假定只有一个全局执行环境。
  • 如果网页中包含多个框架,那实 际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的 Array 构造函数。
  • 为了解决上述问题,新增了 Array.isArray()方法,这个方法的目的是终确定某 个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。
 if (Array.isArray(value)){  
 //对数组执行某些操作 
 }  

转换方法

  • 所有对象都具有toLocaleString()、toString()和 valueOf()方法。
  • 数组的 toString()方法会返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。而调用valueOf()返回的还是数组。
  • join()方法只接收一个参数,即用作分隔符的字符串,然后返回包含所有数组项的字符串。
  • 如果不给join()方法传入任何值,或者给它传入 undefined,则使用逗号作为分隔符。
  • 如果数组中的某一项的值是 null 或者 undefined,那么该值在 join()、 toLocaleString()、toString()和 valueOf()方法返回的结果中以空字符串表示。

栈方法

  • 栈是一种 LIFO(Last-In-First-Out, 后进先出)的数据结构,也就是新添加的项早被移除。
  • 栈中项的插入(叫做推入)和移除(叫做弹出),只发生在一个位置——栈的顶部。
  • push()方法可以接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度。
  • pop()方法则从数组末尾移除后一项,减少数组的 length值,然后返回移除的项。

队列方法

  • 队列数据结构的访问规则是 FIFO(First-In-First-Out, 先进先出)。队列在列表的末端添加项,从列表的前端移除项。
  • 结合使用shift()和push()方法,可以像使用队列一样使用数组。
  • 同时使用 unshift()和pop()方法,可以 从相反的方向来模拟队列,即在数组的前端添加项,从数组末端移除项。

重排序方法

  • 数组中已经存在两个可以直接用来重排序的方法:reverse()和sort()。
  • sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,以 确定如何排序。
  • 即使数组中的每一项都是数值,sort()方法比较的也是字符串。所以会产生5排在10后面的情况。
  • sort()方法可以接收一个比较函数作为参 数,以便我们指定哪个值位于哪个值的前面。
  • 比较函数接收两个参数,如果第一个参数应该位于第二个之前则返回一个负数,如果两个参数相等 则返回 0,如果第一个参数应该位于第二个之后则返回一个正数。
function compare(value1, value2) { 
    if (value1 < value2) {       
        return -1;    
    } else if (value1 > value2) {   
        return 1;    
    } else {     
      return 0; 
    }
} 
 var values = [0, 1, 5, 10, 15];
 values.sort(compare);
 alert(values);  //0,1,5,10,15 
  • 以上方法在将比较函数传递到sort()方法之后,数值仍然保持了正确的升序。当然,也可以通过比较函数产生降序排序的结果,只要交换比较函数返回的值即可。
  • reverse()和sort()方法的返回值是经过排序之后的数组。

操作方法

  • concat()方法可以基于当前数组中的所有项创建一个新数组。这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,后返回新构建的数组。
  • slice()方法能够基于当前数组中的一或多个项创建一个新数组。接受一或两个参数,即要返回项的起始和结束位置。
  • slice()方法不会影响原始数。
  • 如果 slice()方法的参数中有一个负数,则用数组长度加上该数来确定相应的位 置。例如,在一个包含 5项的数组上调用 slice(-2,-1)与调用 slice(3,4)得到的 结果相同。如果结束位置小于起始位置,则返回空数组。
  • splice()方法
    • 删除:指定2个参数:要删除的第一项的位置和要删除的项数
    • 插入:需提供3个参数:起始位置、0(要删除的项数)和要插入的项。如果要插入多个项,可以再传入第四、第五,以至任意多个项。
    • 替换:需指定3个参数:起始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等。
    • splice()方法始终都会返回一个数组,该数组中包含从原始数组中删除的项(如果没有删除任何 项,则返回一个空数组)。

位置方法

  • indexOf()和lastIndexOf()。这两个方法都接收两个参数:要查找的项和(可选的)表示查找起点位置的索引。
  • indexOf()方法从数组的开头(位置 0)开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。
  • 这两个方法都返回要查找的项在数组中的位置,或者在没找到的情况下返回-1。

迭代方法

数组定义了 5个迭代方法,以上方法都不会修改原数组数组中的包含的值。

  • every():对数组中的每一项运行给定函数,如果该函数对每一项都返回true,则返回 true。
  • filter():对数组中的每一项运行给定函数,返回该函数会返回true的项组成的数组。
  • forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
  • map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组
  • some():对数组中的每一项运行给定函数,如果该函数对任一项返回true,则返回 true。

归并方法

reduce()和 reduceRight()。

  • 这两个方法都会迭代数组的所有项,然后构建一个终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历 到后。而reduceRight()则从数组的后一项开始,向前遍历到第一项。
  • 传给 reduce()和reduceRight()的函数接收 4 个参数:前一个值、当前值、项的索引和数组对象。
  • 使用 reduce()还是reduceRight(),主要取决于要从哪头开始遍历数组。除此之外,它们完全 相同。

3. Date 类型

  • Date 类型使用自 UTC(Coordinated Universal Time,国际协调时间)1970年 1月 1日午夜(零时)开始经过 的毫秒数来保存日期。
  • Date.parse()方法接收一个表示日期的字符串参数,然后尝试根据这个字符串返回相应日 期的毫秒数。
  • Date.parse()方法的字符串不能表示日期,那么它会返回NaN。如果直接将表示日期的字符串传递给Date构造函数,也会在后台调用 Date.parse()。
  • Date.UTC()方法同样也返回表示日期的毫秒数,但它与Date.parse()在构建值时使用不同的信息。
  • Date.UTC()的参数分别是年份、基于 0的月份(一月是 0,二月是 1,以此类推)、月中的哪一天 (1 到 31)、小时数(0 到 23)、分钟、秒以及毫秒数。
  • Data.now()方法,返回表示调用这个方法时的日期和时间的毫秒数。

继承的方法

  • Date 类型的 toLocaleString()方法会按照与浏览器 设置的地区相适应的格式返回日期和时间。这大致意味着时间格式中会包含 AM或 PM,但不会包含时 区信息(当然,具体的格式会因浏览器而异)。
  • toString()方法则通常返回带有时区信息的日期和时间,其中时间一般以军用时间(即小时的范围是 0 到 23)表示。
  • valueOf()方法,则根本不返回字符串,而是返回日期的毫秒表示。因此,可以 方便使用比较操作符(小于或大于)来比较日期值。

日期格式化方法

  • toDateString()——以特定于实现的格式显示星期几、月、日和年;
  • toTimeString()——以特定于实现的格式显示时、分、秒和时区;
  • toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;
  • toLocaleTimeString()——以特定于实现的格式显示时、分、秒;
  • toUTCString()——以特定于实现的格式完整的 UTC日期。

日期 /时间组件方法

方 法 说 明
getTime() 返回表示日期的毫秒数;与valueOf()方法返回的值相同
setTime(毫秒) 以毫秒数设置日期,会改变整个日期
getFullYear() 取得4位数的年份(如2007而非仅07)
getUTCFullYear() 返回UTC日期的4位数年份 setFullYear(年 设置日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
setUTCFullYear(年) 设置UTC日期的年份。传入的年份值必须是4位数字(如2007而非仅07) getMonth() 返回日期中的月份,其中0表示一月,11表示十二月
getUTCMonth() 返回UTC日期中的月份,其中0表示一月,11表示十二月
setMonth(月) 设置日期的月份。传入的月份值必须大于0,超过11则增加年份
setUTCMonth(月) 设置UTC日期的月份。传入的月份值必须大于0,超过11则增加年份
getDate() 返回日期月份中的天数(1到31)
getUTCDate() 返回UTC日期月份中的天数(1到31)
setDate(日) 设置日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
setUTCDate(日) 设置UTC日期月份中的天数。如果传入的值超过了该月中应有的天数,则增加月份
getDay() 返回日期中星期的星期几(其中0表示星期日,6表示星期六)
getUTCDay() 返回UTC日期中星期的星期几(其中0表示星期日,6表示星期六)
getHours() 返回日期中的小时数(0到23)
getUTCHours() 返回UTC日期中的小时数(0到23)
setHours(时) 设置日期中的小时数。传入的值超过了23则增加月份中的天数
setUTCHours(时) 设置UTC日期中的小时数。传入的值超过了23则增加月份中的天数
getMinutes() 返回日期中的分钟数(0到59)
getUTCMinutes() 返回UTC日期中的分钟数(0到59)
setMinutes(分) 设置日期中的分钟数。传入的值超过59则增加小时数
setUTCMinutes(分) 设置UTC日期中的分钟数。传入的值超过59则增加小时数
getSeconds() 返回日期中的秒数(0到59)
getUTCSeconds() 返回UTC日期中的秒数(0到59)
setSeconds(秒) 设置日期中的秒数。传入的值超过了59会增加分钟数
setUTCSeconds(秒) 设置UTC日期中的秒数。传入的值超过了59会增加分钟数
getMilliseconds() 返回日期中的毫秒数
getUTCMilliseconds() 返回UTC日期中的毫秒数
setMilliseconds(毫秒) 设置日期中的毫秒数
setUTCMilliseconds(毫秒) 设置UTC日期中的毫秒数
getTimezoneOffset() 返回本地时间与UTC时间相差的分钟数。例如,美国东部标准时间返回300。在某 地进入夏令时的情况下,这个值会有所变化

4. RegExp 类型

  • var expression = / pattern / flags ;,就可以创建一个正则表达式。
  • 每个正则表达式都可带有一或多个标志(flags),用以标明正则表达式的行为。 正则表达式的匹配模式支持下列 3个标志。
    • g:表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即 停止;
    • i:表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写;
    • m:表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项

RegExp实例属性

  • global:布尔值,表示是否设置了 g 标志。
  • ignoreCase:布尔值,表示是否设置了 i 标志。
  • lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从 0算起。
  • multiline:布尔值,表示是否设置了 m 标志。
  • source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。

RegExp实例方法

  • exec()接受一个参数,即 要应用模式的字符串,然后返回包含第一个匹配项信息的数组;或者在没有匹配项的情况下返回 null。
  • exec()返回的数组虽然是 Array 的实例,但包含两个额外的属性:index 和 input。其中,index 表示匹配 项在字符串中的位置,而 input 表示应用正则表达式的字符串。
  • test()接受一个字符串参数。在模式与该参数匹配的情况下返回true;否则,返回false。在只想知道目标字符串与某个模式是否匹配,但不需要知道其文本内容的 情况下,使用这个方法非常方便。
  • RegExp 实例继承的 toLocaleString()和 toString()方法都会返回正则表达式的字面量,与创 建正则表达式的方式无关。

RegExp构造函数属性

  • input 属性返回了原始字符串;
  • leftContext 属性返回了单词 short 之前的字符串,而 rightContext 属性则返回了 short 之后的字符串;
  • lastMatch属性返回近一次与整个正则表达式匹配的字符串,即 short;
  • lastParen属性返回近一次匹配的捕获组,即例子中的 s。

模式的局限性

不支持的特性

匹配字符串开始和结尾的\A 和\Z 锚 、向后查找(lookbehind) 、并集和交集类 、原子组(atomic grouping) 、Unicode支持(单个字符除外,如\uFFFF) 、命名的捕获组s(single,单行)和 x(free-spacing,无间隔)匹配模式 、 条件匹配 、正则表达式注释

5. Function 类型

  • 函数实际上是对象。每个函数都是 Function 类型的实例,而且都与其他引用类型一样具有属性和方法。
  • 函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。
  • 使用不带圆括号的函数名是访问函 数指针,而非调用函数。

没有重载

函数名为指针,再次定义的时候相当于将指针指向新的函数对象,覆盖之前的引用,所以不会形成重载。

函数声明与函数表达式

解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。

作为值的函数

函数接受两个参数。第一个参数应该是一个函数,第二个参数应该是要传递给该函数的一个值。

函数内部属性

  • 函数内部两个特殊对象this和arguments
  • arguments的主要用途是保存函数参数, 但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。
  • caller属性: 保存着调用当前函数的函数的引用, 如果是在全局作用域中调用当前函数,它的值为 null。

函数属性和方法

  • 每个函数都包含两个 属性:length 和 prototype。
  • length 属性表示函数希望接收的命名参数的个数。
  • prototype是保存它们所有实例方法的真正所在。所以toString()和valueOf()等方法实际上都保存在 prototype 名下。
  • prototype属性是不可枚举的,因此使用 for-in 无法发现。
  • 每个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的作 用域中调用函数,实际上等于设置函数体内 this 对象的值。
  • 传递参数并非 apply()和 call()真正的用武之地;它们真正强大的地方是能够扩充函数赖以运行的作用域。
  • 每个函数继承的 toLocaleString()和 toString()方法始终都返回函数的代码。

二、基本包装类型

我们知道,基本类型值不是对象,因而从逻辑上 讲它们不应该有方法(尽管如我们所愿,它们确实有方法)。

每当读取一个基本类型值的时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。

引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一 行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。

Object 构造函数也会像工厂方法一样,根据传入值的类型返回相应基本包装类型的实例。

1. Boolean 类型

  • Boolean类型的实例重写了valueOf()方法,返回基本类型值true或false;重写了toString() 方法,返回字符串"true"和"false"。

  • 基本类型与引用类型的布尔值还有两个区别。

    • typeof 操作符对基本类型返回"boolean", 而对引用类型返回"object"。
    • 由于Boolean对象是Boolean类型的实例,所以使用instanceof 操作符测试 Boolean 对象会返回 true,而测试基本类型的布尔值则返回 false。

2. Number 类型

  • Number 类型也重写了valueOf()、toLocaleString()和 toString() 方法。
  • 重写后的valueOf()方法返回对象表示的基本类型的数值,另外两个方法则返回字符串形式的数值。
  • 可以为 toString()方法传递一个表示基数的参数,告诉它返回几进制数值的字符串形式。
  • toFixed()方法会按照指定的小数位返回数值的字符串表示。
  • toExponential()方法返回以指数表示法(也称 e表示法)表示的数值的字符串形式。
  • toPrecision()方法可能会返回固定大小(fixed)格式,也可能返回指数 (exponential)格式。

3. String 类型

  • String 对象的方法也可以在所有基本的字符串值中访问到。
  • 继承的 valueOf()、toLocaleString()和 toString()方法,都返回对象所表示的基本字符串值。

字符方法

  • charAt()和 charCodeAt()。这两个方法都接收一个 参数,即基于 0的字符位置。
  • charAt()方法以单字符字符串的形式返回给定位置的那个字符。

字符串操作方法

  • concat()用于将一或多个字符串拼接起来,返回拼接得到的新字符串。
  • slice()、substr()和substring()。 这三个方法都不回修改字符串本身,会返回被操作字符串的一个子字符串。
  • slice()、substr()和substring()在传递正值的情况下结果大致相同,但是传递负值则有区别:
    • slice()方法会将传入的负值与字符串的长度相加
    • substr()方法将负的第一个参数加上字符串的长度,而将负的第二个 参数转换为 0
    • substring()方法会把所有负值参数都转换为 0

字符串位置方法

indexOf()和lastIndexOf():indexOf()方法从字符串的开头向后搜索子字符串,而lastIndexOf()方法是从字符串的末尾向前搜索子字符串。

trim()方法

这个方法会创建一个字符串的副本,删除前置及 后缀的所有空格,然后返回结果。

字符串大小写转换方法

toLowerCase()、toLocaleLowerCase()、toUpperCase()和 toLocaleUpperCase()。

字符串的模式匹配方法

  • match(),在字符串上调用这个方法,本质上与调用 RegExp 的exec()方法相同。match()方法只接受一个参数,要么是一个正则表达式,要么是一个 RegExp 对象。
  • search(),这个方法的唯一参数与 match()方法的参数相同:由字符串或 RegExp 对象指定的一个正则表达式。返回字符串中第一个匹配项的索引;如果没 有找到匹配项,则返回-1。而且始终是从字符串开头向后查找模式。
  • replace(),这个方法接受两个参数:第一个参数可以是一个RegExp对象或者一个字符串(这个字符串不会被转换成正则表达式),第二个参数可以是一个字符串或者一个函数。
  • split(),这个方法可以基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。

localeCompare()方法

这个方法比较两个字符串,并返回下列 值中的一个:

  • 如果字符串在字母表中应该排在字符串参数之前,则返回一个负数(大多数情况下是-1,具体的值要视实现而定);
  • 如果字符串等于字符串参数,则返回 0;
  • 如果字符串在字母表中应该排在字符串参数之后,则返回一个正数(大多数情况下是 1,具体的值同样要视实现而定)。

fromCharCode()方法

这个方法的任务是接收一或多个字符编码,然后将它们转换成一个字符串。

HTML方法

三、单体内置对象

1. Global对象

不属于任何其他对象的属性和方法,终都是它的属性和方法。

事实上,没有全局变量或全局函数;所有在全局作用域中定义的属性和函数,都是 Global 对象的属性。

  • URI编码方法 :Global 对象的encodeURI()和encodeURIComponent()方法可以对 URI(Uniform ResourceIdentifiers,通用资源标识符)进行编码,以便发送给浏览器。
  • eval()方法:该方法就像是一个完整的 ECMAScript解析器,它只接受一个参数,即要执行的 ECMAScript(或 JavaScript) 字符串。
    • 在 eval()中创建的任何变量或函数都不会被提升,因为在解析代码的时候,它们被包含在一个字符串中;它们只在eval()执行的时候创建。
    • 能够解释代码字符串的能力非常强大,但也非常危险。
  • window对象:ECMAScript 虽然没有指出如何直接访问 Global 对象,但 Web浏览器都是将这个全局对象作为 window对象的一部分加以实现的。因此,在全局作用域中声明的所有变量和函数,就都成为了 window 对象的属性。

2. Math对象

与我们在 JavaScript直 接编写的计算功能相比,Math 对象提供的计算功能执行起来要快得多。

属性

属 性 说 明
Math.E 自然对数的底数,即常量e的值
Math.LN10 10的自然对数
Math.LN2 2的自然对数
Math.LOG2E 以2为底e的对数
Math.LOG10E 以10为底e的对数
Math.PI π的值
Math.SQRT1_2 1/2的平方根(即2的平方根的倒数)
Math.SQRT2 2的平方根

min()和 max()方法

min()和 max()方法用于确定一组数值中的小值和大值。接受任意多个参数。

舍入方法

  • Math.ceil()执行向上舍入,即它总是将数值向上舍入为接近的整数;
  • Math.floor()执行向下舍入,即它总是将数值向下舍入为接近的整数;
  • Math.round()执行标准舍入,即它总是将数值四舍五入为接近的整数(这也是我们在数学课上学到的舍入规则)。

random()方法

Math.random()方法返回大于等于 0小于 1的一个随机数。

值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)

其他方法

小结

对象在 JavaScript 中被称为引用类型的值,而且有一些内置的引用类型可以用来创建特定的对象,现简要总结如下:

  • 引用类型与传统面向对象程序设计中的类相似,但实现不同;
  • Object 是一个基础类型,其他所有类型都从 Object 继承了基本的行为;
  • Array 类型是一组值的有序列表,同时还提供了操作和转换这些值的功能;
  • Date 类型提供了有关日期和时间的信息,包括当前日期和时间以及相关的计算功能;
  • RegExp 类型是 ECMAScript支持正则表达式的一个接口,提供了基本的和一些高级的正则表达式功能。

函数实际上是 Function类型的实例,因此函数也是对象;而这一点正是JavaScript有特色的地方。由于函数是对象,所以函数也拥有方法,可以用来增强其行为。

因为有了基本包装类型,所以JavaScript中的基本类型值可以被当作对象来访问。三种基本包装类型分别是:Boolean、Number 和 String。以下是它们共同的特征:

  • 每个包装类型都映射到同名的基本类型;
  • 在读取模式下访问基本类型值时,就会创建对应的基本包装类型的一个对象,从而方便了数据 操作;
  • 操作基本类型值的语句一经执行完毕,就会立即销毁新创建的包装对象。

在所有代码执行之前,作用域中就已经存在两个内置对象:Global 和 Math。在大多数ECMAScript 实现中都不能直接访问 Global 对象;不过,Web 浏览器实现了承担该角色的 window 对象。全局变 量和函数都是 Global 对象的属性。Math 对象提供了很多属性和方法,用于辅助完成复杂的数学计算 任务。

恭喜你又完成本章知识的学习啦!是不是又在基础上有不小的收获,这也是我在看这本书的过程中是不是感受到的!一起加油哇!点击以下链接直接跳转其他章节哦!

《JavaScript高级程序设计》:JS基础概念

《JavaScript高级程序设计》:JS变量、作用域和内存问题

《JavaScript高级程序设计》:引用类型

《JavaScript高级程序设计》:面向对象的程序设计

《JavaScript高级程序设计》:函数表达式