1. 函数

1.1. 什么是函数

  1. 函数将一系列语句组织成一个整体,以执行某一特定任务。
  2. 如果在不同的地方有些任务要重复执行,可以重用函数。

1.2. 简单函数示例

1
2
3
4
5
6
7
var a = 10;
var b = 20;
var area = 0;
function calArea() {
    area = a * b;
}
calArea();

1.3. 声明函数

  1. 要创建函数,需要首先对函数进行命名,然后在花括号中完成任务所需的语句,这就是函数的声明。
1
2
3
function sayHello() {
    alert("hello");
}
  1. 使用 function 关键字声明函数。
  2. 给函数指定名称,这里是 sayHello,然后紧跟一对括号。
  3. 执行任务的语句放在代码块(花括号内)。

1.4. 调用函数

  1. 声明了函数后,可以使用一行代码来执行函数里面的所有语句,这就是函数的调用。
1
sayHello();
  1. 如果要运行函数中的代码,需要在函数名后面加上一对括号。
  2. 可以在同一个 JavaScript 文件中调用同一个函数任意次。
  3. 函数有时候可以在声明前就被调用。这是因为解释器在执行某个具体的函数前会扫描所有的代码,所以会知道此函数的定义在脚本后面位置。

1.5. 声明需要信息的函数

  1. 有时,函数需要特定的信息来执行任务。
  2. 当函数需要外部的信息时,声明函数时需要给它提供形参。
  3. 在函数的内部,形参的行为类似变量。
1
2
3
function getArea(width, height) {
    return width * height;
}
  1. 函数需要的信息需要在函数名称后面的括号内指定。
  2. 括号中这些项就是函数的形参。

1.6. 调用需要提供信息的函数

  1. 调用带有形参的函数时,需要在函数名后面的括号中指定一些值,这些值就是实参,可以像变量一样被赋值。
  2. 值作为实参:
1
getArea(3, 4);
  1. 变量作为实参
1
2
var a = 3, b = 4;
getArea(a, b);
  1. 函数声明中,在括号中的变量被称为形参,在函数体中,它们的行为和变量一样。
  2. 传入的这些值就是实参。

1.7. 从函数中获得单一值

  1. 有些函数为调用它们的代码返回信息,例如返回计算结果。
  2. 使用 return 关键字将返回值返回给调用此函数的代码。
  3. 当出现 return 关键字时,解释器立刻离开函数,回到调用函数的代码。如果之后还有语句,将被跳过不执行。
1
2
3
function getArea(width, height) {
    return width * height;
}

1.8. 从函数获取多个值

  1. 使用数组,函数可以返回多个值。
1
2
3
4
function getArray() {
    var arr = [0, 1];
    return arr;
}

1.9. 匿名方法和函数表达式

  1. 表达式会产生值,这些值可以被用于所期望的位置。
  2. 如果函数被置于浏览器看到表达式的地方,那么函数将被当作表达式一样对待。
  3. 函数声明创建将来代码调用的函数,之前的函数都是这种形式,也就是先声明,再使用。
1
2
3
4
function getArea(width, height) {
    return width * height;
}
getArea(a, b);
  1. 如果将函数放在本该表达式待的地方,它将会被当作表达式对待,这被称为函数表达式。
  2. 在函数表达式中,名字经常被忽略,没有名字的函数被称为匿名函数。
  3. 可以将匿名函数赋值给某一个变量,之后使用变量名即可调用这个匿名函数。
1
2
3
var area = function(width, height) {
    return width * height;
}
  1. 在函数表达式中,解释器到达这条语句时函数是不会执行的,这意味着在解释器发现这条语句前,不能调用此函数,这和普通的函数声明有区别。

1.10. 立即调用函数表达式

  1. 立即调用函数表达式(IIFE),这些函数没有名称,在解释器经过它们时执行一次。
