Tian Jiale's Blog

JavaScript 笔记

JavaScript 负责页面中的的行为。

它是一门运行在浏览器端的脚本语言。

基础内容

JS 的编写的位置

1.可以编写到标签的指定属性中

<button onclick="alert('hello');">我是按钮</button> <a href="javascript:alert('aaa');">超链接</a>

2.可以编写到 script 标签中

<script type="text/javascript">
  //编写js代码
</script>

3.可以将代码编写到外部的 js 文件中,然后通过标签将其引入

script 标签一旦用于引入外部文件了,就不能在编写代码了,即使编写了浏览器也会忽略 ,如果需要则可以在创建一个新的 script 标签用于编写内部代码

<script type="text/javascript" src="文件路径"></script>

输出语句

alert('要输出的内容');

该语句会在浏览器窗口中弹出一个警告框

document.write('要输出的内容');

该内容将会被写到 body 标签中,并在页面中显示

console.log('要输出的内容');

该内容会被写到开发者工具的控制台中

基本的语法

js 函数声明不需要;分号,但是赋值语句要加;分号

function functionName(arg0, arg1, arg2) {
  //函数声明
}
var functionName = function (arg0, arg1, arg2) {
  //函数表达式
};
注意分号;

注释

单行注释

//注释内容

多行注释

/*
注释内容
*/

JS 严格区分大小写

JS 中每条语句以分号(;)结尾如果不写分号,浏览器会自动添加,但是会消耗一些系统资源, 而且有些时候,浏览器会加错分号,所以在开发中分号必须写

JS 中会自动忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化。

字面量和变量

字面量:

字面量实际上就是一些固定的值,比如 1 2 3 4 true false null NaN “hello”,字面量都是不可以改变的。

由于字面量不是很方便使用,所以在 JS 中很少直接使用字面量

变量:

变量可以用来保存字面量,并且可以保存任意的字面量

一般都是通过变量来使用字面量,而不直接使用字面量,而且也可以通过变量来对字面量进行一个描述

声明变量

使用 var 关键字来声明一个变量

var a;

为变量赋值

a = 1;

声明和赋值同时进行

var a = 456;

标识符

在 JS 中所有的可以自主命名的内容,都可以认为是一个标识符,是标识符就应该遵守标识符的规范。

比如:变量名、函数名、属性名

规范:

  1. 标识符中可以含有字母、数字、_、$
  2. 标识符不能以数字开头
  3. 标识符不能是 JS 中的关键字和保留字
  4. 标识符一般采用驼峰命名法:xxxYyyZzz

数据类型

String 字符串

JS 中的字符串需要使用引号引起来双引号或单引号都行

在字符串中使用\作为转义字符

\'  ==> '
\"  ==> "
\n  ==> 换行
\t  ==> 制表符
\\  ==> \

使用 typeof 运算符检查字符串时,会返回"string"

Number 数值

JS 中所有的整数和浮点数都是 Number 类型

最大能表示的值:Number.MAX_VALUE=1.7976931348623157e+308

特殊的数字:能赋值给变量

  • Infinity 正无穷 a = Infinity ,能赋值

  • Infinity 负无穷

  • NaN 非法数字(Not A Number)

其他进制的数字的表示:

  • 0b 开头表示二进制,但是不是所有的浏览器都支持

  • 0 开头表示八进制

  • 0x 开头表示十六进制

使用 typeof 检查一个 Number 类型的数据时,会返回"number"(包括 NaN 和 Infinity)

Boolean 布尔值

布尔值主要用来进行逻辑判断,布尔值只有两个

  • true 逻辑的真

  • false 逻辑的假

使用 typeof 检查一个布尔值时,会返回"boolean"

Null 空值

空值专门用来表示为空的对象,Null 类型的值只有一个 null

使用 typeof 检查一个 Null 类型的值时会返回"object"

Undefined 未定义

如果声明一个变量但是没有为变量赋值此时变量的值就是 undefined

该类型的值只有一个 undefined

使用 typeof 检查一个 Undefined 类型的值时,会返回"undefined"

引用数据类型

Object 对象

类型转换

类型转换就是指将其他的数据类型,转换为 String Number 或 Boolean

转换为 String

toString()方法

强制类型转换

var a = 123;
a = a.toString();
// 注意:这个方法不适用于null和undefined
// 由于这两个类型的数据中没有方法,所以调用toString()时会报错

String()函数

强制类型转换

var a = 123;
a = String(a);
// 对于Number Boolean String都会调用他们的toString()方法来将其转换为字符串,对于null值,直接转换为字符串"null"。对于undefined直接转换为字符串"undefined"

为任意的数据类型 + ""

隐式类型转换

var a = true;
a = a + '';

原理:和 String()函数一样

转换为 Number

Number()函数

强制类型转换

var s = '123';
s = Number(s);

转换的情况

  1. 字符串 > 数字

    如果字符串是一个合法的数字,则直接转换为对应的数字

    如果字符串是一个非法的数字,则转换为 NaN

    如果是一个空串或纯空格的字符串,则转换为 0

  2. 布尔值 > 数字

    true 转换为 1

    false 转换为 0

  3. 空值 > 数字

    null 转换为 0

  4. 未定义 > 数字

    undefined 转换为 NaN

parseInt()或 parseFloat()

强制类型转换

如果对非 String 使用 parseInt()或 parseFloat(),它会先将其转换为 String然后在操作

var a = '123.456px';
a = parseInt(a); //123

var b = '123.456px';
b = parseFloat(b); //123.456

使用一元的+

隐式类型转换

var a = '123';
a = +a;

原理:和 Number()函数一样

转换为布尔值

Boolean()函数

强制类型转换

var s = 'false';
s = Boolean(s); //true

转换情况

  1. 字符串 > 布尔

    除了空串其余全是 true

  2. 数值 > 布尔

    除了 0 和 NaN 其余的全是 true

  3. null、undefined > 布尔

    都是 false

  4. 对象 > 布尔

    都是 true

两次非运算

隐式类型转换

var a = 'hello';
a = !!a; //true

基础语法

运算符

运算符也称为操作符

通过运算符可以对一个或多个值进行运算或操作

typeof 运算符

