1. 注释
1.行注释
//注释内容
2.块注释
/*注释内容*/
2. 规定
1. JS中严格区分大小写
2. JS中每一条语句以分号(;)结尾
- 如果不写分号,浏览器会自动添加,但是会消耗一些系统资源,
- 而且有些时候,浏览器会加错分号,所以在开发中分号必须写
3. JS中会忽略多个空格和换行,所以我们可以利用空格和换行对代码进行格式化
3. 字面量
1. 字面量是一些不可改变的值
1 2 3 4 5 "hello"
字面量都是可以直接使用的,但是我们一般不会使用字面量
4. 变量
1. 变量可以用来保存字面量, 是可以任意改变的值
2. 在JS中使用var关键字来声明一个变量;
3. 要先用"="赋值再使用
5. 标识符
在JS中所有的可以由我们自主命名的都可以称为是标识符
- 例如:变量名、函数名、属性名都属于标识符
- 命名一个标识符时需要遵守如下的规则:
1.标识符中可以含有字母、数字、_、$
2.标识符不能以数字开头
3.标识符不能是ES中的关键字或保留字
4.标识符一般都采用驼峰命名法
- 首字母小写,每个单词的开头字母大写,其余字母小写
helloWorld xxxYyyZzz
- JS底层保存标识符时实际上是采用的Unicode编码,
所以理论上讲,所有的UTF-8中含有的内容都可以作为标识符
6. 数据类型
- 前5个是基本数据类型,Object是引用数据类型
- 可以使用一个运算符 typeof来检查一个变量的类型
语法:typeof 变量
检查字符串时,会返回string
检查数值时,会返回number
检查布尔值时,会返回boolean
检查null时,会返回object
检查undefined时,会返回undefined
检查对象时,会返回object
检查函数时,会返回function
检查数组时,会返回object - JS中的变量都是保存到栈内存中的,
* 基本数据类型的值直接在栈内存中存储,
* 值与值之间是独立存在,修改一个变量不会影响其他的变量 - 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,
* 而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,
* 当一个通过一个变量修改属性时,另一个也会受到影响 - 当比较两个基本数据类型的值时,就是比较值。
- 而比较两个引用数据类型时,它是比较的对象的内存地址,如果两个对象是一摸一样的,但是地址不同,它也会返回false
1. String 字符串
- 在JS中字符串需要使用引号引起来
- 使用双引号或单引号都可以,但是不要混着用
- 引号不能嵌套,双引号不能放双引号,单引号不能放单引号
错误例子:var str = "我说:"今天天气不错"!";
正确例子:var str = "我说:'今天天气不错' !";
- 在字符串中我们可以使用\作为转义字符,
当表示一些特殊符号时可以使用\进行转义
\" 表示 "
\' 表示 '
\n 表示换行
\t 制表符
\\ 表示\
2. Number 数值
- 在JS中所有的数值都是Number类型,
* 包括整数和浮点数(小数)
- JS中可以表示的数字的最大值
* Number.MAX_VALUE=1.7976931348623157e+308
* Number.MIN_VALUE 大于0的最小值=5e-324
- 如果使用Number表示的数字超过了最大值,则会返回一个
* Infinity 表示正无穷
* -Infinity 表示负无穷
* 使用typeof检查Infinity也会返回number
- NaN 是一个特殊的数字,表示Not A Number
* 使用typeof检查一个NaN也会返回number
* NaN == NaN //false
- 如果使用JS进行浮点运算,可能得到一个不精确的结果
* 比如:var c = 0.1 + 0.2=0.30000000000000004
*可以这样解决:var c = (0.1*10 + 0.2*10)/10=0.3
* 所以千万不要使用JS进行对精确度要求比较高的运算
3. Boolean 布尔值
- 布尔值只有两个,主要用来做逻辑判断
* true 表示真
* false 表示假
4. Null 空值
- Null(空值)类型的值只有一个,就是null
- null这个值专门用来表示一个为空的对象
- 使用typeof检查一个null值时,会返回object
5. Undefined 未定义
- Undefined(未定义)类型的值只有一个,就undefined
- 当声明一个变量,但是并不给变量赋值时,它的值就是undefined
- 使用typeof检查一个undefined时也会返回undefined
6. Object 对象
1. 只要不是上边的5种,全都是对象
基本数据类型都是单一的值"hello" 123 true,值和值之间没有任何的联系。
2. 对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。
3. 对象的分类
1.内建对象
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object....
2.宿主对象
- 由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
- 比如 BOM DOM
3.自定义对象
- 由开发人员自己创建的对象
4. 创建对象
- 使用new关键字调用的函数,是构造函数constructor
构造函数是专门用来创建对象的函数
var obj = new Object();
- 使用typeof检查一个对象时,会返回object
- 另一种方法
var obj2 = {
name:"猪八戒",
age:13,
gender:"男",
test:{name:"沙僧"}
};
5. 对象属性
- 在对象中保存的值称为属性
- 向对象添加属性
语法:对象.属性名 = 属性值;
- 读取对象中的属性
语法:对象.属性名
如果读取对象中没有的属性,不会报错而是会返回undefined
- 删除对象的属性
语法:delete 对象.属性名
- 修改对象的属性值
语法:对象.属性名 = 新值
- 对象的属性名不强制要求遵守标识符的规范什么乱七八糟的名字都可以使用
但是我们使用是还是尽量按照标识符的规范去做
- 如果要使用特殊的属性名,不能采用.的方式来操作需要使用另一种方式:
语法:对象["属性名"] = 属性值
读取时也需要采用这种方式
使用[]这种形式去操作属性,更加的灵活,
在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
- in 运算符
- 通过该运算符可以检查一个对象中是否含有指定的属性
如果有则返回true,没有则返回false
- 语法:"属性名" in 对象
- 枚举对象中的属性
-使用for ... in 语句
语法:
for(var n in obj){
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
}
for...in语句 对象中有几个属性,循环体就会执行几次
每次执行时,会将对象中的一个属性的名字赋值给变量
7. 强制类型转换
- 指将一个数据类型强制转换为其他的数据类型
- 类型转换主要指,将其他的数据类型,转换为String Number Boolean
将其他的数据类型转换为String
方式一:
- 调用被转换数据类型的toString()方法
- 该方法不会影响到原变量,它会将转换的结果返回
- 对象也有这个方法,默认生成这样的“[object Object]”一个字符串
- 但是注意:null和undefined这两个值没有toString()方法,如果调用他们的方法,会报错
- 对于Number调用toString()时可以在方法中传递一个整数作为参数
此时它将会把数字转换为指定的进制,如果不指定则默认转换为10进制
方式二:
- 调用String()函数,并将被转换的数据作为参数传递给函数
- 该方法不会影响到原变量,它会将转换的结果返回
- 使用String()函数做强制类型转换时,
对于Number和Boolean实际上就是调用的toString()方法
但是对于null和undefined,就不会调用toString()方法
它会将 null 直接转换为 "null"
将 undefined 直接转换为 "undefined"
方式三:
我们只需要为任意的数据类型 + 一个 "" 即可将其转换为String。
这是一种隐式的类型转换,由浏览器自动完成,实际上它也是调用String()函数
将其他的数据类型转换为Number
方式一:
使用Number()函数
- 字符串 --> 数字
- 如果是纯数字的字符串,则直接将其转换为数字
- 如果字符串中有非数字的内容,则转换为NaN
- 如果字符串是一个空串或者是一个全是空格的字符串,则转换为0
- 布尔 --> 数字
- true 转成 1
- false 转成 0
- null --> 数字 0
- undefined --> 数字 NaN
- 对象-->数字
- 永远是NaN
方式二:
这种方式专门用来对付字符串
- parseInt() 把一个字符串转换为一个整数
- parseInt()可以将一个以数字或空格开头的字符串中前面的有效的整数内容读出来,然后转换为Number
- parseFloat() 把一个字符串转换为一个浮点数
- parseFloat()作用和parseInt()类似,不同的是它可以获得有效的小数
- 可以在parseInt()/parseFloat()中传递一个第二个参数,来指定数字的进制
- a = parseInt("070",8); //八进制转换,结果56
方式三:
*任何值做- * /运算时都会自动转换为Number
我们可以利用这一特点做隐式的类型转换
可以通过为一个值 -0 ,*1 ,/1来将其转换为Number
原理和Number()函数一样,使用起来更加简单
*任何值做+一元运算,会自动转换为Number
a = "18";
a = +a; //a变number了
将其他的数据类型转换为Boolean
- 使用Boolean()函数
- 数字 ---> 布尔
- 除了0和NaN,其余的都是true
- 字符串 ---> 布尔
- 除了空串,其余的都是true
- null和undefined都会转换为false
- 对象也会转换为true
- 如果对非布尔值进行取反,则会将其转换为布尔值,然后再取反
所以我们可以利用该特点,来将一个其他的数据类型转换为布尔值
可以为一个任意数据类型取两次反,来将其转换为布尔值,
原理和Boolean()函数一样
var b = 10;
b = !!b;
8. 运算符
1.运算符也叫操作符
2.通过运算符可以对一个或多个值进行运算,并获取运算结果
比如:typeof就是运算符,可以来获得一个值的类型
它会将该值的类型以字符串的形式返回
number string boolean undefined object,function
3.算数运算符
当对非Number类型的值进行运算时,会将这些值转换为Number然后在运算
任何值和NaN做运算都得NaN
+
+可以对两个值进行加法运算,并将结果返回
如果对两个字符串进行加法运算,则会做拼串,会将两个字符串拼接为一个字符串,并返回
任何的值和字符串做加法运算,都会先转换为字符串,然后再和字符串做拼串的操作。
我们可以利用这一特点,来将一个任意的数据类型转换为String。
我们只需要为任意的数据类型 + 一个 "" 即可将其转换为String。
这是一种隐式的类型转换,由浏览器自动完成,实际上它也是调用String()函数
-
- 可以对两个值进行减法运算,并将结果返回
*
* 可以对两个值进行乘法运算
/
/ 可以对两个值进行除法运算
%
% 取模运算(取余数)
*任何值做- * /运算时都会自动转换为Number
我们可以利用这一特点做隐式的类型转换
可以通过为一个值 -0 ,*1 ,/1来将其转换为Number
原理和Number()函数一样,使用起来更加简单
*任何值做+一元运算,会自动转换为Number
a = true;
a = "18";
a = +a; //a变number了
9. 逻辑运算
JS中为我们提供了三种逻辑运算符
对于非布尔值进行与或运算时,会先将其转换为布尔值,然后再运算,并且返回原值
1.! 非
- !可以用来对一个值进行非运算,返回结果是布尔值
- 所谓非运算就是值对一个布尔值进行取反操作,
true变false,false变true
- 如果对一个值进行两次取反,它不会变化
- 如果对非布尔值进行取反,则会将其转换为布尔值,然后再取反
所以我们可以利用该特点,来将一个其他的数据类型转换为布尔值
可以为一个任意数据类型取两次反,来将其转换为布尔值,
原理和Boolean()函数一样
2. && 与
- &&可以对符号两侧的值进行与运算并返回结果,返回结果不一定是布尔值
- 运算规则
- 两个值中只要有一个值为false就返回false,
只有两个值都为true时,才会返回true
- JS中的“与”属于短路的与,
如果第一个值为false,则不会看第二个值
- 对于非布尔值进行与运算时,会先将其转换为布尔值,然后再运算,并且返回原值
- 如果第一个值为true,则必然返回第二个值
- 如果第一个值为false,则直接返回第一个值
3.|| 或
- ||可以对符号两侧的值进行或运算并返回结果
- 运算规则:
- 两个值中只要有一个true,就返回true
如果两个值都为false,才返回false
- JS中的“或”属于短路的或
如果第一个值为true,则不会检查第二个值
- 对于非布尔值进行或运算时,会先将其转换为布尔值,然后再运算,并且返回原值
- 如果第一个值为true,则直接返回第一个值
- 如果第一个值为false,则返回第二个值
10.关系运算符
- 通过关系运算符可以比较两个值之间的大小关系,
如果关系成立它会返回true,如果关系不成立则返回false
- 非数值的情况
- 对于非数值进行比较时,会将其转换为数字然后在比较
- 如果符号两侧的值都是字符串时,不会将其转换为数字进行比较
而会分别比较字符串中字符的Unicode编码
- 比较两个字符串时,比较的是字符串的字符编码
//console.log("a" < "b");//true
- 比较字符编码时是一位一位进行比较
- 如果两位一样,则比较下一位,所以借用它来对英文进行排序
//console.log("abc" < "bcd");//true
- 比较中文时没有意义
- 如果比较的两个字符串型的数字,可能会得到不可预期的结果
注意:在比较两个字符串型的数字时,一定一定一定要转型
11. 相等运算符
1.相等 ==
当使用==来比较两个值时,如果值的类型不同,则会自动进行类型转换,将其转换为相同的类型,然后在比较,如果相等会返回true,否则返回false
- undefined 衍生自 null,所以这两个值做相等判断时,会返回true
- NaN不和任何值相等,包括他本身
- 可以通过isNaN()函数来判断一个值是否是NaN,如果该值是NaN则返回true,否则返回false
2. 不相等 !=
不相等也会对变量进行自动的类型转换,如果转换后相等它会返回false
3. 全等 ===
用来判断两个值是否全等,它和相等类似,不同的是它不会做自动的类型转换,如果两个值的类型不同,直接返回false
4.不全等 !==
用来判断两个值是否不全等,和不等类似,不同的是它不会做自动的类型转换,如果两个值的类型不同,直接返回true
12. 函数 function
- 函数也是一个对象
- 对象的属性也可以说函数(方法)
- 函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)
- 函数中可以保存一些代码在需要的时候调用
- 使用typeof检查一个函数对象时,会返回function
- 创建一个函数对象
可以将要封装的代码以字符串的形式传递给构造函数
var fun = new Function("console.log('Hello 这是我的第一个函数');");
封装到函数中的代码不会立即执行
函数中的代码会在函数调用的时候执行
* 我们在实际开发中很少使用构造函数来创建一个函数对象,用下面的
- 使用 函数声明 来创建一个函数
function 函数名([形参1,形参2...形参N]){
语句...
}
- 使用 函数表达式 来创建一个函数
var 函数名 = function([形参1,形参2...形参N]){
语句....
}
- 调用函数 语法:函数对象()
当调用函数时,函数中封装的代码会按照顺序执行
fun();
13. 函数参数
- 可以在函数的()中来指定一个或多个形参(形式参数),多个形参之间使用,隔开,声明形参就相当于在函数内部声明了对应的变量,但是并不赋值
- 调用函数时,解析器不会检查实参的类型,也不会检查实参的数量
- 多余实参不会被赋值
- 如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined
14. 返回值
1. 可以使用 return 来设置函数的返回值
2. 语法:return 值
3. return后的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果
4. 在函数中return后的语句都不会执行
5. 如果return语句后不跟任何值就相当于返回一个undefined,如果函数中不写return,则也会返回undefined
6. return后可以跟任意类型的值
14. 立即执行函数
函数对象()
- 函数定义完,立即被调用,这种函数叫做立即执行函数
- 立即执行函数往往只会执行一次
(function(){
alert("我是一个匿名函数~~~");
})();
15. 作用域
- 作用域指一个变量的作用的范围
- 声明提前
1.变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)
但是如果声明变量时不适用var关键字,则变量不会被声明提前
2.函数的声明提前
- 使用函数声明形式创建的函数 function 函数(){}
它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
- 使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
- 在JS中一共有两种作用域:
1.全局作用域
- 直接编写在script标签中的JS代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window,
它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
- 在全局作用域中:
创建的变量都会作为window对象的属性保存
创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,
在页面的任意的部分都可以访问的到
2.函数作用域
- 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
- 在函数作用域中可以访问到全局作用域的变量
在全局作用域中无法访问到函数作用域的变量
- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
如果没有则向上一级作用域中寻找,直到找到全局作用域,
如果全局作用域中依然没有找到,则会报错ReferenceError
- 在函数中要访问全局变量可以使用window对象
- 在函数中,不使用var声明的变量都会成为全局变量
- 定义形参就相当于在函数作用域中声明了变量
16.this
解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
这个隐含的参数就是this,this指向的是一个对象,
这个对象我们称为函数执行的 上下文对象,
根据函数的调用方式的不同,this会指向不同的对象
1.以函数形式调用时,this永远都是window
2.以方法的形式调用时,this是调用方法的对象
3.以构造函数的形式调用时,this是新创建的那个对象
4.使用call和apply调用时,this是指定的那个对象
5.在事件中,this指向触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window
17.构造函数
1.构造函数就是一个普通的函数,创建方式和普通函数没有区别,
不同的是构造函数习惯上首字母大写
2.构造函数和普通函数的区别就是调用方式的不同
普通函数是直接调用,而构造函数需要使用new关键字来调用
3.构造函数的执行流程:
1.立刻创建一个新的对象
2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象
3.逐行执行函数中的代码
4.将新建的对象作为返回值返回
4.this的情况:
1.当以函数的形式调用时,this是window
2.当以方法的形式调用时,谁调用方法this就是谁
3.当以构造函数的形式调用时,this就是新创建的那个对象
5.例子
function Person(name , age , gender){
this.name = name;
this.age = age;
this.gender = gender;
}
//向原型中添加sayName方法,可以使所有的对象共享同一个方法
Person.prototype.sayName = function(){
alert("Hello大家好,我是:"+this.name);
};
var per = new Person("孙悟空",18,"男");
6.使用instanceof可以检查一个对象是否是一个类的实例
- 语法:
对象 instanceof 构造函数
- 如果是,则返回true,否则返回false
- console.log(per instanceof Person);
- 所有的对象都是Object的后代,
所以任何对象和Object在instanceof检查时都会返回true
18.原型 prototype
1.我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
这个属性对应着一个对象,这个对象就是我们所谓的原型对象
2.如果函数作为普通函数调用prototype没有任何作用
3.当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,
指向该构造函数的原型对象,我们可以通过__proto__来访问该属性
4.原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
我们可以将对象中共有的内容,统一设置到原型对象中。
5.当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
如果没有则会去原型对象中寻找,如果找到则直接使用
6.以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,
这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
7.使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
7.可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性,而含有原型中还有
使用该方法只有当对象自身中含有属性时,才会返回true
8.原型对象也是对象,所以它也有原型,当我们使用一个对象的属性或方法时,会现在自身中寻找
自身中如果有,则直接使用,
如果没有则去原型对象中寻找,如果原型对象中有,则使用,
如果没有则去原型的原型中寻找,直到找到Object对象的原型,
Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined
19. 垃圾回收 GC
- 就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
这些垃圾积攒过多以后,会导致程序运行的速度过慢,
所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
- 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
所以这种垃圾必须进行清理。
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
我们不需要也不能进行垃圾回收的操作
- 我们需要做的只是要将不再使用的对象设置null即可
20. 数组 Array
- 数组也是一个对象
- 它和我们普通对象功能类似,也是用来存储一些值的
- 不同的是普通对象是使用字符串作为属性名的,而数组时使用数字来作为索引操作元素
- 索引:从0开始的整数就是索引
- 数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据
- 创建数组对象
var arr = new Array();
- 向数组中添加元素
语法:数组[索引] = 值
- 读取数组中的元素
语法:数组[索引]
如果读取不存在的索引,他不会报错而是返回undefined
- 获取数组的长度
可以使用length属性来获取数组的长度(元素的个数)
语法:数组.length
对于连续的数组,使用length可以获取到数组的长度(元素的个数)
对于非连续的数组,使用length会获取到数组的最大的索引+1,尽量不要创建非连续的数组
- 修改length
如果修改的length大于原长度,则多出部分会空出来
如果修改的length小于原长度,则多出的元素会被删除,变为undefined
- 向数组的最后一个位置添加元素
语法:数组[数组.length] = 值;
- 使用字面量来创建数组
语法:[]
var arr = [];
- 使用字面量创建数组时,可以在创建时就指定数组中的元素
var arr = [1,2,3,4,5,10];
- 使用构造函数创建数组时,也可以同时添加元素,将要添加的元素作为构造函数的参数传递元素之间使用,隔开
var arr2 = new Array(10,20,30);
- 创建一个长度为10的数组
arr2 = new Array(10);
- 数组中的元素可以是任意的数据类型,甚至对象,函数和数组
arr = ["hello",1,true,null,undefined,{name:"孙悟空"},function(){alert(1)},[1,2,3]];
21. 数组的方法 补充:for in,forEach, for of的区别
1. push() 改变数组
- 该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
- 可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的末尾
- 该方法会将数组新的长度作为返回值返回
2. pop() 改变数组
- 该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
3. unshift() 改变数组
- 向数组开头添加一个或多个元素,并返回新的数组长度
- 向前边插入元素以后,其他的元素索引会依次调整
4. shift() 改变数组
- 可以删除数组的第一个元素,并将被删除的元素作为返回值返回
5. forEach()
- 一般我们都是使用for循环去遍历数组,JS中还为我们提供了一个方法,用来遍历数组:forEach()
- 这个方法只支持IE8以上的浏览器,IE8及以下的浏览器均不支持该方法,
所以如果需要兼容IE8,则不要使用forEach,还是使用for循环来遍历
- forEach()方法需要一个函数作为参数
- 像这种函数,由我们创建但是不由我们调用的,我们称为回调函数
- 数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素
以实参的形式传递进来,我们可以来定义形参,来读取这些内容
- 浏览器会在回调函数中传递三个参数:
第一个参数,就是当前正在遍历的元素
第二个参数,就是当前正在遍历的元素的索引
第三个参数,就是正在遍历的数组
-例子 :
arr.forEach(function(value , index , obj){
console.log(index);
});
6. slice() 不改变数组
- 可以用来从数组提取指定元素
- 该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回
- 参数:
1.截取开始的位置的索引,包含开始索引
2.截取结束的位置的索引,不包含结束索引
- 第二个参数可以省略不写,此时会截取从开始索引往后的所有元素
3.索引可以传递一个负值,如果传递一个负值,则从后往前计算
-1 倒数第一个
-2 倒数第二个
7. splice() 改变数组
- 可以用于删除数组中的指定元素
- 使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除的元素作为返回值返回
- 参数:
第一个,表示开始位置的索引
第二个,表示删除的数量
第三个及以后。。可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边
8. concat() 不改变数组
-可以连接两个或多个数组,并将新的数组返回
- 该方法不会对原数组产生影响
- var result = arr.concat(arr2,arr3,"牛魔王","铁扇公主");
9. join() 不改变数组
- 该方法可以将数组转换为一个字符串
- 该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
- 在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
如果不指定连接符,则默认使用,作为连接符
- result = arr.join("@-@");
孙悟空@-@猪八戒@-@沙和尚@-@唐僧
10. reverse() 改变数组
- 该方法用来反转数组(前边的去后边,后边的去前边)
- 该方法会直接修改原数组
11. sort() 改变数组
- 可以用来对数组中的元素进行排序
- 也会影响原数组,默认会按照Unicode编码进行排序
- 即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,
所以对数字进排序时,可能会得到错误的结果。
- 我们可以自己来指定排序的规则
我们可以在sort()添加一个回调函数,来指定排序规则,回调函数中需要定义两个形参,
浏览器将会分别使用数组中的元素作为实参去调用回调函数,
使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边
- 浏览器会根据回调函数的返回值来决定元素的顺序,
如果返回一个大于0的值,则元素会交换位置
如果返回一个小于0的值,则元素位置不变
如果返回一个0,则认为两个元素相等,也不交换位置
- 如果需要升序排列,则返回 a-b
- 如果需要降序排列,则返回b-a
12. map() 不改变数组
- 返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
- array.map(function(currentValue,index,arr), thisValue)
- currentValue 必须。当前元素的值
- index 可选。当前元素的索引值
- arr 可选。当前元素属于的数组对象
- thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
12. filter() 不改变数组
- 遍历过滤出一个新的子数组, 返回条件为true的值
- array.filter(function(currentValue,index,arr), thisValue)
- currentValue 必须。当前元素的值
- index 可选。当前元素的索引值
- arr 可选。当前元素属于的数组对象
- thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
13. indexOf(value) 不改变数组
- 得到值在数组中的第一个下标
14. astIndexOf(value) 不改变数组
- 得到值在数组中的最后一个下标
15. Array.prototype.includes(value) : 判断数组中是否包含指定value
16. array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
参数 描述
total 必需。初始值, 或者计算结束后的返回值。
currentValue 必需。当前元素
currentIndex 可选。当前元素的索引
arr 可选。当前元素所属的数组对象。
initialValue 可选。传递给函数的初始值
接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
22. 函数的方法
1. call()和apply()
- 这两个方法都是函数对象的方法,需要通过函数对象来调用
- 当对函数调用call()和apply()都会调用函数执行
- 在调用call()和apply()可以将一个对象指定为第一个参数
此时这个对象将会成为函数执行时的this
- call()方法可以将实参在对象之后依次传递
- apply()方法需要将实参封装到一个数组中统一传递
- this的情况:
1.以函数形式调用时,this永远都是window
2.以方法的形式调用时,this是调用方法的对象
3.以构造函数的形式调用时,this是新创建的那个对象
4.使用call和apply调用时,this是指定的那个对象
2. bind()
- 作用: 将函数内的this绑定为obj, 并将函数返回
- 区别bind()与call()和apply()?
* 都能指定函数中的this
* call()/apply()是立即调用函数
* bind()是将函数返回
* bind()传参和call一样,都是在要绑定的this后依次写上,用,隔开
```F
#23. arguments
在调用函数时,浏览器每次都会传递进两个隐含的参数:
1.函数的上下文对象 this
2.封装实参的对象 arguments
- arguments是一个伪数组对象,它也可以通过索引来操作数据,也可以获取长度
- 在调用函数时,我们所传递的实参都会在arguments中保存
- arguments.length可以用来获取实参的长度
- 我们即使不定义形参,也可以通过arguments来使用实参,只不过比较麻烦
arguments[0] 表示第一个实参
arguments[1] 表示第二个实参 。。。
- 它里边有一个属性叫做callee,这个属性对应一个函数对象,就是当前正在指向的函数的对象
#24. Date对象
- 在JS中使用Date对象来表示一个时间
- 创建一个Date对象
如果直接使用构造函数创建一个Date对象,则会封装为当前代码执行的时间
var d = new Date(); - 创建一个指定的时间对象
需要在构造函数中传递一个表示时间的字符串作为参数
日期的格式 月份/日/年 时:分:秒
var d2 = new Date("2/18/2011 11:10:30"); - 获取
- getDate()
- 获取当前日期对象是几日
- getDay()
- 获取当前日期对象时周几
- 会返回一个0-6的值
0 表示周日
1 表示周一 。。。
- getMonth()
- 获取当前时间对象的月份
- 会返回一个0-11的值
0 表示1月
1 表示2月
11 表示12月
- getFullYear()
- 获取当前日期对象的年份
- getHours()
- 获取当前日期对象的小时(0~23)
- getMinutes()
- 获取当前日期对象的分钟(0~59)
- getSeconds()
- 获取当前日期对象的秒(0~59)
- getMilliseconds()
- 获取当前日期对象的毫秒(0~999)
- getTime()
- 获取当前日期对象的时间戳
- 时间戳,指的是从格林威治标准时间的1970年1月1日,0时0分0秒到当前日期所花费的毫秒数(1秒 = 1000毫秒)
- 计算机底层在保存时间时使用都是时间戳
- Date.now()
- 获取执行该行代码时的时间戳
- var start = Date.now();
- var end = Date.now();
- 利用时间戳来测试代码的执行的性能
- toTimeString()
- 把 Date 对象的日期部分转换为可读字符串:
#25. Math
- Math和其他的对象不同,它不是构造函数,它属于工具类不用创建对象,它里边封装了数学运算相关的属性和方法
- 比如:Math.PI 表示的圆周率
- abs()
可以用来计算一个数的绝对值
Math.abs(-1) = 1 - Math.ceil()
可以对一个数进行向上取整,小数位只要有值就自动进1
Math.ceil(1.1) = 2 - Math.floor()
可以对一个数进行向下取整,小数部分会被舍掉
Math.floor(1.99) = 1 - Math.round()
可以对一个数进行四舍五入取整
Math.round(1.4) = 1 - Math.random()
- 可以用来生成一个(0,1)之间的随机数 开区间
- 生成一个0-x之间的随机数
Math.round(Math.random()*x) - 生成一个x-y之间的随机数
Math.round(Math.random()*(y-x)+x)
- max() 可以获取多个数中的最大值
var max = Math.max(10,45,30,100); - min() 可以获取多个数中的最小值
var min = Math.min(10,45,30,100); - Math.pow(x,y)
返回x的y次幂 - Math.sqrt()
用于对一个数进行开方运算
#26. 包装类
- 在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
- String()
- 可以将基本数据类型字符串转换为String对象
- var num = new Number(3);
- Number()
- 可以将基本数据类型的数字转换为Number对象
- var str = new String("hello");
- Boolean()
- 可以将基本数据类型的布尔值转换为Boolean对象
- var bool = new Boolean(true);
- 但是注意:我们在实际应用中不会使用基本数据类型的对象,
如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果 - 方法和属性只能添加给对象,不能添加给基本数据类型
当我们对一些基本数据类型的值去调用属性和方法时,
浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法
调用完以后,再将其转换为基本数据类型
#27. 字符串的相关方法
- 在底层字符串是以字符数组的形式保存的
["H","e","l"] - length属性
- 可以用来获取字符串的长度
- charAt()
- 可以返回字符串中指定位置的字符
- 根据索引获取指定的字符
- charCodeAt()
- 获取指定位置字符的字符编码(Unicode编码)
- String.formCharCode()
- 可以根据字符编码去获取字符
- concat() 不改变字符串
- 可以用来连接两个或多个字符串
- 作用和+一样
- indexof()
- 该方法可以检索一个字符串中是否含有指定内容
- 如果字符串中含有该内容,则会返回其第一次出现的索引,如果没有找到指定的内容,则返回-1
- 可以指定一个第二个参数,指定开始查找的位置
- lastIndexOf();
- 该方法的用法和indexOf()一样,不同的是indexOf是从前往后找,而lastIndexOf是从后往前找
- 也可以指定开始查找的位置
- slice() 不改变字符串
- 可以从字符串中截取指定的内容
- 不会影响原字符串,而是将截取到内容返回
- 参数:
- 第一个,开始位置的索引(包括开始位置)
- 第二个,结束位置的索引(不包括结束位置)
- 如果省略第二个参数,则会截取到后边所有的
- 也可以传递一个负数作为参数,负数的话将会从后边计算
- substring() 不改变字符串
- 可以用来截取一个字符串,可以slice()类似
- 参数:
- 第一个:开始截取位置的索引(包括开始位置)
- 第二个:结束位置的索引(不包括结束位置)
- 不同的是这个方法不能接受负值作为参数,如果传递了一个负值,则默认使用0
- 而且他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换
- substr 不改变字符串
- 用来截取字符串
- 参数:
1.截取开始位置的索引
2.截取的长度
- split() 不改变字符串
- 可以将一个字符串拆分为一个数组
- 参数:
- 需要一个字符串作为参数,将会根据该字符串去拆分数组
- 如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素
- 方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串
- 这个方法即使正则表达式不指定全局匹配,也会全都拆分
- toUpperCase() 不改变字符串
- 将一个字符串转换为大写并返回
- toLowerCase() 不改变字符串
- 将一个字符串转换为小写并返回
- search()
- 可以搜索字符串中是否含有指定内容
- 如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1
- 它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
- serach()只会查找第一个,即使设置全局匹配也没用
- match()
- 可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
- 默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
可以为一个正则表达式设置多个匹配模式,且顺序无所谓 - match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
- replace()
- 可以将字符串中指定内容替换为新的内容
- 参数:
1.被替换的内容,可以接受一个正则表达式作为参数
2.新的内容 - 默认只会替换第一个
#28. 正则表达式
- 正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式,
来检查一个字符串是否符合规则,获取将字符串中符合规则的内容提取出来 - 创建正则表达式的对象
语法:
var 变量 = new RegExp("正则表达式","匹配模式");
使用typeof检查正则对象,会返回object
var reg = new RegExp("a"); 这个正则表达式可以来检查一个字符串中是否含有a
在构造函数中可以传递一个匹配模式作为第二个参数,可以是
i 忽略大小写
g 全局匹配模式. 查找所有匹配而并非在找到带一个匹配后停止
可以为一个正则表达式设置多个匹配模式,且顺序无所谓 /[a-z]/ig - 正则表达式的方法:
test()- 使用这个方法可以用来检查一个字符串是否符合正则表达式的规则,如果符合则返回true,否则返回false
- 使用字面量来创建正则表达式
语法:var 变量 = /正则表达式/匹配模式- 使用字面量的方式创建更加简单
- 使用构造函数创建更加灵活,因为可以把变量作为一个正则表达式传进去
- 可以为一个正则表达式设置多个匹配模式,且顺序无所谓
- 正则表达式规则
- 使用 | 表示或者的意思
- []里的内容也是或的关系
[ab] == a|b - [a-z] 任意小写字母
- [A-Z] 任意大写字母
- [A-z] 任意字母
- [0-9] 任意数字
- [^ ] 除了
- 量词
- 通过量词可以设置一个内容出现的次数
- 量词只对它前边的一个内容起作用
- {n} 正好出现n次
- {m,n} 出现m-n次
- {m,} m次以上
-
- 至少一个,相当于{1,}
-
- 0个或多个,相当于{0,}
- ? 0个或1个,相当于{0,1}
- ^ 表示开头
- $ 表示结尾
- 元字符
- .
- 表示任意字符,除了换行和行结束符
- \w
- 任意字母、数字、_ [A-z0-9_]
- \W
- 除了字母、数字、_ [^A-z0-9_]
- \d
- 任意的数字 [0-9]
- \D
- 除了数字 [^0-9]
- \s
- 空格
- \S
- 除了空格
- \b
- 单词边界
- \B
- 除了单词边界
#29. DOM
- DOM,全称Document Object Model文档对象模型。
- JS中通过DOM来对HTML文档进行操作。只要理解了DOM就可以随
心所欲的操作WEB页面。 - 文档
- 文档表示的就是整个的HTML网页文档
- 对象
- 对象表示将网页中的每一个部分都转换为了一个对象。
- 模型
- 使用模型来表示对象之间的关系,这样方便我们获取对象。
- 节点
- Node——构成HTML文档最基本的单元。
- 常用节点分为四类
- 文档节点:整个HTML文档
- 元素节点:HTML文档中的HTML标签
- 属性节点:元素的属性
- 文本节点:HTML标签中的文本内容
![QQ浏览器截图20200121175011.png](https://upload-images.jianshu.io/upload_images/20262498-294267c6e146ac2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 文档节点
- 文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。
- document对象作为window对象的属性存在
的,我们不用获取可以直接使用。 - 通过该对象我们可以在整个文档访问内查找节
点对象,并可以通过该对象创建各种节点对象。 - console.log(document);
- 元素节点
- HTML中的各种标签都是元素节点,这也是我们最常用的一个节点。
- 浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。
- 比如:
- document.getElementById()
- 根据id属性值获取一个元素节点对象
- 文本节点(Text)
- 文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。
- 它包括可以字面解释的纯文本内容。
- 文本节点一般是作为元素节点的子节点存在的。
- 获取文本节点时,一般先要获取元素节点。在通过元素节点获取文本节点。
- 例如:
- 元素节点.firstChild;
- 获取元素节点的第一个子节点,一般为文本节点
- 属性节点(Attr)
- 属性节点表示的是标签中的一个一个的属性
这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。 - 可以通过元素节点来获取指定的属性节点。
- 例如:
- 元素节点.getAttributeNode("属性名");
- 注意:我们一般不使用属性节点
- 获取元素节点
- 通过document对象调用
- getElementById()
- 通过id属性获取一个元素节点对象
- getElementsByTagName()
- 通过标签名获取一组元素节点对象
- getElementsByName()
- 通过name属性获取一组元素节点对象
- 获取元素节点的子节点
- 通过具体的元素节点调用
- getElementsByTagName()
- 方法,返回当前节点的指定标签名后代节点
- childNodes
- 属性,表示当前节点的所有子节点,文本元素都有
- children
- 属性,表示当前节点的所有子节点,只有元素节点,推荐使用
- firstChild
- 属性,表示当前节点的第一个子节点,文本元素都有
- firstElementChild
- 获取当前元素的第一个子元素,只有元素节点,不支持ie8
- lastChild
- 属性,表示当前节点的最后一个子节点
- firstElementChild
- 获取当前元素的最后一个子元素,只有元素节点,不支持ie8
- 获取父节点和兄弟节点
- 通过具体的节点调用
- parentNode
- 属性,表示当前节点的父节点
- parentElement
- 属性,表示当前节点的父元素
- previousSibling
- 属性,表示当前节点的前一个兄弟节点
- previousElementSibling
- 属性,表示当前节点的前一个兄弟元素,不支持ie8
- nextSibling
- 属性,表示当前节点的后一个兄弟节点
- nextElementSibling
- 属性,表示当前节点的后一个兄弟元素,不支持ie8
- 元素节点的属性
- 获取,元素对象.属性名
例:element.value
element.id
element.className - 设置,元素对象.属性名=新的值
例:element.value = “hello”
element.id = “id01”
element.className = “newClass” - 其他属性
- nodeValue
- 文本节点可以通过nodeValue属性获取和设置文本节点的内容
- innerHTML
- 元素节点通过该属性获取和设置标签内部的html代码
- innerHTML对于自结束标签,这个属性没有意义
- innerText
- 该属性可以获取到元素内部的文本内容
-
- 它和innerHTML类似,不同的是它会自动将html去除
- nodeValue
- 事件
- 事件,就是用户和浏览器之间的交互行为,比如:点击按钮,鼠标移动、关闭窗口。。。
- 可以为按钮的对应事件绑定处理函数的形式来响应事件,这样当事件被触发时,其对应的函数将会被调用
//绑定一个单击事件
//像这种为单击事件绑定的函数,我们称为单击响应函数
btn.onclick = function(){
alert("点击了按钮");
};
- 文档的加载
- 浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,
如果将script标签写到页面的上边,在代码执行时,页面还没有加载,
页面没有加载DOM对象也没有加载,会导致无法获取到DOM对象 - onload事件会在整个页面加载完成之后才触发
为window绑定一个onload事件
该事件对应的响应函数将会在页面加载完成之后执行,
这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了 - window.onload = function(){
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("hello");
};
};
- DOM查询的其他方法
- 获取body标签
var body = document.body; - 获取html 标签
var html = document.documentElement; - 获取所有标签
var all = document.all;
var all = document.getElementsByTagName("*"); - 根据元素的class属性值查询一组元素节点对象
getElementsByClassName()可以根据class属性值获取一组元素节点对象,
但是该方法不支持IE8及以下的浏览器 - CSS选择器
- var div = document.querySelector(".box1 div");
- 需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
- 虽然IE8中没有getElementsByClassName()但是可以使用querySelector()代替
- 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
2. document.querySelectorAll()
- 该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回
- 即使符合条件的元素只有一个,它也会返回数组
- DOM增删改
- document.createElement()
可以用于创建一个元素节点对象
它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回 - document.createTextNode()
可以用来创建一个文本节点对象
需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回 - appendChild()
- 向一个父节点中添加一个新的子节点
- 语法:父节点.appendChild(子节点);
- insertBefore()
- 可以在指定的子节点前插入新的子节点
- 语法:父节点.insertBefore(新节点,指定的子节点);
- replaceChild()
- 可以使用指定的子节点替换已有的子节点
- 语法:父节点.replaceChild(新节点,旧节点);
- removeChild()
- 可以删除一个子节点
- 语法:父节点.removeChild(子节点);
子节点.parentNode.removeChild(子节点);
- DOM操作CSS
- 通过JS修改元素的样式:
- 语法:元素.style.样式名 = 样式值
- 注意:如果CSS的样式名中含有-,这种名称在JS中是不合法的比如background-color
需要将这种样式名修改为驼峰命名法,去掉-,然后将-后的字母大写
- 我们通过style属性设置的样式都是内联样式,而内联样式有较高的优先级,所以通过JS修改的样式往往会立即显示
但是如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,
此时将会导致JS修改样式失效,所以尽量不要为样式添加!important
- 读取元素的内联样式
- 语法:元素.style.样式名
- 通过style属性设置和读取的都是内联样式,无法读取样式表中的样式
- 获取元素的当前显示的样式(IE)
- 语法:元素.currentStyle.样式名
- 它可以用来读取当前元素正在显示的样式,如果当前元素没有设置该样式,则获取它的默认值
- currentStyle只有IE浏览器支持,其他的浏览器都不支持
- 获取元素当前的样式(其他)
- var obj = getComputedStyle(box1,null);
- 在其他浏览器中可以使用
- getComputedStyle()这个方法来获取元素当前的样式
- 这个方法是window的方法,可以直接使用
- 需要两个参数
第一个:要获取样式的元素
第二个:可以传递一个伪元素,一般都传null
- 该方法会返回一个对象,对象中封装了当前元素对应的样式
- 可以通过对象.样式名来读取样式
- 如果获取的样式没有设置,则会获取到真实的值,而不是默认值
比如:没有设置width,它不会获取到auto,而是一个长度
- 但是该方法不支持IE8及以下的浏览器
- 通过currentStyle和getComputedStyle()读取到的样式都是只读的,
- 不能修改,如果要修改必须通过style属性
-
兼容IE8和其他浏览器的获取样式
定义一个函数,用来获取指定元素的当前的样式
* 参数:
* obj 要获取样式的元素
* name 要获取的样式名
function getStyle(obj , name){if(window.getComputedStyle){ //正常浏览器的方式,具有getComputedStyle()方法 return getComputedStyle(obj , null)[name]; }else{ //IE8的方式,没有getComputedStyle()方法 return obj.currentStyle[name]; }
其他样式属性
clientWidth和clientHeight
- 这两个属性可以获取元素的可见宽度和高度
- 这些属性都是不带px的,返回都是一个数字,可以直接进行计算
- 会获取元素宽度和高度,包括内容区和内边距
- 这些属性都是只读的,不能修改
2. offsetWidth和offsetHeight
- 获取元素的整个的宽度和高度,包括内容区、内边距和边框
3. offsetParent
- 可以用来获取当前元素的定位父元素
- 会获取到离当前元素最近的开启了定位的祖先元素
如果所有的祖先元素都没有开启定位,则返回body
4. offsetLeft
- 当前元素相对于其定位父元素的水平偏移量
5. offsetTop
- 当前元素相对于其定位父元素的垂直偏移量
6. scrollWidth和scrollHeight
- 可以获取元素整个滚动区域的宽度和高度
7. scrollLeft和scrollTop
- 可以获取水平滚动条滚动的距离和垂直滚动条滚动的距离
8. 当满足scrollHeight - scrollTop == clientHeight,说明垂直滚动条滚动到底了
当满足scrollWidth - scrollLeft == clientWidth,说明水平滚动条滚动到底
#30. 事件对象
- 添加事件对象的三种办法
- 通过HTML标签的属性设置
- 通过DOM对象的属性绑定 (推荐)
- var btn = document.getElementById('btn');
btn.onclick = function(){
alert("hello");
};
- 设置事件监听器
- btn.addEventListener('click' , function(){alert("hello");});
- 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数
在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标 键盘哪个按键被按下 鼠标滚轮滚动的方向。。 - 在IE8中,响应函数被触发时,浏览器不会传递事件对象,
在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的
解决方法:
var event = event || window.event; - clientX和clientY用于获取鼠标在当前的可见窗口的坐标
#30. 事件冒泡
- 事件的冒泡(Bubble)
- 所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
- 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡
- 取消冒泡/捕获
- 可以将事件对象的cancelBubble设置为true,即可取消冒泡/捕获
event.cancelBubble = true;
在高级浏览器中使用stopPropagation()方法;在IE下必须设置cancelBubble = true
#30. 事件委派
- 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件。
- 事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
- 我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的
#31. 事件绑定
- 使用 对象.事件 = 函数 的形式绑定响应函数,
- 它只能同时为一个元素的一个事件绑定一个响应函数,
- 不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
- addEventListener()
- 通过这个方法也可以为元素绑定响应函数
- 参数:
1.事件的字符串,不要on
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false - 使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,
这样当事件被触发时,响应函数将会按照函数的绑定顺序执行 - 这个方法不支持IE8及以下的浏览器
- btn01.addEventListener("click",function(){
alert(1);
},false);
- attachEvent()
- 在IE8中可以使用attachEvent()来绑定事件
- 参数:
1.事件的字符串,要on
2.回调函数 - 这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和addEventListener()相反
- 综合
定义一个函数,用来为指定元素绑定响应函数
- addEventListener()中的this,是绑定事件的对象
attachEvent()中的this,是window
需要统一两个方法this - 参数:
obj 要绑定事件的对象
eventStr 事件的字符串(不要on)
callback 回调函数 - function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏览器兼容的方式
obj.addEventListener(eventStr , callback , false);
}else{
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函数中调用回调函数,这一步是为了this能指向元素,而不是window
callback.call(obj);
});
}
}
#32. 事件传播
- 关于事件的传播网景公司和微软公司有不同的理解
- 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,
然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。 - 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,
然后在向内传播给后代元素 - W3C综合了两个公司的方案,将事件传播分成了三个阶段
1.捕获阶段- 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段 - 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段 - 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
- 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
- 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false - IE8及以下的浏览器中没有捕获阶段
#33. 拖拽事件&&滚轮事件&&键盘事件
JS源码-day16
JS源码-day17 键盘事件-移动div
#34. BOM
- 浏览器对象模型
- BOM可以使我们通过JS来操作浏览器
- 在BOM中为我们提供了一组对象,用来完成对浏览器的操作
- BOM对象
1.Window- 代表的是整个浏览器的窗口,同时window也是网页中的全局对象
2.Navigator - 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
3.Location - 代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
4.History - 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
而且该操作只在当次访问时有效
5.Screen - 代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
- 代表的是整个浏览器的窗口,同时window也是网页中的全局对象
- 这些BOM对象在浏览器中都是作为window对象的属性保存的,
可以通过window对象来使用,也可以直接使用
#35. Navigator
- 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
- 由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
- 一般我们只会使用userAgent来判断浏览器的信息,
userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,
不同的浏览器会有不同的userAgent
火狐的userAgent
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0
Chrome的userAgent
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36
IE8
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE9
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE10
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
IE11
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko - 在IE11中已经将微软和IE相关的标识都已经去除了,
所以我们基本已经不能通过UserAgent来识别一个浏览器是否是IE了 - 如果通过UserAgent不能判断,还可以通过一些浏览器中特有的对象,来判断浏览器的信息
比如:ActiveXObject - 判断手段
var ua = navigator.userAgent;
if(/firefox/i.test(ua)){
alert("你是火狐!!!");
}else if(/chrome/i.test(ua)){
alert("你是Chrome");
}else if(/msie/i.test(ua)){
alert("你是IE浏览器~~~");
}else if("ActiveXObject" in window){
alert("你是IE11,枪毙了你~~~");
}
#36. History
- 对象可以用来操作浏览器向前或向后翻页
- length
- 属性,可以获取到当成访问的链接数量
alert(history.length);
- 属性,可以获取到当成访问的链接数量
- back()
- 可以用来回退到上一个页面,作用和浏览器的回退按钮一样
history.back();
- 可以用来回退到上一个页面,作用和浏览器的回退按钮一样
- forward()
- 可以跳转下一个页面,作用和浏览器的前进按钮一样
history.forward();
- 可以跳转下一个页面,作用和浏览器的前进按钮一样
- go()
- 可以用来跳转到指定的页面
- 它需要一个整数作为参数
1:表示向前跳转一个页面 相当于forward()
2:表示向前跳转两个页面
-1:表示向后跳转一个页面
-2:表示向后跳转两个页面
#37. Location
- 该对象中封装了浏览器的地址栏的信息
- 如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
alert(location); - 如果直接将location属性修改为一个完整的路径,或相对路径
则我们页面会自动跳转到该路径,并且会生成相应的历史记录 - assign()
用来跳转到其他的页面,作用和直接修改location一样 - reload()
用于重新加载当前页面,作用和刷新按钮一样
如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面
location.reload(true);//CTRL+F5 - replace()
可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
不会生成历史记录,不能使用回退按钮回退
#38. window的时间调用功能
- setInterval()
- 定时调用
- 可以将一个函数,每隔一段时间执行一次
- 参数:
1.回调函数,该函数会每隔一段时间被调用一次
2.每次调用间隔的时间,单位是毫秒 - 返回值:返回一个Number类型的数据,这个数字用来作为定时器的唯一标识
- eg:
var timer = setInterval(function(){
count.innerHTML = num++;
},1000);
- clearInterval()
- 可以用来关闭一个定时器
- 方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
- clearInterval(timer);
- 功能
- 通过定时器解决浏览器连续按键卡顿问题 day17-06.移动div练习
- 轮播图 day17
- setTimeout 延时调用
- 延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
延时调用和定时调用实际上是可以互相代替的,在开发中可以根据自己需要去选择 - var timer = setTimeout(function(){
console.log(num++);
},3000); - 使用clearTimeout()来关闭一个延时调用
clearTimeout(timer);
#39. JSON
- JS中的对象只有JS自己认识,其他的语言都不认识,JSON的出现是为了让js和其他语言交流
- JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,
并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互 - JSON
- JavaScript Object Notation JS对象表示法
- JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号
其他的和JS语法一致 - JSON分类:
1.对象 {}
2.数组 [] - JSON中允许的值
1.字符串
2.数值
3.布尔值
4.null
5.对象
6.数组
- 将JSON字符串转换为JS中的对象
- 在JS中,为我们提供了一个工具类,就叫JSON
- 这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
- json --> js对象
- 语法:JSON.parse()
- 可以将以JSON字符串转换为js对象
- 它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
- var o = JSON.parse(json);
- JS对象 ---> JSON
- 语法:JSON.stringify()
- 可以将一个JS对象转换为JSON字符串
- 需要一个js对象作为参数,会返回一个JSON字符串
- var str = JSON.stringify(obj3);
- JSON这个对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错
如果需要兼容IE7及以下的JSON操作,则可以通过引入一个外部的js文件来处理 - eval()
- 这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
- 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块
如果不希望将其当成代码块解析,则需要在字符串前后各加一个() - eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,
但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患