1
2
3
4
5
var area = ( function() { 
    var width = 3;
    var height = 4;
    return width * height;
} ());
  1. 上面名为 area 的变量存储了这个从函数返回的值,而不是保留在函数中以便未来调用。
  2. 右花括号后的最后一个括号告诉解释器马上调用此函数。
  3. 最外层的括号(分组操作符)确保解释器将其作为一个表达式对待。
  4. 匿名函数表达式和IIFE用于任务中只需要执行一次的代码,而不是在脚本中反复调用的代码。
  5. IIFE 通常被用作一组代码的封装器。在此匿名函数中声明的任何变量能够保护变量,防止其他脚本中出现同名变量。

2. 变量作用域

  1. 变量的声明位置将影响它的应用范围。
  2. 如果在函数内部声明变量,它就只能用于此函数,这就是变量的作用域。
  3. 在函数中用 var 关键字创建的变量只能在此函数内部使用,这就是局部变量或函数级别变量,该作用域也被称为局部作用域或函数级别作用域。
  4. 局部变量无法在创建它的函数之外使用。
  5. 在函数运行时,解释器创建一个局部变量,当函数完成任务时立即销毁。
  6. 因此,如果一个函数运行两次,局部变量可能具有不同的值;两个不同的函数可以使用同名变量而不会引起冲突。
  7. 如果在函数的外部创建变量,则该函数可以在脚本的任何地方被使用,这就是全局变量,且具有全局作用域。
  8. 全局变量在页面载入浏览器的时刻就进入内存。
  9. 全局变量会占用更多的内存,浏览器需要在整个页面载入期间保存它们,局部变量只需要在函数执行期间被保存。
  10. 全局变量有命名冲突的风险,如果一个 HTML 页面中引入了两个 JS 文件,这两个 JS 文件都定义了一个同名的全局变量,就可能导致错误。

3. 对象

3.1. 对象简介

  1. 对象将一组变量和函数组合起来,为真实世界创建模型。
  2. 在对象中,变量被认为是属性,属性用于描述这个对象。
  3. 如果一个函数是对象的一部分,我们称它为方法,方法代表和对象相关的任务。

3.2. 创建对象:字面量语法

  1. 字面量语法是最简单最常用创建对象的方法。
1
2
3
4
5
6
7
var person = {
    name: 'an',
    age: 22,
    getAge: function() {
        return this.age;
    }
}
  1. 对象是花括号及其中的内容,存储在变量 person 中。
  2. 每个键和值之间用冒号分隔。
  3. 每个属性和方法之间用逗号分隔(除了最后一个值)。
  4. this 关键字表明当前正在使用的对象本身。

3.3. 访问对象及其点标记语法

  1. 访问属性或者方法时使用点符号,也可以使用方括号。
1
2
3
var name = person.name;
var age = person.getAge();
age = person.["age"];

3.4. 创建对象:构造函数语法

  1. new 关键字和对象的构造函数结合可以创建一个空白对象,然后可以给这个空白对象添加属性和方法。
1
2
3
4
5
6
var person = new Object();
person.age = 22;
person.name = "an";
person.getAge = function() {
    return this.age;
}
  1. 这里 new Object() 创建了一个空对象,然后使用点标记语法向空对象中添加属性和方法,也可以使用字面量创建一个空对象,例如:
1
var person = {}

3.5. 修改对象

  1. 可以使用点符号或方括号来修改属性的值。
  2. 使用 delete 关键字可以删除属性。
1
2
person.name = "An";
delete person.name;

3.6. 创建很多对象:构造函数语法

  1. 对象构造函数可以使用函数作为模板来创建对象。
  2. 使用这种方法首先需要创建带有对象属性和方法的模板。
1
2
3
4
5
6
7
8
function Person(name, age) {
    this.name = name;
    this.age = age;

    this.getAge() = function() {
        return this.age;
    }
}
  1. 构造函数的名称通常首字母大写。
  2. 使用构造函数创建对象的实例时,需要使用 new 关键字后紧接着调用创建新对象的函数,每个对象的属性作为实参传递给函数。