用来检查一个变量的数据类型

语法:typeof 变量

它会返回一个用于描述类型的字符串作为结果

算数运算符

+ 对两个值进行加法运算并返回结果

- 对两个值进行减法运算并返回结果

* 对两个值进行乘法运算并返回结果

/ 对两个值进行除法运算并返回结果

% 对两个值进行取余运算并返回结果

除了加法以外,对非 Number 类型的值进行运算时,都会先转换为 Number 然后在做运算。

而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。

任何值和字符串做加法,都会先转换为字符串,然后再拼串

一元运算符

一元的+

就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字

var a = true;
a = +a;

一元的-

就是负号,可以对一个数字进行符号位取反

var a = 10;
a = -a;

自增

自增可以使变量在原值的基础上自增1

自增使用 ++

自增可以使用 前++(++a)后++(a++)

无论是++a 还是 a++都会立即使原变量自增1

不同的是++a和a++的值是不同的
    ++a的值是变量的新值(自增后的值)
    a++的值是变量的原值(自增前的值)

自减

自减可以使变量在原值的基础上自减1

自减使用 --

自减可以使用 前(--a)后(a--)

无论是a 还是 a都会立即使原变量自减1

不同的是--a和a++的值是不同的
    --a的值是变量的新值(自减后的值)
    a++的值是变量的原值(自减前的值)

逻辑运算符

!

非运算可以对一个布尔值进行取反,true变false false边true
当对非布尔值使用!时,会先将其转换为布尔值然后再取反
我们可以利用!来将其他的数据类型转换为布尔值

&&

&&可以对符号两侧的值进行与运算
只有两端的值都为true时,才会返回true。只要有一个false就会返回false。
与是一个短路的与,如果第一个值是false,则不再检查第二个值
对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
规则:
    1.如果第一个值为false,则返回第一个值
    2.如果第一个值为true,则返回第二个值

||

||可以对符号两侧的值进行或运算
只有两端都是false时,才会返回false。只要有一个true,就会返回true。
或是一个短路的或,如果第一个值是true,则不再检查第二个值
对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
规则:
    1.如果第一个值为true,则返回第一个值
    2.如果第一个值为false,则返回第二个值

赋值运算符

=

可以将符号右侧的值赋值给左侧变量

+=

a += 5; // 相当于 a = a+5
var str = 'hello';
str += 'world';

-=

a -= 5; // 相当于 a = a-5

*=

a *= 5; // 相当于 a = a*5

/=

a /= 5; // 相当于 a = a/5

%=

a %= 5; // 相当于 a = a%5

关系运算符

关系运算符用来比较两个值之间的大小关系的

>、>=、<、<=

关系运算符的规则和数学中一致,用来比较两个值之间的关系

  • 如果关系成立则返回 true,关系不成立则返回 false。

  • 如果比较的两个值是非数值,会将其转换为 Number 然后再比较。

  • 如果比较的两个值都是字符串,此时会比较字符串的 Unicode 编码,而不会转换为 Number。

相等运算符

相等,判断左右两个值是否相等,如果相等返回 true,如果不等返回 false

相等会自动对两个值进行类型转换,如果对不同的类型进行比较,会将其转换为相同的类型然后再比较,转换后相等它也会返回 true,null == undifined

!=

不等,判断左右两个值是否不等,如果不等则返回 true,如果相等则返回 false,不等也会做自动的类型转换。

===

全等,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换,如果两个值的类型不同,则直接返回 false

!==

不全等,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回 true

特殊的值:

  1. null 和 undefined 由于 undefined 衍生自 null,所以null == undefined 会返回 true,但是 null === undefined 会返回 false。

  2. NaN

    NaN 不与任何值相等,包括它自身 NaN == NaN //false

    判断一个值是否是 NaN 使用 isNaN()函数

三元运算符

?: 语法:条件表达式?语句 1:语句 2;

执行流程:

  • 先对条件表达式求值判断

    • 如果判断结果为 true,则执行语句 1,并返回执行结果
    • 果判断结果为 false,则执行语句 2,并返回执行结果

优先级:

和数学中一样,JS 中的运算符也是具有优先级的,比如 先乘除 后加减 先与 后或

具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,优先级越高的越优先计算,优先级相同的,从左往右计算。优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。

流程控制语句

程序都是自上向下的顺序执行的,通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序。

条件判断和分支语句

if 判断语句

语法一

if(条件表达式){
  语句...
}

执行流程:

  • if 语句执行时,会先对条件表达式进行求值判断

  • 如果值为 true,则执行 if 后的语句

  • 如果值为 false,则不执行

语法二

if(条件表达式){
  语句...
}else{
  语句...
}

执行流程:

  • if…else 语句执行时,会对条件表达式进行求值判断

  • 如果值为 true,则执行 if 后的语句

  • 如果值为 false,则执行 else 后的语句

语法三

if(条件表达式){
  语句...
}else if(条件表达式){
  语句...
}else if(条件表达式){
  语句...
}else if(条件表达式){
  语句...
}else{
  语句...
}

执行流程

  • if…else if…else 语句执行时,会自上至下依次对条件表达式进行求值判断,

  • 如果判断结果为 true,则执行当前 if 后的语句,执行完成后语句结束。

  • 如果判断结果为 false,则继续向下判断,直到找到为 true 的为止。

  • 如果所有的条件表达式都是 false,则执行 else 后的语句

条件分支语句

switch 语句

switch(条件表达式){
  case 表达式:
  语句...
  break;
  case 表达式:
  语句...
  break;
  case 表达式:
  语句...
  break;
  default:
  语句...
  break;
}

执行流程:

switch…case…语句在执行时,会依次将 case 后的表达式的值和 switch 后的表达式的值进行全等比较,

如果比较结果为 false,则继续向下比较。如果比较结果为 true,则从当前 case 处开始向下执行代码。

如果所有的 case 判断结果都为 false,则从 default 处开始执行代码。

循环语句

通过循环语句可以反复执行某些语句多次

while 循环:

while(条件表达式){
    语句...
}

执行流程: while 语句在执行时,会先对条件表达式进行求值判断, 如果判断结果为 false,则终止循环 如果判断结果为 true,则执行循环体 循环体执行完毕,继续对条件表达式进行求值判断,依此类推