1
var person = new Person("An", 22);

3.7. this 关键字

  1. this 关键字通常在函数内部或者对象内部使用。
  2. this 执行一个对象,通常是指向当前函数所操作的对象。
  3. 当一个函数创建于脚本的最高级别,也就是说,既不在另一个对象内,也不在其他函数内,它就位于全局作用域或者全局上下文中。
  4. 在全局上下文中的默认对象是 windows 对象,所以在全局上下文中使用 this 关键字时指向的就是 windows 对象。
  5. 所有全局变量也都会称为 windows 对象的属性,当一个函数在全局上下文中,也可以通过 windows 对象来访问它。
  6. 当一个函数嵌套于另一个函数之中时,this 的值可能会有些区别。为了访问外层函数的 this,可以将 this 作为实参传递给内层函数中。
  7. 在对象内定义函数时,该函数就是一个方法。此时,this 引用的就是包含此方法的对象。
  8. 如果命名函数定义在全局作用域内,且它马上被作为对象的方法使用,那么 this 代表着包含它的对象。
1
2
3
4
5
6
var width = {width: 300};
var showWidth = function() {
    return this.width;
}
width.showWidth = showWidth;
width.showWidth(); // 300

3. 数组对象

3.1. 数组也是对象

  1. 数组实际上是一种特殊类型的对象。
  2. 数组存储一组相关的键/值,只不过每个值的键都是索引编号。

3.2. 对象的数组和数组中的对象

  1. 可以将数组和对象合并在一起组成复杂的数据结构:数组可以存储一系列的对象,对象中也可以存储数组作为属性。

4. 内置对象

  1. 浏览器附带了一系列内置的对象,代表当前窗口中网页的一些内容。
  2. 内置对象可以分为如下三部分:
    1. 浏览器对象模型,包含一系列表示当前窗口或标签的对象,比如浏览器历史以及设备屏幕。
    2. 全局 JavaScript 对象,代表那些需要让 JavaScript 语言创建模型的事物。
    3. 文档对象模型,它为网页中的每个元素创建一个新对象。

4.1. 三组内置对象

  1. 浏览器提供的三组内置对象中的每一组都在不同范围内提供工具,方便编写网页脚本。

4.1.1. 浏览器对象模型

  1. 浏览器对象模型创建浏览器或窗口的模型。
  2. 最顶端的对象是 windows 对象,它代表当前浏览器窗口或者标签,它的子对象展示浏览器的其他特性。

4.1.2. 文档对象模型

  1. 文档对象模型(DOM)为当前网页创建模型。
  2. 最顶端的对象是 document,代表整个页面。它的子对象展现了当前页面上的其他项。

4.1.3. 全局 JavaScript 对象

  1. 全局对象不构成模型。
  2. 全局对象是一些独立的对象,分别与 JavaScript 语言的不同部分相关。
  3. 例如 String,Number 等。

4.2. 浏览器对象模型:window 对象

  1. window 对象代表当前浏览器中的窗口或标签,位于浏览器对象模型(BOM)中的最顶端,其中包含了描述浏览器的对象。
属性描述
window.innerHeight窗口高度(不包括边栏和工具栏)
window.innerWidth窗口宽度
window.pageXOffset文档滚动的水平距离(像素)
window.pageYOffset文档滚动的垂直距离
window.screenX鼠标点的X坐标,相对于屏幕左上角(像素)
window.screenY鼠标点的Y坐标
window.locationwindow对象的当前URL
window.document指向 document 对象,代表窗口中的当前页
window.history指向窗口或标签的 history 对象
window.history.length浏览窗口或标签的 history 对象中有多少项
window.screen指向 screen 对象
window.screen.width访问 screen 对象,读取 width 属性的值
window.screen.height访问 screen 对象,读取 height 属性的值
方法描述
window.alert()创建含有消息的对话框
window.open()在新的浏览器窗口中打开参数中指定的 url
window.print()告诉浏览器用户想要打印当前页的内容

4.3. 文档对象模型:document 对象

  1. 文档对象模型的最顶端是 document 对象。
  2. document 对象代表当前浏览器窗口或标签载入的页面。
属性描述
document.title当前文档的标题
document.lastModified文档最后一次被修改的日期
document.URL返回包含当前文档 URL 的字符串
document.domain返回当前文档的域
方法描述
document.write()将文本写入文档
document.getElementById()返回与id属性值相匹配的元素
document.querySelectorAll()返回一组元素,这些元素都符合参数中定义的CSS选择器
document.createElement()创建新元素
document.createTextNode()创建新的文本节点

4.4. 全局对象:String 对象

  1. 有了字符串值后,就可以对其使用 String 对象的属性和方法了。
  2. 这些属性和方法常用于处理变量或对象中的文本。
  3. String 对象既是全局对象,又是封装对象。它既可以像全局变量一样在任何地方都可以工作,同时任何值为字符串的对象都可以使用的行为又使得它好像封装器,只要值为字符串就可以使用这个对象的属性和方法。
  4. length 统计的是字符串中的字节单元数量,对于一些中文,一个字符可能占用多个字节单元。
属性描述
length返回字符串中的字节单元数量
方法描述
toUpperCase()将字符串修改为大写字母
toLowerCase()将字符串修改为小写字母
charAt()以索引编号为参数,返回这个位置的字符
indexOf()在字符串中查找一个或一组字符,返回首次出现的索引编号
lastIndexOf()在字符串中查找一个或一组字符,返回最后一次出现的索引编号
subString()返回两个索引编号之间的字符,包含首索引编号位置的字符,不包含第二个
split()当指定一个字符时,它用查找到的每个此字符将字符串分割,然后存储在一个数组中
trim()删除字符串开始和结束的空格
replace()替换第一个查找到的值

4.5. 全局对象:数字对象

  1. 当拥有一个数字时,可以对其使用 Number 对象的属性和方法。
方法描述
isNaN()检查值是否为数字
toFixed()将特定数字四舍五入至指定小数位数
toPrecision()按数字的位数四舍五入
toExponential()以字符串的形式返回指数计数法表示的数字

4.6. 全局对象:Math 对象

  1. Math 对象有用于数学常量和函数的属性和方法。
属性描述
Math.PI返回 pi(3.1415….)
方法描述
Math.round()将数字四舍五入到离他最近的整数
Math.sqrt(n)返回平方根
Math.ceil()将数字舍入到离他最近且大于它的整数
Math.floor()将数字舍入到离他最近且小于它的整数
Math.random()获取一个从 [0,1) 的随机数

4.7. 全局对象: Date 对象

  1. 可以使用如下方式创建 Date 对象的一个实例,默认情况下,创建 Date 对象时,存储当前日期,如果想要存储其他日期,需要显示指定想要保存的日期和时间。
1
2
var today = new Date();
var newDate = new Date(2022, 11, 11);
  1. Date 对象提供了如下方法允许你设置和返回它代表的时间和日期:
方法描述
getDate()/setDate()返回/设置月份中的日期
getDay()返回星期几(0-6)
getFullYear()/setFullYear()返回/设置年份
getHours()/setHours()返回/设置小时
getMilliseconds()/setMilliseconds()返回/设置毫秒数
getMinutes()/setMinutes()返回/设置分钟
getMonth()/setMonth()返回/设置月份
getSeconds()/setSeconds()返回/设置秒
getTime()/setTime()返回/设置从 1970-01-01 00:00:00 开始计算的毫秒数
getTimezoneOffset()按分钟为本地时间返回时区偏差值
toDateString()返回适合人类阅读的日期
toTimeString()返回适合人类阅读的时间
toString()返回表示特定日期的字符串
  1. 访问者的位置可能会影响时区和语言,程序员使用 locale 代表这类基于位置的信息。