do…while 循环:

do{
语句...
}while(条件表达式)

执行流程

  • do…while 在执行时,会先执行 do 后的循环体,然后在对条件表达式进行判断,

  • 如果判断判断结果为 false,则终止循环。

  • 如果判断结果为 true,则继续执行循环体,依此类推

和 while 的区别:

  • while:先判断后执行

  • do…while: 先执行后判断

  • do…while 可以确保循环体至少执行一次。

for 循环:

语法:

for(①初始化表达式 ; ②条件表达式 ; ④更新表达式){
    ③语句...
}

执行流程:

  • 首先执行 ① 初始化表达式,初始化一个变量,

  • 然后对 ② 条件表达式进行求值判断,如果为 false 则终止循环

  • 如果判断结果为 true,则执行 ③ 循环体

  • 循环体执行完毕,执行 ④ 更新表达式,对变量进行更新。

  • 更新表达式执行完毕重复 ②

死循环:

while (true) {}

for (;;) {}

对象(Object)

对象是 JS 中的引用数据类型

对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性

使用 typeof 检查一个对象时,会返回 object

对象的分类

1.内建对象

由 ES 标准中定义的对象,在任何的 ES 的实现中都可以使用

比如:Math String Number Boolean Function Object….

2.宿主对象

由 JS 的运行环境提供的对象,目前来讲主要指由浏览器提供的对象

比如 BOM DOM

3.自定义对象

由开发人员自己创建的对象

创建对象

方式一

var obj = new Object();

方式二

var obj = {};

对象的属性

  1. 向对象中添加属性

    对象.属性名 = 属性值;
    对象['属性名'] = 属性值; //这种方式能够使用特殊的属性名
    

    对象的属性名没有任何要求,不需要遵守标识符的规范,但是在开发中,尽量按照标识符的要求去写。

    属性值也可以任意的数据类型。

  2. 读取对象中的属性

    对象.属性名;
    对象['属性名']; //"属性名"可以使字符串常量,也可以是字符串变量
    

    如果读取一个对象中没有的属性,它不会报错,而是返回一个 undefined

  3. 删除对象中的属性

    delete 对象.属性名;
    delete 对象['属性名'];
    

遍历

使用 in 检查对象中是否含有指定属性

语法:“属性名” in 对象

如果在对象中含有该属性,则返回 true,如果没有则返回 false

循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)

var obj = { 0: 'a', 1: 'b', 2: 'c' };

for (var i in obj) {
  console.log(i, ':', obj[i]);
}

使用对象字面量,在创建对象时直接向对象中添加属性

var obj = {
  属性名: 属性值,
  属性名: 属性值,
  属性名: 属性值,
  属性名: 属性值,
};

基本数据类型和引用数据类型

  1. 基本数据类型

    String Number Boolean Null Undefined

  2. 引用数据类型

    Object

基本数据类型的数据,变量是直接保存的它的值。

变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。

引用数据类型的数据,变量是保存的对象的引用(内存地址)。

如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。 比较两个变量时,对于基本数据类型,比较的就是值,对于引用数据类型比较的是地址,地址相同才相同

函数(Function)

函数也是一个对象,也具有普通对象的功能(能有属性)

函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码

使用 typeof 检查一个函数时会返回 function

创建函数

// 函数声明
function 函数名([形参1,形参2...形参N]){
语句...
}
// 函数表达式
var 函数名 = function([形参1,形参2...形参N]){
语句...
};

调用函数

语法:函数对象([实参 1,实参 2…实参 N]);

fun() sum() alert() Number() parseInt()

当我们调用函数时,函数中封装的代码会按照编写的顺序执行

立即执行函数

函数定义完,立即被调用,这种函数叫做立即执行函数

立即执行函数往往只会执行一次

(function (a, b) {
  console.log('a = ' + a);
  console.log('b = ' + b);
})(123, 456);

形参和实参

形参:形式参数

定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开,定义形参就相当于在函数内声明了对应的变量但是并不赋值,形参会在调用时才赋值。

实参:实际参数

调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,调用函数时 JS 解析器不会检查实参的类型和个数,可以传递任意数据类型的值。如果实参的数量大于形参,多余实参将不会赋值,如果实参的数量小于形参,则没有对应实参的形参将会赋值 undefined

返回值

使用 return 来设置函数的返回值。

语法:return 值;

该值就会成为函数的返回值,可以通过一个变量来接收返回值。如果 return 后不跟值,或者是不写 return 则函数默认返回 undefined。

break、continue 和 return

break,退出循环

continue,跳过当次循环

return,退出函数

方法(method)

可以将一个函数设置为一个对象的属性,当一个对象的属性是一个函数时,我们称这个函数是该对象的方法。

对象.方法名();

函数名()

函数的属性和方法

call()、apply()

这两个方法都是函数对象的方法需要通过函数对象来调用

通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中 this,不同的是 call 是直接传递函数的实参而 apply 需要将实参封装到一个数组中传递

arguments

arguments 和 this 类似,都是函数中的隐含的参数

arguments 是一个类数组元素,它用来封装函数执行过程中的实参,所以即使不定义形参,也可以通过 arguments 来使用实参,arguments 中有一个属性 callee 表示当前执行的函数对象

this

this 是函数的上下文对象,根据函数的调用方式不同会执向不同的对象

  1. 以函数的形式调用时,this 是 window
  2. 以方法的形式调用时,this 是调用方法的对象
  3. 以构造函数的形式调用时,this 是新建的那个对象
  4. 使用 call 和 apply 调用时,this 是指定的那个对象
  5. 在全局作用域中 this 代表 window

作用域

作用域简单来说就是一个变量的作用范围。

全局作用域

直接在 script 标签中编写的代码都运行在全局作用域中

全局作用域在打开页面时创建,在页面关闭时销毁。

全局作用域中有一个全局对象 window,window 对象由浏览器提供,可以在页面中直接使用,它代表的是整个的浏览器的窗口。在全局作用域中创建的变量都会作为 window 对象的属性保存,在全局作用域中创建的函数都会作为 window 对象的方法保存,在全局作用域中创建的变量和函数可以在页面的任意位置访问。在函数作用域中也可以访问到全局作用域的变量。尽量不要在全局中创建变量。

函数作用域

函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。

函数作用域在函数执行时创建,在函数执行结束时销毁。

在函数作用域中创建的变量,不能在全局中访问。当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,如果找到了则使用,找不到则继续向上找

变量的声明提前

在全局作用域中,使用**var 关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。**所以我们可以在变量声明前使用变量。但是不使用 var 关键字声明的变量不会被声明提前。

在函数作用域中,也具有该特性,使用 var 关键字声明的变量会在函数所有的代码执行前被声明,如果没有使用 var 关键字声明变量,则变量会变成全局变量

函数的声明提前

在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建,也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性。

this(上下文对象)

我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。

使用 this 来引用上下文对象,根据函数的调用形式不同,this 的值也不同。

一般指向当前对象。

this 的不同的情况:

  • 以函数的形式调用时,this 是 window

  • 以方法的形式调用时,this 就是调用方法的对象

  • 以构造函数的形式调用时,this 就是新创建的对象

构造函数

构造函数是专门用来创建对象的函数,一个构造函数我们也可以称为一个类

通过一个构造函数创建的对象,我们称该对象是这个构造函数的实例;通过同一个构造函数创建的对象,我们称为一类对象。

构造函数就是一个普通的函数,只是他的调用方式不同,如果直接调用,它就是一个普通函数,如果使用 new 来调用,则它就是一个构造函数。

例子:

function Person(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
  this.sayName = function () {
    alert(this.name);
  };
  return this;
}

构造函数的执行流程:

  1. 创建一个新的对象

  2. 将新的对象作为函数的上下文对象(this)

  3. 执行函数中的代码

  4. 将新建的对象返回

instanceof 用来检查一个对象是否是一个类的实例

语法:对象 instanceof 构造函数

如果该对象时构造函数的实例,则返回 true,否则返回 false

Object 是所有对象的祖先,所以任何对象和 Object 做 instanceof 都会返回 true

原型(prototype)

创建一个函数以后,解析器都会默认在函数中添加一个数 prototype,prototype 属性指向的是一个对象,这个对象我们称为原型对象。

当函数作为构造函数使用,**它所创建的对象中都会有一个隐含的属性就是该原型对象。**这个隐含的属性可以通过对象.__proto__来访问。

原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。

我们可以将对象中共有的属性和方法统一添加到原型对象中,这样我们只需要添加一次,就可以使所有的对象都可以使用。

当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,如果在自身中找到了,则直接使用。如果没有找到,则去原型对象中寻找,如果找到了则使用,**如果没有找到,则去原型的原型中寻找,**依此类推。直到找到 Object 的原型为止,Object 的原型的原型为 null,如果依然没有找到则返回 undefined

方法 hasOwnProperty()

这个方法可以用来检查对象自身中是否含有某个属性

语法:对象.hasOwnProperty(“属性名”)

toString 方法

当我们直接在页面中打印一个对象时,事件上是输出的对象的 toString()方法的返回值

如果我们希望在输出对象时不输出[object Object],可以为对象添加一个 toString()方法

//修改Person原型的toString
Person.prototype.toString = function () {
  return 'Person[name=' + this.name + ',age=' + this.age + ',gender=' + this.gender + ']';
};

垃圾回收(GC)

就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾,这些垃圾积攒过多以后,会导致程序运行的速度过慢,所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾。

当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象, 此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,所以这种垃圾必须进行清理。

在 JS 中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作,我们需要做的只是要将不再使用的对象设置 null 即可。

数组(Array)

数组也是一个对象,是一个用来存储数据的对象和 Object 类似,但是它的存储效率比普通对象要高;数组中保存的内容我们称为元素;数组使用索引(index)来操作元素;索引指由 0 开始的整数。

数组的操作

创建数组

var arr = new Array();
var arr = [];

向数组中添加元素

arr[0] = 123;
arr[1] = 'hello';

创建数组时直接添加元素

 var arr = [元素1,元素2....元素N];

获取和修改数组的长度 使用 length 属性来操作数组的长度

获取长度
数组.length
    length获取到的是数组的最大索引+1
    对于连续的数组,length获取到的就是数组中元素的个数

修改数组的长度
数组.length = 新长度
     如果修改后的length大于原长度,则多出的部分会空出来
     如果修改后的length小于原长度,则原数组中多出的元素会被删除

向数组的最后添加元素
数组[数组.length] = 值;

数组的方法

方法名
push() 用来向数组的末尾添加一个或多个元素,并返回数组新的长度
pop() 用来删除数组的最后一个元素,并返回被删除的元素
unshift() 向数组的开头添加一个或多个元素,并返回数组的新的长度
shift() 删除数组的开头的一个元素,并返回被删除的元素
reverse() 可以用来反转一个数组,它会对原数组产生影响
concat() 可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回

slice(sart,[end])

可以从一个数组中截取指定的元素,该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回。

参数:

  1. 截取开始位置的索引(包括开始位置)

  2. 截取结束位置的索引(不包括结束位置)

    第二个参数可以省略不写,如果不写则一直截取到最后

    参数可以传递一个负值,如果是负值,则从后往前数

splice()

可以用来删除数组中指定元素,并使用新的元素替换,该方法会将删除的元素封装到新数组中返回

参数:

  1. 删除开始位置的索引

  2. 删除的个数

  3. 三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边

join([splitor])

可以将一个数组转换为一个字符串

参数:

需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素,如果不指定连接符则默认使用

sort()

可以对一个数组中的内容进行排序,默认是按照 Unicode 编码进行排序,调用以后,会直接修改原数组。

我们可以在 sort()添加一个回调函数,来指定排序规则,回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数,使用哪个元素调用不确定,但是肯定的是在数组中 a 一定在 b 前边

  • 浏览器会根据回调函数的返回值来决定元素的顺序, 如果返回一个大于 0 的值,则元素会交换位置 如果返回一个小于 0 的值,则元素位置不变 如果返回一个 0,则认为两个元素相等,也不交换位置

  • 如果需要升序排列,则返回 a-b 如果需要降序排列,则返回 b-a

function(a,b){
  //升序排列
  //return a-b;

  //降序排列
  return b-a;
}

遍历数组

遍历数组就是将数组中元素都获取到

一般情况我们都是使用 for 循环来遍历数组

for (var i = 0; i < 数组.length; i++) {
  //数组[i]
}

使用 forEach()方法来遍历数组(不兼容 IE8)

数组.forEach(function (value, index, obj) {});
// value:正在遍历的元素
// index:正在遍历元素的索引
// obj:被遍历对象

forEach()方法需要一个回调函数作为参数,数组中有几个元素,回调函数就会被调用几次,每次调用时,都会将遍历到的信息以实参的形式传递进来,我们可以定义形参来获取这些信息。

常用类和方法

包装类

在 JS 中为我们提供了三个包装类:

String() Boolean() Number()

通过这三个包装类可以创建基本数据类型的对象

var num = new Number(2);
var str = new String('hello');
var bool = new Boolean(true);

但是在实际应用中千万不要这么干。

当我们去操作一个基本数据类型的属性和方法时,解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,

操作完成以后再将这个临时对象进行销毁。

Date

日期的对象,在 JS 中通过 Date 对象来表示一个时间

创建对象

// 创建一个当前的时间对象
var d = new Date();
// 创建一个指定的时间对象
var d = new Date('月/日/年 时:分:秒');

方法

方法名
getDate() 当前日期对象是几日(1-31)
getDay() 返回当前日期对象时周几(0-6)
getMonth() 返回当前日期对象的月份(0-11)
getFullYear() 从 Date 对象以四位数字返回年份。
getHours() 返回 Date 对象的小时 (0 ~ 23)。
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
getTime() 返回当前日期对象的时间戳
Date.now() 可以获取当前代码执行时的时间戳

Math

Math 属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法,我们可以直接使用它来进行数学运算相关的操作。 方法:

方法名
Math.PI 常量,圆周率
Math.abs() 绝对值运算
Math.ceil() 向上取整
Math.floor() 向下取整
Math.round() 四舍五入取整
Math.random() 生成一个 01 之间的随机数
Math.pow(x,y) 求 x 的 y 次幂
Math.sqrt() 对一个数进行开方
Math.max() 求多个数中最大值
Math.min() 求多个数中的最小值

字符串的相关的方法

方法名
String.prototype.padStart(maxLength, fillString=’') 填充字符串
String.prototype.padEnd(maxLength, fillString=’') 填充字符串
length 获取字符串的长度
charAt() 根据索引获取指定的字符
charCodeAt() 根据索引获取指定的字符编码
String.fromCharCode() 根据字符编码获取字符
indexOf() 从一个字符串中检索指定内容 第一个字符串参数,找到返回索引,否则-1,第二个参数开始位置
lastIndexOf() indexOf()的逆序版
slice(start,[end]) 从一个字符串中截取指定的内容并返回,不影响原变量
substr() 和 slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量
substring() 和 slice()基本一致,不同的是它不接受负值作参数,负值会修正为 0,substring()中第二个参数小于第一个,自动调整位置
toLowerCase() 将字符串转换为小写并返回
toUpperCase() 将字符串转换为大写并返回
split() 可以根据指定内容将一个字符串拆分为一个数组,可以接收一个字符串或正则表达式
match() 可以根据字符串正则表达式,从一个字符串中将符合条件的内容提取出来
replace() 可以将字符串中指定内容替换为新的内容
search() 可以搜索字符串中是否含有指定内容

正则表达式

正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,也可以将一个字符串中符合规则的内容提取出来。

创建正则表达式:

var reg = new RegExp('正则', '匹配模式');
// 注意:使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,如果要使用\则需要使用\\来代替

var reg = /正则表达式/;
// 匹配模式 (匹配模式可以多个一起写:/gi)

语法

匹配模式:

i:忽略大小写(ignore)

g:全局匹配模式(默认为 1 次)

设置匹配模式时,可以都不设置,也可以设置 1 个,也可以全设置,设置时没有顺序要求

其他

方法

test()

可以用来检查一个字符串是否符合正则表达式

如果符合返回 true,否则返回 false

例子:

去掉两端的空格:

var s = '            f    afa    ';
s = s.replace(/^\s*|\s*$/g, '');

DOM

Document Object Model

文档对象模型,通过 DOM 可以来任意来修改网页中各个内容

文档:文档指的是网页,一个网页就是一个文档

对象:对象指将网页中的每一个节点都转换为对象

模型:模型用来表示节点和节点之间的关系,方便操作页面

节点(Node):节点是构成网页的最基本的单元,网页中的每一个部分都可以称为是一个节点

节点类型:

文档节点 (Document):代表整个网页 ​ 元素节点(Element):代表网页中的标签 ​ 属性节点(Attribute):代表标签中的属性 ​ 文本节点(Text):代表网页中的文本内容

DOM 操作

DOM 查询

在网页中浏览器已经为我们提供了document 对象,它代表的是整个网页,它是 window 对象的属性,可以在页面中直接使用。

document 查询方法

// 根据元素的id属性查询一个元素节点对象:
document.getElementById('id属性值');
// 根据元素的name属性值查询一组元素节点对象:
document.getElementsByName('name属性值');
// 根据标签名来查询一组元素节点对象:
document.getElementsByTagName('标签名');

元素的属性 读取元素的属性:

语法元素.属性名
ele.name
ele.id
ele.value
ele.className

修改元素的属性:

语法元素.属性名 = 属性值

innerHTML:

使用该属性可以获取或设置元素内部的 HTML 代码

文档的加载:

浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。如果将 js 代码编写到页面的上边,当代码执行时,页面中的 DOM 对象还没有加载,此时将会无法正常获取到 DOM 对象,导致 DOM 操作失败。

解决方式一:

可以将 js 代码编写到 body 的下边

<body>
  <button id='btn'>按钮</button>

  <script>var btn = document.getElementById("btn"); btn.onclick = function(){};</script>
</body>

解决方式二:

将 js 代码编写到 window.onload = function(){}中;window.onload 对应的回调函数会在整个页面加载完毕以后才执行,所以可以确保代码执行时,DOM 对象已经加载完毕了。

<script>
    window.onload = function(){
        var btn = document.getElementById("btn");
        btn.onclick = function(){
        };
    };
</script>

DOM 查询 API:

name
元素.childNodes 获取当前元素的所有子节点会获取到空白的文本子节点
元素.children 获取当前元素的所有子元素
元素.firstChild 获取当前元素的第一个子节点,会获取到空白的文本子节点
元素.lastChild 获取当前元素的最后一个子节点
元素.parentNode 获取当前元素的父元素
元素.previousSibling 获取当前元素的前一个兄弟节点
元素.previousElementSibling 获取前一个兄弟元素,IE8 及以下不支持
元素.nextSibling 获取当前元素的后一个兄弟节点
元素.firstElementChild 获取当前元素的第一个子元素,不支持 IE8 及以下的浏览器
元素.innerHTML 获取到标签内部的内容。包含 HTML 标签
元素.innerText 获取到标签内部的内容。不包含 HTML 标签
元素.firstChild.nodeValue 读取标签内部的文本内容
document.all 获取页面中的所有元素
document.documentElement 获取页面中 html 根元素
document.body 获取页面中的 body 元素
document.getElementsByClassName() 根据元素的 class 属性值查询一组元素节点对象
document.querySelector() 根据 CSS 选择器去页面中查询一个元素,返回查询到的第一个元素
document.querySelectorAll() 根据 CSS 选择器去页面中查询一组元素,以数组方式返回

DOM 修改

name
document.createElement(“TagName”) 可以用于创建一个元素节点对象,它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回
document.createTextNode(“textContent”) 可以根据文本内容创建一个文本节点对象
父节点.appendChild(子节点) 向父节点中添加指定的子节点
父节点.insertBefore(新节点,旧节点) 将一个新的节点插入到旧节点的前边
父节点.replaceChild(新节点,旧节点) 使用一个新的节点去替换旧节点
父节点.removeChild(子节点) 删除指定的子节点,推荐方式:子节点.parentNode.removeChild(子节点)

DOM 对 CSS 的操作

读取和修改内联样式

使用 style 属性来操作元素的内联样式

读取内联样式:

// 语法
元素.style.样式名;
// 例子
元素.style.width;
元素.style.height;
/*
 *注意:如果样式名中带有-,则需要将样式名修改为驼峰命名法将-去掉,然后后的字母改大写
 *比如:background-color > backgroundColor
 *border-width > borderWidth
 */

修改内联样式:

// 语法:
元素.style.样式名 = 样式值;
/*
 *通过style修改和读取的样式都是内联样式,由于内联样式的优先级比较高,所以我们通过JS来修改*的样式,往往会立即生效,但是如果样式中设置了!important,则内联样式将不会生效。
 */

读取元素的当前样式

正常浏览器

getComputedStyle();
/*
这个方法是window对象的方法,可以返回一个对象,这个对象中保存着当前元素生效样式

参数:
  1.要获取样式的元素
  2.可以传递一个伪元素,一般传null
*例子:
*    获取元素的宽度
*    getComputedStyle(box , null)["width"];
* 
*通过该方法读取到样式都是只读的不能修改
*/

IE8

元素.currentStyle;
/*
 *例子:
 *box.currentStyle["width"]
 *
 *通过这个属性读取到的样式是只读的不能修改
 */

实现兼容性:

function getStyle(obj, name) {
  //对象.属性不存在,不会报错,如果直接寻找对象,(当前作用域到全局作用域)找不到会报错
  if (window.getComputedStyle) {
    //正常浏览器的方式,具有getComputedStyle()方法
    return getComputedStyle(obj, null)[name];
  } else {
    //IE8的方式,没有getComputedStyle()方法
    return obj.currentStyle[name];
  }
}

其他的样式相关的属性

注意:以下样式都是只读的,未指明偏移量都是相对于当前窗口左上角

name
clientHeight 元素的可见高度,包括元素的内容区和内边距的高度
clientWidth 元素的可见宽度,包括元素的内容区和内边距的宽度
offsetHeight 整个元素的高度,包括内容区、内边距、边框
offfsetWidth 整个元素的宽度,包括内容区、内边距、边框
offsetParent 当前元素的定位父元素
offsetLeft 当前元素和定位父元素之间的水平偏移量
offsetTop 当前元素和定位父元素之间的垂直偏移量
scrollHeight 获取元素滚动区域的高度
scrollWidth 获取元素滚动区域的宽度
scrollTop 获取元素垂直滚动条滚动的距离
scrollLeft 获取元素水平滚动条滚动的距离

判断滚动条是否滚动到底:

  1. 垂直滚动条

    scrollHeight -scrollTop = clientHeight

  2. 水平滚动

    scrollWidth -scrollLeft = clientWidth

事件

事件对象

当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向……

可以在响应函数中定义一个形参,来使用事件对象,但是在 IE8 以下浏览器中事件对象没有做为实参传递,而是作为 window 对象的属性保存

例子:

元素.事件 = function (event) {
  event = event || window.event;
};

元素.事件 = function (e) {
  e = e || event;
};

获取到鼠标的坐标:

  1. clientX 和 clientY

    用于获取鼠标在当前的可见窗口的坐标,div 的偏移量,是相对于整个页面的。

  2. pageX 和 pageY 可以获取鼠标相对于当前页面的坐标。

    但是这个两个属性在 IE8 中不支持,所以如果需要兼容 IE8,则不要使用

事件的冒泡(Bubble)

事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。

事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消,可以将事件对象的 cancelBubble 设置为 true,即可取消冒泡

元素.事件 = function (event) {
  event = event || window.event;
  event.cancelBubble = true;
};

事件的委派

指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。

事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能。

我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的,我们可以尝试将其绑定给元素的共同的祖先元素。

target : event 中的 target 表示的触发事件的对象。

事件的绑定

addEventListener()

通过这个方法也可以为元素绑定响应函数

参数:

  1. 事件的字符串,不要 on

  2. 回调函数,当事件触发时该函数会被调用

  3. 是否在捕获阶段触发事件,需要一个布尔值,一般都传 false

使用 addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行。

这个方法不支持 IE8 及以下的浏览器。

attachEvent()

在 IE8 中可以使用 attachEvent()来绑定事件

参数:

  1. 事件的字符串,要 on

  2. 回调函数

这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和 addEventListener()相反。

实现兼容性

function bind(obj , eventStr , callback){
    if(obj.addEventListener){
        //大部分浏览器兼容的方式
        obj.addEventListener(eventStr , function(){
            //在匿名函数中调用回调函数
            callback.call(obj);
        }), false);
    }else{
        //IE8及以下
        obj.attachEvent("on"+eventStr , function(){
            //在匿名函数中调用回调函数
            callback.call(obj);
        });
    }
}

事件的传播

事件传播分为三个阶段

  • 捕获阶段

    在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件

  • 目标阶段

    事件捕获到目标元素,捕获结束开始在目标元素上触发事件

  • 冒泡阶段

    事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件

如果希望在捕获阶段就触发事件,可以将 addEventListener()的第三个参数设置为 true,一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是 false。

IE8 及以下的浏览器中没有捕获阶段。

常用事件

鼠标事件

拖拽事件

function drag(obj) {
  //当鼠标在被拖拽元素上按下时,开始拖拽onmousedown
  obj.onmousedown = function (event) {
    //设置obj捕获所有鼠标按下的事件

    /*
     * setCapture()
     * - 只有IE支持,但是在火狐中调用时不会报错,
     * * 而如果使用chrome调用,会报错
     * */
    obj.setCapture && obj.setCapture();

    event = event || window.event;

    //obj的定位父元素相对于可视窗口左上角的水平偏移量 鼠标.clentX - 元素.offsetLeft
    //obj的定位父元素相对于可视窗口左上角的垂直偏移量 鼠标.clentY - 元素.offsetTop
    var ol = event.clientX - obj.offsetLeft;
    var ot = event.clientY - obj.offsetTop;

    //为document绑定一个onmousemove事件
    document.onmousemove = function (event) {
      event = event || window.event;
      //当鼠标移动时被拖拽元素跟随鼠标移动 onmousemove
      //获取鼠标的坐标
      var left = event.clientX - ol;
      var top = event.clientY - ot;
      //修改obj的位置
      obj.style.left = left + 'px';
      obj.style.top = top + 'px';
    };

    //为document绑定一个鼠标松开事件
    document.onmouseup = function () {
      //当鼠标松开时,被拖拽元素固定在当前位置 onmouseup
      //取消document的onmousemove事件
      document.onmousemove = null;
      //取消document的onmouseup事件
      document.onmouseup = null;
      //当鼠标松开时,取消对事件的捕获
      obj.releaseCapture && obj.releaseCapture();
    };
    /*
     * 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
     * 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
     *
     * 如果不希望发生这个行为,则可以通过return false来取消默认行为
     *
     * 但是这招对IE8不起作用
     */
    return false;
  };
}

滚轮事件

onwheel 都支持

//获取id为box1的div
var box1 = document.getElementById('box1');

//为box1绑定一个鼠标滚轮滚动的事件
/*
 * onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,
 *     但是火狐不支持该属性
 *
 * 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件
 * 注意该事件需要通过addEventListener()函数来绑定
 */

box1.onmousewheel = function (event) {
  event = event || window.event;

  //event.wheelDelta 可以获取鼠标滚轮滚动的方向
  //向上滚 120   向下滚 -120
  //wheelDelta这个值我们不看大小,只看正负

  //alert(event.wheelDelta);

  //wheelDelta这个属性火狐中不支持
  //在火狐中使用event.detail来获取滚动的方向
  //向上滚 -3  向下滚 3
  //alert(event.detail);

  /*
   * 当鼠标滚轮向下滚动时,box1变长
   *     当滚轮向上滚动时,box1变短
   */
  //判断鼠标滚轮滚动的方向
  if (event.wheelDelta > 0 || event.detail < 0) {
    //向上滚,box1变短
    box1.style.height = box1.clientHeight - 10 + 'px';
  } else {
    //向下滚,box1变长
    box1.style.height = box1.clientHeight + 10 + 'px';
  }

  /*
   * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
   * 需要使用event来取消默认行为event.preventDefault();
   * 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
   */
  event.preventDefault && event.preventDefault();

  /*
   * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,
   * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
   */
  return false;
};

//为火狐绑定滚轮事件
bind(box1, 'DOMMouseScroll', box1.onmousewheel);

function bind(obj, eventStr, callback) {
  if (obj.addEventListener) {
    //大部分浏览器兼容的方式
    obj.addEventListener(
      eventStr,
      function () {
        callback.call(obj);
      },
      false
    );
  } else {
    //IE8及以下
    obj.attachEvent('on' + eventStr, function () {
      callback.call(obj);
    });
  }
}

键盘事件

onkeydown

按键被按下,如果一直按着某个按键不松手,则事件会一直触发;当 onkeydown 连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快,这种设计是为了防止误操作的发生。

onkeyup

按键被松开

键盘事件一般都会绑定给一些可以获取到焦点的对象或者是 document。

keyCode

可以通过 keyCode 来获取按键的编码,通过它可以判断哪个按键被按下,除了 keyCode,事件对象中还提供了几个属性:

altKey、ctrlKey、shiftKey

这个三个用来判断 alt ctrl 和 shift 是否被按下,如果按下则返回 true,否则返回 false。

input.onkeydown = function (event) {
  event = event || window.event;
  //数字 48 - 57
  //使文本框中不能输入数字
  if (event.keyCode >= 48 && event.keyCode <= 57) {
    //在文本框中输入内容,属于onkeydown的默认行为
    //如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
    return false;
  }
};

BOM

浏览器对象模型(browser object model)

BOM 可以使我们通过 JS 来操作浏览器,在 BOM 中为我们提供了一组对象,用来完成对浏览器的操作 BOM 对象。这些 BOM 对象在浏览器中都是作为 window 对象的属性保存的,可以通过 window 对象来使用,也可以直接使用。

Window

代表的是整个浏览器的窗口,同时 window 也是网页中的全局对象。

Navigator

代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器。

Location

代表当前浏览器的地址栏信息,通过 Location 可以获取地址栏信息,或者操作浏览器跳转页面。

History

代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录。

由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页;而且该操作只在当次访问时有效。

Screen 代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息。

代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器,由于历史原因,Navigator 对象中的大部分属性都已经不能帮助我们识别浏览器了, 一般我们只会使用 userAgent 来判断浏览器的信息。

userAgent 是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的 userAgent。

在 IE11 中已经将微软和 IE 相关的标识都已经去除了,所以我们基本已经不能通过 UserAgent 来识别一个浏览器是否是 IE 了。

alert(navigator.appName);
var ua = navigator.userAgent;
console.log(ua);

History

history 对象可以用来操作浏览器向前或向后翻页。

length

可以获取到当前访问的链接数量

back()

可以用来回退到上一个页面,作用和浏览器的回退按钮一样

forward()

可以跳转下一个页面,作用和浏览器的前进按钮一样

go()

可以用来跳转到指定的页面

它需要一个整数作为参数 1:表示向前跳转一个页面 相当于 forward() 2:表示向前跳转两个页面 -1:表示向后跳转一个页面 -2:表示向后跳转两个页面

Location

该对象中封装了浏览器的地址栏的信息。

如果直接打印 location,则可以获取到地址栏的信息(当前页面的完整路径)

如果直接将 location 属性修改为一个完整的路径,或相对路径,则我们页面会自动跳转到该路径,并且会生成相应的历史记录

assign()

用来跳转到其他的页面,作用和直接修改 location 一样

reload()

用于重新加载当前页面,作用和刷新按钮一样

如果在方法中传递一个 true,作为参数,则会强制清空缓存刷新页面

replace()

可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用回退按钮回退

window

定时器

setInterval()

定时调用

可以将一个函数,每隔一段时间执行一次

参数:

  1. 回调函数

  2. 间隔的时间,单位是毫秒

返回值:返回一个 Number 类型的数据,这个数字用来作为定时器的唯一标识

clearInterval()可以用来关闭一个定时器

方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器

var num = 1;
var timer = setInterval(function () {
  count.innerHTML = num++;
  if (num == 11) {
    //关闭定时器
    clearInterval(timer);
  }
}, 1000);
clearInterval(timer);

延时调用

setTimeout()

延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次。

延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择。

clearTimeout()

clearTimeout()来关闭一个延时调用。

var timer = setTimeout(function () {
  console.log(num++);
}, 3000);

clearTimeout(timer);

修改元素的类更改样式

通过 style 属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面。 这样的执行的性能是比较差的,而且这种形式当我们要修改多个样式时,也不太方便 我希望一行代码,可以同时修改多个样式。

我们可以通过修改元素的 class 属性来间接的修改样式.这样一来,我们只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好,并且这种方式,可以使表现和行为进一步的分离。

box.className += ' b2'; //注意有空格,添加class属性
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
 * 参数:
 *     obj 要添加class属性的元素
 *  cn 要添加的class值
 *
 */
function addClass(obj, cn) {
  if (!hasClass(obj, cn)) {
    obj.className += ' ' + cn;
  }
}

/*
 * 判断一个元素中是否含有指定的class属性值
 *     如果有该class,则返回true,没有则返回false
 *
 */
function hasClass(obj, cn) {
  var reg = new RegExp('\\b' + cn + '\\b');
  return reg.test(obj.className);
}

/*
 * 删除一个元素中的指定的class属性
 */
function removeClass(obj, cn) {
  //创建一个正则表达式
  var reg = new RegExp('\\b' + cn + '\\b');
  //删除class
  obj.className = obj.className.replace(reg, '');
}

/*
 * toggleClass可以用来切换一个类
 *     如果元素中具有该类,则删除
 *     如果元素中没有该类,则添加
 */
function toggleClass(obj, cn) {
  //判断obj中是否含有cn
  if (hasClass(obj, cn)) {
    //有,则删除
    removeClass(obj, cn);
  } else {
    //没有,则添加
    addClass(obj, cn);
  }
}

JSON

JavaScript Object Notation JS 对象表示法

JSON 格式

  1. 复合类型的值只能是数组或对象,不能是函数、正则表达式对象、日期对象。
  2. 原始类型的值只有四种:字符串、数值(必须以十进制表示)、布尔值和 null
  3. 字符串必须使用双引号表示,不能使用单引号。
  4. 对象的键名必须放在双引号里面。
  5. 数组或对象最后一个成员的后面,不能加逗号。
[
  { "name": "孙悟空", "age": 18, "gender": "男" },
  { "name": "孙悟空", "age": 18, "gender": "男" }
]

JSON 和 JS 对象转换

JSON 转 JS 对象

var jsObj = JSON.parse(jsonStr);

JS 对象转 JSON

var jsonStr = JSON.stringify(jsObj);

other

localStorage

localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。

localStorage 属性是只读的。

// 保存数据
localStorage.setItem('key', 'value');

// 读取数据
var lastname = localStorage.getItem('key');

// 删除数据
localStorage.removeItem('key');

eval()

eval() 这个函数可以用来执行一段字符串形式的 JS 代码,并将执行结果返回

如果使用 eval()执行的字符串中含有{},它会将{}当成是代码块;如果不希望将其当成代码块解析,则需要在字符串前后各加上左右括号()。

eval()这个函数的功能很强大,可以直接执行一个字符串中的 js 代码,但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患。

var str = '{"name":"孙悟空","age":18,"gender":"男"}';
var obj = eval('(' + str + ')');

编码

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title></title>
    <script type="text/javascript">
      /*
       * 在字符串中使用转义字符输入Unicode编码
       *     \u四位编码
       */
      console.log('\u2620');
    </script>
  </head>
  <body>
    <!--在网页中使用Unicode编码
  &#编码; 这里的编码需要的是10进制
  -->
    <h1 style="font-size: 200px;">&#9760;</h1>
    <h1 style="font-size: 200px;">&#9856;</h1>
  </body>
</html>

confirm()

用于弹出一个带有确认和取消按钮的提示框,需要一个字符串作为参数,该字符串将会作为提示文字显示出来,如果用户点击确认则会返回 true,如果点击取消则返回 false。

var flag = confirm('确认删除' + name + '吗?');