s = Number(s);
- 转换的情况:
1.字符串 --> 数字
-
如果字符串是一个合法的数字,则直接转换为对应的数字
-
如果字符串是一个非法的数字,则转换为NaN
-
如果是一个空串或纯空格的字符串,则转换为0
2.布尔值 --> 数字
-
true转换为1
-
false转换为0
3.空值 --> 数字
- null转换为0
4.未定义 --> 数字
-
undefined 转换为NaN
-
方式二(强制类型转换):
-
调用parseInt()或parseFloat()
-
这两个函数专门用来将一个字符串转换为数字的
-
parseInt()
-
可以将一个字符串中的有效的整数位提取出来,并转换为Number
-
例子:
var a = “123.456px”;
a = parseInt(a); //123
- 如果需要可以在parseInt()中指定一个第二个参数,来指定进制
a = “070”;
//可以在parseInt()中传递一个第二个参数,来指定数字的进制
a = parseInt(a,10);
-
parseFloat()
-
可以将一个字符串中的有效的小数位提取出来,并转换为Number
-
例子:
var a = “123.456px”;
a = parseFloat(a); //123.456
- 如果对非String使用parseInt()或parseFloat()
它会先将其转换为String然后在操作
-
方式三(隐式的类型转换):
-
使用一元的+来进行隐式的类型转换
-
- / - 隐式转换
-
例子:
var a = “123”;
a = +a;
-
原理:和Number()函数一样
-
转换为布尔值
-
方式一(强制类型转换):
-
使用Boolean()函数
-
例子:
var s = “false”;
s = Boolean(s); //true
- 转换的情况
字符串 --> 布尔
- 除了空串其余全是true
数值 --> 布尔
- 除了0和NaN其余的全是true
null、undefined —> 布尔
- 都是false
对象 —> 布尔
-
都是true
-
方式二(隐式类型转换):
-
为任意的数据类型做两次非运算,即可将其转换为布尔值
-
例子:
var a = “hello”;
a = !!a; //true
3.运算符(算数运算符-一元运算符-逻辑运算符-赋值运算符-关系运算符-相等运算符-三元运算符)
1.运算符
-
运算符
-
运算符也称为操作符
-
通过运算符可以对一个或多个值进行运算或操作
-
typeof运算符
-
用来检查一个变量的数据类型
-
语法:typeof 变量
-
它会返回一个用于描述类型的字符串作为结果
-
算数运算符
- 对两个值进行加法运算并返回结果
- 对两个值进行减法运算并返回结果
- 对两个值进行乘法运算并返回结果
/ 对两个值进行除法运算并返回结果
% 对两个值进行取余运算并返回结果
** 次方
-
除了加法以外,对非Number类型的值进行运算时,都会先转换为Number然后在做运算。
-
而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。
-
任何值和字符串做加法,都会先转换为字符串,然后再拼串
-
一元运算符
-
一元运算符只需要一个操作数
-
一元的+
-
就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字
-
例子:
var a = true;
a = +a;
对于非Number类型的值,
它会将先转换为Number,然后在运算
可以对一个其他的数据类型使用+,来将其转换为number
它的原理和Number()函数一样
-
一元的-
-
就是负号,可以对一个数字进行符号位取反
-
例子:
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,则返回第二个值
****3.返回的不一定是布尔值,而是返回表达式结果
||
-
||可以对符号两侧的值进行或运算
-
只有两端都是false时,才会返回false。只要有一个true,就会返回true。
-
或是一个短路的或,如果第一个值是true,则不再检查第二个值
-
对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值
-
规则:
1.如果第一个值为true,则返回第一个值
2.如果第一个值为false,则返回第二个值
&& || 非布尔值的情况
-
- 与运算:
-
- 如果第一个值为true,则必然返回第二个值
-
- 如果第一个值为false,则直接返回第一个值
-
- 或运算
-
- 如果第一个值为true,则直接返回第一个值
-
- 如果第一个值为false,则返回第二个值
- 赋值运算符
=
- 可以将符号右侧的值赋值给左侧变量
+=
-
a += 5 相当于 a = a+5
-
var str = “hello”; str += “world”;
-=
- a -= 5 相当于 a = a-5
*=
- a = 5 相当于 a = a5
/=
- a /= 5 相当于 a = a/5
%=
-
a %= 5 相当于 a = a%5
-
关系运算符
-
关系运算符用来比较两个值之间的大小关系的
=
<
<=
- 关系运算符的规则和数学中一致,用来比较两个值之间的关系,
如果关系成立则返回true,关系不成立则返回false。
- 如果比较的两个值是非数值,会将其转换为Number然后再比较。
任何值和NaN做任何比较都是false
- 如果比较的两个值都是字符串,此时会比较字符串的Unicode编码,而不会转换为Number。
比较字符编码时是一位一位进行比较
如果两位一样,则比较下一位,所以借用它来对英文进行排序
比较中文时没有意义
如果比较的两个字符串型的数字,可能会得到不可预期的结果
********注意:在比较两个字符串型的数字时,一定一定一定要转型
- 相等运算符
==
-
相等,判断左右两个值是否相等,如果相等返回true,如果不等返回false
-
相等会自动对两个值进行类型转换,如果对不同的类型进行比较,会将其转换为相同的类型然后再比较,
转换后相等它也会返回true
!=
-
不等,判断左右两个值是否不等,如果不等则返回true,如果相等则返回false
-
不等也会做自动的类型转换。
===
- 全等,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换,
如果两个值的类型不同,则直接返回false
!==
- 不全等,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回true
特殊的值:
-
null和undefined
-
由于undefined衍生自null,所以null == undefined 会返回true。
但是 null === undefined 会返回false。
0 != null 0!= undefined
-
NaN
-
NaN不与任何值相等,报告它自身 NaN == NaN //false
-
判断一个值是否是NaN
-
使用isNaN()函数
-
三元运算符:
?:
-
语法:条件表达式?语句1:语句2;
-
执行流程:
先对条件表达式求值判断,
如果判断结果为true,则执行语句1,并返回执行结果
如果判断结果为false,则执行语句2,并返回执行结果
-
优先级:
-
和数学中一样,JS中的运算符也是具有优先级的,
比如 先乘除 后加减 先与 后或
- 具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高,
优先级越高的越优先计算,优先级相同的,从左往右计算。
- 优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。
4.html页面和 js使用 Unicode编码
☠
⚀
5.语句 代码块
语句
前边我所说表达式和运算符等内容可以理解成是我们一门语言中的单词,短语。
而语句(statement)就是我们这个语言中一句一句完整的话了。
语句是一个程序的基本单位,JS的程序就是由一条一条语句构成的,每一条语句使用;结尾。
JS中的语句默认是由上至下顺序执行的,但是我们也可以通过一些流程控制语句来控制语句的执行顺序。
代码块
代码块是在大括号 {} 中所写的语句,以此将多条语句的集合视为一条语句来使用。
例如:
{
var a = 123;
a++;
alert(a);
}
我们一般使用代码块将需要一起执行的语句进行分组,需要注意的是,代码块结尾不需要加分号。
es6语法 , let const 变量在代码块里只有局部作用,外面的代码看不到代码块内的let 变量
6. 流程控制语句(if-else if-else ;switch-case; while; do-while;for)
补充知识点
prompt()可以弹出一个提示框,该提示框中会带有一个文本框,
用户可以在文本框中输入一段内容,该函数需要一个字符串作为参数,
该字符串将会作为提示框的提示文字
用户输入的内容将会作为函数的返回值返回,可以定义一个变量来接收该内容
1.流程控制语句
- 程序都是自上向下的顺序执行的,
通过流程控制语句可以改变程序执行的顺序,或者反复的执行某一段的程序。
- 分类:
1.条件判断语句
2.条件分支语句
3.循环语句
条件判断语句
-
条件判断语句也称为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后的语句
1.条件分支语句
-
switch语句
-
语法:
-
这里需要与 case 全等 ===
switch(条件表达式){
case 表达式:
语句…
break;
case 表达式:
语句…
break;
case 表达式:
语句…
break;
default:
语句…
break;
}
-
执行流程:
-
switch…case…语句在执行时,会依次将case后的表达式的值和switch后的表达式的值进行全等比较,
如果比较结果为false,则继续向下比较。如果比较结果为true,则从当前case处开始向下执行代码。
如果所有的case判断结果都为false,则从default处开始执行代码。
2.循环语句
-
通过循环语句可以反复执行某些语句多次
-
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(;😉{
}
1.break-continue
break关键字可以用来退出switch或循环语句
不能在if语句中使用break和continue
break关键字,会立即终止离他最近的那个循环语句
可以为循环语句创建一个label,来标识当前的循环
label:循环语句
使用break语句时,可以在break后跟着一个label,
这样break将会结束指定的循环,而不是最近的
continue关键字可以用来跳过当次循环
同样continue也是默认只会对离他最近的循环循环起作用
continue 也能配合label使用
2.补充 程序计时-开方
console.time(“计时器的名字”)可以用来开启一个计时器
它需要一个字符串作为参数,这个字符串将会作为计时器的标识
console.timeEnd()用来停止一个计时器,需要一个计时器的名字作为参数
例如:
console.time(“test”);
console.timeEnd(“test”);
可以通过Math.sqrt()对一个数进行开方
7.对象
对象分类
1.内建对象
-
由ES标准中定义的对象,在任何的ES的实现中都可以使用
-
比如:Math String Number Boolean Function Object…
2.宿主对象
-
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
-
比如 BOM DOM
3.自定义对象
- 由开发人员自己创建的对象
1.对象(Object)
-
对象是JS中的引用数据类型
-
对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性
-
使用typeof检查一个对象时,会返回object
-
创建对象
-
方式一:
-
var obj = new Object();
-
方式二:使用对象字面量
-
var obj = {};
-
向对象中添加属性
-
语法:
对象.属性名 = 属性值;
对象[“属性名”] = 属性值;
- 对象的属性名没有任何要求,不需要遵守标识符的规范,
但是在开发中,尽量按照标识符的要求去写。
-
属性值也可以任意的数据类型。
-
读取对象中的属性
-
语法:
对象.属性名
对象[“属性名”]
-
如果读取一个对象中没有的属性,它不会报错,而是返回一个undefined
-
删除对象中的属性
-
语法:
delete 对象.属性名
delete 对象[“属性名”]
-
使用in检查对象中是否含有指定属性
-
语法:“属性名” in 对象
-
如果在对象中含有该属性,则返回true
如果没有则返回false
- 使用对象字面量,在创建对象时直接向对象中添加属性
语法:
var obj = {
属性名:属性值,
属性名:属性值,
属性名:属性值,
属性名:属性值
}
- 使用工厂方法创建对象 通过该方法可以大批量的创建对象
使用工厂方法创建的对象,使用的构造函数都是Object
就导致我们无法区分出多种不同类型的对象,后面用构造函数解决
function createPerson(name , age ,gender){
//创建一个新的对象
var obj = new Object();
//向对象中添加属性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
};
//将新的对象返回
return obj;
}
-
基本数据类型和引用数据类型
-
基本数据类型
String Number Boolean Null Undefined
- 引用数据类型
Object
- 基本数据类型的数据,变量是直接保存的它的值。
变量与变量之间是互相独立的,修改一个变量不会影响其他的变量。
- 引用数据类型的数据,变量是保存的对象的引用(内存地址)。
如果多个变量指向的是同一个对象,此时修改一个变量的属性,会影响其他的变量。
- 比较两个变量时,对于基本数据类型,比较的就是值,
对于引用数据类型比较的是地址,地址相同才相同
8.函数
1.函数(Function)
-
函数也是一个对象,也具有普通对象的功能
-
函数中可以封装一些代码,在需要的时候可以去调用函数来执行这些代码
-
使用typeof检查一个函数时会返回function
-
创建函数
-
构造函数
//我们在实际开发中很少使用构造函数来创建一个函数对象
//创建一个函数对象
//可以将要封装的代码以字符串的形式传递给构造函数
//var fun = new Function(“console.log(‘Hello 这是我的第一个函数’);”);
- 函数声明
function 函数名([形参1,形参2…形参N]){
语句…
}
- 函数表达式
var 函数名 = function([形参1,形参2…形参N]){
语句…
//这是匿名函数 function 后面没有函数名
};
-
调用函数
-
语法:函数对象([实参1,实参2…实参N]);
fun() sum() alert() Number() parseInt()
-
当我们调用函数时,函数中封装的代码会按照编写的顺序执行
-
形参和实参
-
形参:形式参数
-
定义函数时,可以在()中定义一个或多个形参,形参之间使用,隔开
定义形参就相当于在函数内声明了对应的变量但是并不赋值,
形参会在调用时才赋值。
-
实参:实际参数
-
调用函数时,可以在()传递实参,传递的实参会赋值给对应的形参,
调用函数时JS解析器不会检查实参的类型和个数,可以传递任意数据类型的值。
如果实参的数量大于形参,多余实参将不会赋值,
如果实参的数量小于形参,则没有对应实参的形参将会赋值undefined
-
返回值,就是函数执行的结果。
-
使用return 来设置函数的返回值。
-
语法:return 值;
-
该值就会成为函数的返回值,可以通过一个变量来接收返回值
-
return后边的代码都不会执行,一旦执行到return语句时,函数将会立刻退出。
-
return后可以跟任意类型的值,可以是基本数据类型,也可以是一个对象。
-
如果return后不跟值,或者是不写return则函数默认返回undefined。
-
break、continue和return
-
break
-
退出循环
-
continue
-
跳过当次循环
-
return
-
退出函数
-
参数,函数的实参也可以是任意的数据类型。
-
方法(method)
-
可以将一个函数设置为一个对象的属性,
当一个对象的属性是一个函数时,
我们称这个函数是该对象的方法。
-
对象.方法名();
-
函数名();
补充 立即执行函数
/*
-
立即执行函数
-
函数定义完,立即被调用,这种函数叫做立即执行函数
-
立即执行函数往往只会执行一次
*/
(function () {
alert(“我是一个匿名函数~~~”);
})();
(function (a, b) {
console.log("a = " + a);
console.log("b = " + b);
})(123, 456);
(function () {
alert(“我是一个匿名函数~~~”);
}());
(function (a, b) {
console.log("a = " + a);
console.log("b = " + b);
}(123, 456));
9.作用域
作用域
-
作用域简单来说就是一个变量的作用范围。
-
在JS中作用域分成两种:
1.全局作用域
-
直接在script标签中编写的代码都运行在全局作用域中
-
全局作用域在打开页面时创建,在页面关闭时销毁。
-
全局作用域中有一个全局对象window,window对象由浏览器提供,
可以在页面中直接使用,它代表的是整个的浏览器的窗口。
- 在全局作用域中创建的变量都会作为window对象的属性保存
在全局作用域中创建的函数都会作为window对象的方法保存
- 在全局作用域中创建的变量和函数可以在页面的任意位置访问。
在函数作用域中也可以访问到全局作用域的变量。
- 尽量不要在全局中创建变量
2.函数作用域
-
函数作用域是函数执行时创建的作用域,每次调用函数都会创建一个新的函数作用域。
-
函数作用域在函数执行时创建,在函数执行结束时销毁。
-
在函数作用域中创建的变量,不能在全局中访问。
-
当在函数作用域中使用一个变量时,它会先在自身作用域中寻找,
如果找到了则直接使用,如果没有找到则到上一级作用域中寻找,
如果找到了则使用,找不到则继续向上找,一直会
-
变量的声明提前
-
在全局作用域中,使用var关键字声明的变量会在所有的代码执行之前被声明,但是不会赋值。
所以我们可以在变量声明前使用变量。但是不使用var关键字声明的变量不会被声明提前。
- 在函数作用域中,也具有该特性,使用var关键字声明的变量会在函数所有的代码执行前被声明,
****如果没有使用var关键字声明变量,则变量会变成全局变量,不使用var关键字声明的变量不会被声明提前。
-
函数的声明提前
-
在全局作用域中,使用函数声明创建的函数(function fun(){}),会在所有的代码执行之前被创建,
也就是我们可以在函数声明前去调用函数,但是使用函数表达式(var fun = function(){})创建的函数没有该特性
- 在函数作用域中,使用函数声明创建的函数,会在所有的函数中的代码执行之前就被创建好了。
10.this(上下文对象)
- 我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。
使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。
- this的不同的情况:
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this就是调用方法的对象
3.以构造函数的形式调用时,this就是新创建的对象
4.使用call和apply调用时,this是指定的那个对象
5.在全局作用域中this代表window
目前以我自己知识量对this指向的总结
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this就是调用方法的对象
3.以构造函数的形式调用时,this就是新创建的对象
函数箭头函数没有自己的this对象,看他所在作用域的this。
bind 可以绑定 普通函数的this对象,不可以绑定箭头函数的
箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。
普通函数只有作为某对象方法时,内部this是这个对象,其余全是window ,构造函数作为普通函数使用 this 指向 window
构造函数new方式使用,this就是新创建的对象。
如下代码 输出的this 指向 window
var test = {
id: 1,
fun: function (fun1) {
fun1()
}
}
var obj = {
id: 2,
fun: function () {
test.fun(function () { console.log(this); })
}
}
obj.fun()
补充:
4.使用call和apply调用时,this是指定的那个对象,不可以改变箭头函数的this指向
5.在全局作用域中this代表window
-
call()
-
apply()
-
这两个方法都是函数对象的方法需要通过函数对象来调用
-
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
-
不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递
-
call()方法可以将实参在对象之后依次传递
-
apply()方法需要将实参封装到一个数组中统一传递
11.构造函数
-
构造函数是专门用来创建对象的函数
-
一个构造函数我们也可以称为一个类
-
通过一个构造函数创建的对象,我们称该对象时这个构造函数的实例
-
通过同一个构造函数创建的对象,我们称为一类对象
-
构造函数就是一个普通的函数,只是他的调用方式不同,
如果直接调用,它就是一个普通函数
如果使用new来调用,则它就是一个构造函数
- 例子:
function Person(){
}
- 构造函数的执行流程:
1.创建一个新的对象
2.将新的对象作为函数的上下文对象(this)
3.执行函数中的代码
4.将新建的对象返回
-
instanceof 用来检查一个对象是否是一个类的实例
-
语法:对象 instanceof 构造函数
-
如果该对象时构造函数的实例,则返回true,否则返回false
-
Object是所有对象的祖先,所以任何对象和Object做instanceof都会返回true
/*
-
创建一个Person构造函数
-
- 在Person构造函数中,为每一个对象都添加了一个sayName方法,
-
目前我们的方法是在构造函数内部创建的,
-
也就是构造函数每执行一次就会创建一个新的sayName方法
-
也是所有实例的sayName都是唯一的。
-
这样就导致了构造函数执行一次就会创建一个新的方法,
-
执行10000次就会创建10000个新的方法,而10000个方法都是一摸一样的
-
这是完全没有必要,完全可以使所有的对象共享同一个方法
*/
function Person(name , age , gender){
this.name = name;
this.age = age;
this.gender = gender;
//向对象中添加一个方法
this.sayName = function(){
alert(“Hello大家好,我是:”+this.name);
}
}
//将sayName方法在全局作用域中定义
/*
-
将函数定义在全局作用域,污染了全局作用域的命名空间
-
而且定义在全局作用域中也很不安全
*/
function Person(name , age , gender){
this.name = name;
this.age = age;
this.gender = gender;
//向对象中添加一个方法
this.sayName = fun;
}
function fun(){
alert(“Hello大家好,我是:”+this.name);
};
//向原型中添加sayName方法 √
Person.prototype.sayName = function(){
alert(“Hello大家好,我是:”+this.name);
};
1.枚举对象中的属性
for…in
语法:
for(var 属性名 in 对象){
}
for…in语句的循环体会执行多次,对象中有几个属性就会执行几次(包括自己在构造函数在原型对象中添加的属性),
每次将一个属性名赋值给我们定义的变量,我们可以通过它来获取对象中的属性
如果是数组,对应的属性名是从0开始的索引
for…of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句
12.原型
1.原型(prototype)
- 创建一个函数以后,解析器都会默认在函数中添加一个数prototype
prototype属性指向的是一个对象,这个对象我们称为原型对象。
如果函数作为普通函数调用prototype没有任何作用
- 当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,
指向该构造函数的原型对象,我们可以通过__proto__来访问该属性
- 原型对象就相当于一个公共的区域,凡是通过同一个构造函数创建的对象他们通常都可以访问到相同的原型对象。
我们可以将对象中共有的属性和方法统一添加到原型对象中,
这样我们只需要添加一次,就可以使所有的对象都可以使用。
- 当我们去访问对象的一个属性或调用对象的一个方法时,它会先自身中寻找,
如果在自身中找到了,则直接使用。
如果没有找到,则去原型对象中寻找,如果找到了则使用,
如果没有找到,则去原型的原型中寻找,依此类推。直到找到Object的原型为止,Object的原型的原型为null,
如果依然没有找到则返回undefined
- 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,
这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了
-
hasOwnProperty()
-
这个方法可以用来检查对象自身中是否含有某个属性(原型身上的不算)
-
语法:对象.hasOwnProperty(“属性名”)
1.补充 toString
当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值
如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法
一般加在构造函数prototype上
2.垃圾回收(GC)
- 就像人生活的时间长了会产生垃圾一样,程序运行过程中也会产生垃圾
这些垃圾积攒过多以后,会导致程序运行的速度过慢,
所以我们需要一个垃圾回收的机制,来处理程序运行过程中产生垃圾
- 当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
所以这种垃圾必须进行清理。
- 在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
我们不需要也不能进行垃圾回收的操作
- 我们需要做的只是要将不再使用的对象设置null即可
13.数组
数组(Array)
- 数组也是一个对象,是一个用来存储数据的对象
和Object类似,但是它的存储效率比普通对象要高
数组中的元素可以是任意的数据类型
数组中也可以放数组,生成多维数组
-
数组中保存的内容我们称为元素
-
数组使用索引(index)来操作元素
-
索引指由0开始的整数
-
数组的操作:
-
创建数组
-
var arr = new Array();
-
var arr = [];
-
向数组中添加元素
-
语法;
数组对象[索引] = 值;
arr[0] = 123;
arr[1] = “hello”;
-
创建数组时直接添加元素
-
语法:
var arr = [元素1,元素2…元素N];
var arr = new Array(1, ‘a’, null);
new Array(3) 创建长度为3的空数组
- 例子:
var arr = [123,“hello”,true,null];
-
获取和修改数组的长度
-
使用length属性来操作数组的长度
-
获取长度:
数组.length
-
length获取到的是数组的最大索引+1
-
对于连续的数组,length获取到的就是数组中元素的个数
-
修改数组的长度
数组.length = 新长度
-
如果修改后的length大于原长度,则多出的部分会空出来
-
如果修改后的length小于原长度,则原数组中多出的元素会被删除
-
向数组的最后添加元素
数组[数组.length] = 值;
-
数组的方法
-
push()
-
用来向数组的末尾添加一个或多个元素,并返回数组新的长度
-
语法:数组.push(元素1,元素2,元素N)
-
pop()
-
用来删除数组的最后一个元素,并返回被删除的元素
-
unshift()
-
向数组的前边添加一个或多个元素,并返回数组的新的长度
-
shift()
-
删除数组的前边的一个元素,并返回被删除的元素
-
slice()
-
可以从一个数组中截取指定的元素
-
该方法不会影响原数组,而是将截取到的内容封装为一个新的数组并返回
-
参数:
1.截取开始位置的索引(包括开始位置)
2.截取结束位置的索引(不包括结束位置)
-
第二个参数可以省略不写,如果不写则一直截取到最后
-
参数可以传递一个负值,如果是负值,则从后往前数
-
splice()
-
可以用来删除数组中指定元素,并使用新的元素替换
该方法会将删除的元素封装到新数组中返回
- 参数:
1.删除开始位置的索引
2.删除的个数
3.三个以后,都是替换的元素,这些元素将会插入到开始位置索引的前边
-
遍历数组
-
遍历数组就是将数组中元素都获取到
-
一般情况我们都是使用for循环来遍历数组:
for(var i=0 ; i<数组.length ; i++){
//数组[i]
}
- 使用forEach()方法来遍历数组(不兼容IE8)
数组.forEach(function(value , index , obj){
});
forEach()方法需要一个回调函数作为参数,
数组中有几个元素,回调函数就会被调用几次,
每次调用时,都会将遍历到的信息以实参的形式传递进来,
我们可以定义形参来获取这些信息。
value:正在遍历的元素
index:正在遍历元素的索引
obj:被遍历对象
14.数组方法
reverse()
- reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组。
concat()
- 可以连接两个或多个数组,它不会影响原数组,而是新数组作为返回值返回
该方法不会对原数组产生影响
join()
-
可以将一个数组转换为一个字符串
-
参数:
需要一个字符串作为参数,这个字符串将会作为连接符来连接数组中的元素
如果不指定连接符则默认使用’,’
sort()
- 可以对一个数组中的内容进行排序,默认是按照’Unicode编码’进行排序
调用以后,会直接修改原数组。
-
即使数组是数字数组,也默认Unicode 编码排序
-
可以自己指定排序的规则,需要一个回调函数作为参数:
function(a,b){
//升序排列
//return a-b;
//降序排列
return b-a;
}
| 方法 | 描述 |
| :-- | :-- |
| push() | 将新元素添加到数组的末尾,并返回新的长度。 |
| pop() | 删除数组的最后一个元素,并返回该元素。 |
| shift() | 删除数组的第一个元素,并返回该元素。 |
| unshift() | 将新元素添加到数组的开头,并返回新的长度。 |
| forEach() | 为每个数组元素调用函数。 |
| slice() | 选择数组的一部分,并返回新数组。 |
| splice() | 从数组中添加/删除元素。 |
| concat() | 连接两个或多个数组,并返回已连接数组的副本。 |
| reverse() | 反转数组中元素的顺序。 |
| join() | 将数组的所有元素连接成一个字符串。 |
| sort() | 对数组的元素进行排序。 |
| copyWithin() | 将数组中的数组元素复制到指定位置或从指定位置复制。 |
| entries() | 返回键/值对数组迭代对象。 |
| every() | 检查数组中的每个元素是否通过测试。 |
| fill() | 用静态值填充数组中的元素。 |
| filter() | 使用数组中通过测试的每个元素创建新数组。 |
| find() | 返回数组中第一个通过测试的元素的值。 |
| findIndex() | 返回数组中通过测试的第一个元素的索引。 |
| from() | 从对象创建数组。 |
| includes() | 检查数组是否包含指定的元素。 |
| indexOf() | 在数组中搜索元素并返回其位置。 |
| isArray() | 检查对象是否为数组。 |
| keys() | 返回 Array Iteration 对象,包含原始数组的键. |
| lastIndexOf() | 在数组中搜索元素,从末尾开始,并返回其位置。 |
| map() | 使用为每个数组元素调用函数的结果创建新数组。 |
| reduce() | 将数组的值减为单个值(从左到右)。 |
| reduceRight() | 将数组的值减为单个值(从右到左)。 |
| some() | 检查数组中的任何元素是否通过测试。 |
| toString() | 将数组转换为字符串,并返回结果。 |
| valueOf() | 返回数组的原始值。 |
15.函数方法call-apply-arguments[callee]
-
call()
-
apply()
-
这两个方法都是函数对象的方法需要通过函数对象来调用
-
通过两个方法可以直接调用函数,并且可以通过第一个实参来指定函数中this
-
不同的是call是直接传递函数的实参而apply需要将实参封装到一个数组中传递
-
call()方法可以将实参在对象之后依次传递
-
apply()方法需要将实参封装到一个数组中统一传递
-
arguments
-
arguments和this类似,都是函数中的隐含的参数
-
arguments是一个类数组元素,它用来封装函数执行过程中的实参
所以即使不定义形参,也可以通过arguments来使用实参
- arguments中有一个属性callee表示当前执行的函数对象
1.补充:闭包
闭包(closure)
- 闭包是JS一个非常重要的特性,这意味着当前作用域总是能够访问外部作用域中的
变量。因为函数是JS中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。
- 也可以将闭包的特征理解为,其相关的局部变量在函数调用结束之后将会继续存在。
16.包装类
- 在JS中为我们提供了三个包装类:
String() Boolean() Number()
- 通过这三个包装类可以创建基本数据类型的对象
例子:
var num = new Number(2);
var str = new String(“hello”);
var bool = new Boolean(true);
-
但是在实际应用中千万不要这么干。
-
当我们去操作一个基本数据类型的属性和方法时,
解析器会临时将其转换为对应的包装类,然后再去操作属性和方法,
操作完成以后再将这个临时对象进行销毁。
17.字符串的相关的方法
在底层字符串是以字符数组的形式保存的
//console.log(str.length);
//console.log(str[5]);
length
- 获取字符串的长度
charAt()
- 根据索引获取指定的字符
charCodeAt()
- 根据索引获取指定的字符编码
String.fromCharCode()
- 根据字符编码获取字符
concat()
-
可以用来连接两个或多个字符串
-
作用和+一样
indexOf()
lastIndexOf()
-
从一个字符串中检索指定内容
-
需要一个字符串作为参数,这个字符串就是要检索的内容,
如果找到该内容,则会返回其第一次出现的索引,如果没有找到则返回-1。
-
可以指定一个第二个参数,来表示开始查找的位置 ,不能指定负数
-
indexOf()是从前向后找
-
lastIndexOf()是从后向前找
slice()
-
可以从一个字符串中截取指定的内容,并将截取到内容返回,不会影响原变量
-
参数:
第一个:截取开始的位置(包括开始)
第二个:截取结束的位置(不包括结束)
-
可以省略第二个参数,如果省略则一直截取到最后
-
可以传负数,如果是负数则从后往前数
substr()
- 和slice()基本一致,不同的是它第二个参数不是索引,而是截取的数量
substring()
- 和slice()基本一致,不同的是它不能接受负值作为参数,如果设置一个负值,则会自动修正为0,
substring()中如果第二个参数小于第一个,自动调整位置
toLowerCase() toLocaleLowerCase()
- 将字符串转换为小写并返回
toUpperCase() toLocaleUpperCase()
- 将字符串转换为大写并返回
split()
-
可以根据指定内容将一个字符串拆分为一个数组
-
参数:
-
需要一个字符串作为参数,将会根据字符串去拆分数组
可以接收一个正则表达式,此时会根据正则表达式去拆分数组
| 方法 | 描述 |
| :-- | :-- |
| anchor() | 创建 HTML 锚。 |
| big() | 用大号字体显示字符串。 |
| blink() | 显示闪动字符串。 |
| bold() | 使用粗体显示字符串。 |
| charAt() | 返回在指定位置的字符。 |
| charCodeAt() | 返回在指定的位置的字符的 Unicode 编码。 |
| concat() | 连接字符串。 |
| fixed() | 以打字机文本显示字符串。 |
| fontcolor() | 使用指定的颜色来显示字符串。 |
| fontsize() | 使用指定的尺寸来显示字符串。 |
| fromCharCode() | 从字符编码创建一个字符串。 |
| indexOf() | 检索字符串。 |
| italics() | 使用斜体显示字符串。 |
| lastIndexOf() | 从后向前搜索字符串。 |
| link() | 将字符串显示为链接。 |
| localeCompare() | 用本地特定的顺序来比较两个字符串。 |
| match() | 找到一个或多个正则表达式的匹配。 |
| replace() | 替换与正则表达式匹配的子串。 |
| search() | 检索与正则表达式相匹配的值。 |
| slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分。 |
| small() | 使用小字号来显示字符串。 |
| split() | 把字符串分割为字符串数组。 |
| strike() | 使用删除线来显示字符串。 |
| sub() | 把字符串显示为下标。 |
| substr() | 从起始索引号提取字符串中指定数目的字符。 |
| substring() | 提取字符串中两个指定的索引号之间的字符。 |
| sup() | 把字符串显示为上标。 |
| toLocaleLowerCase() | 把字符串转换为小写。 |
| toLocaleUpperCase() | 把字符串转换为大写。 |
| toLowerCase() | 把字符串转换为小写。 |
| toUpperCase() | 把字符串转换为大写。 |
| toSource() | 代表对象的源代码。 |
| toString() | 返回字符串。 |
| valueOf() | 返回某个字符串对象的原始值。 |
18.正则表达式
| 方法 | 描述 |
| :-- | :-- |
| exec
| 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(只有索引为零的值)(未匹配到则返回 null)【一次查一个 迭代使用】。 |
| test
| 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。 |
| match
| 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。 |
| matchAll
| 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。 |
| search
| 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
| replace
| 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
| split
| 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String
方法。 |
- 正则用来定义一些字符串的规则,程序可以根据这些规则来判断一个字符串是否符合规则,
也可以将一个字符串中符合规则的内容提取出来。
-
创建正则表达式
-
var reg = new RegExp(“正则”,“匹配模式”);
-
var reg = /正则表达式/匹配模式
下面这是两两等价 注意一下
var reg = /./
var reg = RegExp(‘\.’)
var reg = /\/
var reg = RegExp(‘\\’)
- 语法:
匹配模式:
i:忽略大小写
g:全局匹配模式
- 设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求
正则语法
| 或
[] 或
[^ ] 除了
[a-z] 小写字母
[A-Z] 大写字母
[A-z] 任意字母
[0-9] 任意数字
-
语法:
-
量词
{n} 正好n次
{m,n} m-n次
{m,} 至少m次
- 至少1次 {1,}
? 0次或1次 {0,1}
- 0次或多次 {0,}
- 转义字符
\ 在正则表达式中使用\作为转义字符
. 表示.
\ 表示\
. 表示任意字符
\w
- 相当于[A-z0-9_]
\W
- 相当于[^A-z0-9_]
\d
- 任意数字
\D
- 除了数字
\s
- 空格
\S
- 除了空格
\b
- 单词边界
下列都有/\bword\b/
‘word’ ‘#word%’
下列无/\bword\b/
‘_word’ ‘1word’
边界不能为 \w 相当于[A-z0-9_]
\B
- 除了单词边界
^ 表示开始
$ 表示结束
- 方法:
test()
-
可以用来检查一个字符串是否符合正则表达式
-
如果符合返回true,否则返回false
match()
-
可以将字符串中和正则表达式匹配的内容提取出来
-
默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
以为一个正则表达式设置多个匹配模式,且顺序无所谓
-
match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
-
参数:
-
正则表达式,可以根据该正则表达式将字符串中符合要求的内容提取出来
并且封装到一个数组中返回
replace()
-
可以将字符串中指定内容替换为新的内容
-
参数:
-
第一个:被替换的内容,可以是一个正则表达式
-
第二个:替换的新内容
-
默认只会替换第一个 ,可以设置为全局匹配
search()
-
可以根据正则表达式去字符串中查找指定的内容
-
可以搜索字符串中是否含有指定内容
-
参数:
正则表达式(也可以为字符串,但是有indexOf),将会根据该表达式查询内容,
并且将第一个匹配到的内容的索引返回,如果没有匹配到任何内容,则返回-1。
split()
-
可以根据指定内容将一个字符串拆分为一个数组
-
参数:
-
需要一个字符串作为参数,将会根据字符串去拆分数组
可以接收一个正则表达式,此时会根据正则表达式去拆分数组
这个方法即使不指定全局匹配,也会全都插分
19.Date
-
日期的对象,在JS中通过Date对象来表示一个时间
-
创建对象
-
创建一个当前的时间对象
var d = new Date();
- 创建一个指定的时间对象
var d = new Date(“月/日/年 时:分:秒”);
- 方法:
getDate()
- 当前日期对象是几日(1-31)
getDay()
-
返回当前日期对象时周几(0-6)
-
0 周日
-
1 周一 。。。
getMonth()
-
返回当前日期对象的月份(0-11)
-
0 一月 1 二月 。。。
getFullYear() 从 Date 对象以四位数字返回年份。
getHours() 返回 Date 对象的小时 (0 ~ 23)。
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
getTime()
-
返回当前日期对象的时间戳
-
时间戳,指的是从1970年1月1日 0时0分0秒,到现在时间的毫秒数
计算机底层保存时间都是以时间戳的形式保存的。
Date.now()
- 可以获取当前代码执行时的时间戳
20.Math
- Math属于一个工具类,它不需要我们创建对象,它里边封装了属性运算相关的常量和方法
我们可以直接使用它来进行数学运算相关的操作
- 方法:
Math.PI
- 常量,圆周率
Math.abs()
- 绝对值运算
Math.ceil()
- 向上取整
Math.floor()
- 向下取整
Math.round()
- 四舍五入取整
Math.random()
-
生成一个0-1之间的随机数 没有0和1
-
生成一个x-y之间的随机整数
Math.floor(Math.random()*(y+1-x)+x);
Math.pow(x,y)
-
求x的y次幂
-
x ** y
Math.sqrt()
- 对一个数进行开方
Math.max()
- 求多个数中最大值
Math.min()
- 求多个数中的最小值
21.JSON
IE7及以下的浏览器的JSON字符串转为对象格式
1.什么是DOM
-
DOM,全称Document Object Model文档对象模型。
-
JS中通过DOM来对HTML文档进行操作。只要理解了DOM就可以随心所欲的操作WEB页面。
-
文档
– 文档表示的就是整个的HTML网页文档
- 对象
– 对象表示将网页中的每一个部分都转换为了一个对象。
-
转换完对象以后,就可以以一种纯面向对象的形式来操作网页了
-
模型
– 使用模型来表示对象之间的关系,这样方便我们获取对象。
2.节点
-
节点Node,是构成我们网页的最基本的组成部分,网页中每一个部分都可以称为是一个节点。
-
比如:html标签、属性、文本、注释、整个文档等都是一个节点。
-
虽然都是节点,但是实际上他们的具体类型是不同的。
-
比如:标签我们称为元素节点、属性称为属性节点、文本称为文本节点、文档称为文档节点。
-
节点的类型不同,属性和方法也都不尽相同。
节点的属性
文档节点(document)
-
文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。
-
document对象作为window对象的属性存在的,我们不用获取可以直接使用。
-
通过该对象我们可以在整个文档访问内查找节点对象,并可以通过该对象创建各种节点对象。
元素节点(Element)
-
HTML中的各种标签都是元素节点,这也是我们最常用的一个节点。
-
浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。
-
比如:
– document.getElementById()
– 根据id属性值获取一个元素节点对象。
文本节点(Text)
-
文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。
-
它包括可以字面解释的纯文本内容。
-
文本节点一般是作为元素节点的子节点存在的。
-
获取文本节点时,一般先要获取元素节点。在通过元素节点获取文本节点。
-
例如:
– 元素节点.firstChild;
– 获取元素节点的第一个子节点,一般为文本节点
属性节点(Attr
)
-
属性节点表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
-
可以通过元素节点来获取指定的属性节点。
-
例如:
– 元素节点.getAttributeNode("属性名");
注意:我们一般不使用属性节点。
3.事件
-
事件,就是文档或浏览器窗口中发生的一些特定的交互瞬间。
-
JavaScript 与 HTML 之间的交互是通过事件实现的。
-
对于 Web 应用来说,有下面这些代表性的事件:点击某个元素、将鼠标移动至某个元素上方、按下键盘上某个键,等等。
4.获取节点
获取元素节点 – 通过document对象调用
getElementById()
– 通过id属性获取一个元素节点对象
getElementsByTagName()
– 通过标签名获取一组元素节点对象
getElementsByName()
只有document有
– 通过name属性获取一组元素节点对象
getElementsByClassName()
-
DOM操作
-
DOM查询
-
在网页中浏览器已经为我们提供了document对象,
它代表的是整个网页,它是window对象的属性,可以在页面中直接使用。
-
document查询方法:
-
根据元素的id属性查询一个元素节点对象:
-
document.getElementById(“id属性值”);
-
根据元素的name属性值查询一组元素节点对象:
-
document.getElementsByName(“name属性值”);
-
根据标签名来查询一组元素节点对象:
-
document.getElementsByTagName(“标签名”);
获取元素节点的子节点 – 通过具体的元素节点调用
getElementsByTagName()
– 方法,返回当前节点的指定标签名后代节点
getElementsByClassName
– 方法,返回当前节点的指定类名后代节点
childNodes
– 属性,表示当前节点的所有子节点
firstChild
– 属性,表示当前节点的第一个子节点
firstElementChild
– 属性,表示当前节点的第一个元素子节点
lastChild
– 属性,表示当前节点的最后一个子节点
lastElementChild
– 属性,表示当前节点的最后一个元素子节点
children
– 获取当前元素的所有子元素
- 可以通过元素节点来获取指定的属性节点。
– 元素节点.getAttributeNode("属性名");
注意:我们一般不使用属性节点。
获取父节点和兄弟节点 – 通过具体的节点调用
parentNode
– 属性,表示当前节点的父节点
previousSibling
– 属性,表示当前节点的前一个兄弟节点
previousElementSibling
– 属性,表示当前节点的前一个兄弟节点
nextSibling
– 属性,表示当前节点的后一个元素兄弟节点
nextElementSibling
– 属性,表示当前节点的后一个元素兄弟节点
元素节点的属性
-
获取,元素对象.属性名
-
注意 属性
class
在js
里面是className
例:
element.value
element.id
element.className
- 设置,元素对象.属性名=新的值
例:
element.value = “hello”
element.id = “id01”
element.className = “newClass”
nodeValue
-innerHTML
-innerText
nodeValue
– 文本节点可以通过nodeValue
属性获取和设置文本节点的内容
innerHTML
– 元素节点通过该属性获取和设置标签内部的html
代码
innerHTML和innerText
-
这两个属性并没有在DOM标准定义,但是大部分浏览器都支持这两个属性
-
两个属性作用类似,都可以获取到标签内部的内容,
不同是innerHTML会获取到html标签,而innerText会自动去除标签
- 如果使用这两个属性来设置标签内部的内容时,没有任何区别的
读取标签内部的文本内容
h1中的文本内容
元素.firstChild.nodeValue
其他属性
- document对象的其他的属性和方法
document.all
- 获取页面中的所有元素,相当于document.getElementsByTagName(“*”);
document.documentElement
- 获取页面中html根元素
document.body
- 获取页面中的body元素
document.getElementsByClassName()
-
根据元素的class属性值查询一组元素节点对象
-
这个方法不支持IE8及以下的浏览器
使用CSS选择器进行查询
-
querySelector()
-
querySelectorAll()
-
这两个方法都是用document对象来调用,两个方法使用相同,都是传递一个选择器字符串作为参数,方法会自动根据选择器字符串去网页中查找元素。
-
不同的地方是
querySelector()
只会返回找到的第一个元素,而querySelectorAll()
会返回所有符合条件的元素。
5.节点的修改(DOM修改)
-
这里的修改我们主要指对元素节点的操作。
-
创建节点
– document.createElement(标签名)
- 删除节点
– 父节点.removeChild(子节点)
- 替换节点
– 父节点.replaceChild(新节点 , 旧节点)
- 插入节点
– 父节点.appendChild(子节点)
– 父节点.insertBefore(新节点 , 旧节点)
DOM修改
document.createElement()
- 可以根据标签名创建一个元素节点对象
document.createTextNode()
- 可以根据文本内容创建一个文本节点对象
父节点.appendChild(子节点)
-
向父节点中添加指定的子节点
-
若这个节点是页面上的,就把原位置节拿走放到指定父节点的里面
父节点.insertBefore(新节点,旧节点)
- 将一个新的节点插入到旧节点的前边
父节点.replaceChild(新节点,旧节点)
- 使用一个新的节点去替换旧节点
父节点.removeChild(子节点)
-
删除指定的子节点
-
推荐方式:子节点.parentNode.removeChild(子节点)
innerHTML
配合 字符串 也可以完成上述操作,但浏览器在添加元素时,会把之前存在的相同的元素节点覆盖替换,比较浪费资源,须在合适的时机使用
myClick(‘btn02’, function () {
var li = document.createElement(‘li’)
// var text = document.createTextNode(‘广州’)
// li.appendChild(text);
li.innerHTML = ‘广州’
city.insertBefore(li, bj)
})
6.文档的加载
-
文档的加载
-
浏览器在加载一个页面时,是按照自上向下的顺序加载的,加载一行执行一行。
-
如果将js代码编写到页面的上边,当代码执行时,页面中的DOM对象还没有加载,
此时将会无法正常获取到DOM对象,导致DOM操作失败。
-
解决方式一:
-
可以将js代码编写到body的下边
按钮
-
解决方式二:
-
将js代码编写到window.onload = function(){}中
-
window.onload 对应的回调函数会在整个页面加载完毕以后才执行,
所以可以确保代码执行时,DOM对象已经加载完毕了
7.DOM
对CSS
的操作
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
-
语法:
元素.currentStyle.样式名
- 例子:
box.currentStyle[“width”] (不好的地方 div宽度可能读到auto)
- 通过这个属性读取到的样式是只读的不能修改
读取当前样式兼容写法
function getStyle(obj , name){
if(window.getComputedStyle){
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj , null)[name];
}else{
//IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
//return window.getComputedStyle?getComputedStyle(obj , null)[name]:obj.currentStyle[name];
}
- 其他的样式相关的属性
注意:以下样式都是只读的
clientHeight
- 元素的可见高度,指元素的-内容区和内边距-的高度
clientWidth
- 元素的可见宽度,指元素的-内容区和内边距-的宽度
offsetHeight
- 整个元素的高度,包括-内容区、内边距、边框-
offsetWidth
- 整个元素的宽度,包括-内容区、内边距、边框-
offsetParent
-
当前元素的定位父元素
-
离他最近的开启了定位的祖先元素,如果所有的元素都没有开启定位,则返回body
offsetLeft
offsetTop
-
当前元素和定位父元素之间的偏移量
-
offsetLeft水平偏移量 offsetTop垂直偏移量
scrollHeight
scrollWidth
- 获取元素滚动区域的高度和宽度 -内容区和内边距-
scrollTop
scrollLeft
- 获取元素垂直和水平滚动条滚动的距离
判断滚动条是否滚动到底
- 垂直滚动条
scrollHeight - scrollTop = clientHeight
- 水平滚动
scrollWidth - scrollLeft = clientWidth
//当满足scrollHeight - scrollTop == clientHeight
//说明垂直滚动条滚动到底了
//当满足scrollWidth - scrollLeft == clientWidth
//说明水平滚动条滚动到底
8.对类的操作
点击按钮以后修改box的样式
1.了解 事件
-
指的就是用户与浏览器交互的一瞬间
-
我们通过为指定事件绑定回调函数的形式来处理事件,当指定事件触发以后我们的回调函数就会被调用,这样我们的页面就可以完成和用户的交互了。
-
事件(Event)
-
事件指的是用户和浏览器之间的交互行为。比如:点击按钮、关闭窗口、鼠标移动。。。
-
我们可以为事件来绑定回调函数来响应事件。
-
绑定事件的方式:
1.可以在标签的事件属性中设置相应的JS代码
例子:
<button οnclick=“js代码。。。”>按钮
2.可以通过为对象的指定事件属性设置回调函数的形式来处理事件
例子:
按钮
2.事件处理程序
- 我们可以通过两种方式为一个元素绑定事件处理程序:
– 通过HTML元素指定事件属性来绑定
– 通过DOM对象指定的属性来绑定
-
这两种方式都是我们日常用的比较多的,但是更推荐使用第二种方式。
-
还有一种方式比较特殊我们称为设置事件监听器。使用如下方式:
– 元素对象.addEventListener()
3.通过HTML标签的属性设置
- 通过HTML属性来绑定事件处理程序是最简单的方式。
按钮
-
这种方式当我们点击按钮以后,
onclick
属性中对应的JS代码将会执行,也就是点击按钮以后,页面中会弹出两个提示框。 -
这种方式我们直接将代码编写到了onclick属性中,可以编写多行js代码,当然也可以事先在外部定义好函数。
-
这种方式的优点在于,设定步骤非常简单,并且能够确保事件处理程序会在载入时被设定。
-
如果在函数的最后return false则会取消元素的默认行为。
-
使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
-
需要使用event来取消默认行为event.preventDefault();
-
但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
-
<a href="javascript:;">Delete</a>
可以取消啊的默认行为
4.通过DOM对象的属性绑定
- 但是其实上面的写法虽然简单,但却将
JS
和HTML
的代码编写到了一起,并不推荐使用,我们更推荐
如下的写法:
var btn = document.getElementById(‘btn’);
btn.onclick = function(){
alert(“hello”);
};
- 这种写法将HTML代码和JS写在不同的位置,维护起来更加容易。
5.设置事件监听器
-
前边两种方式都可以绑定事件处理程序,但是它们都有一个缺点就是都只能绑定一个程序,而不能为一个事件绑定多个程序,如果绑定了多个,则后边会覆盖掉前边的。
-
这是我们就可以使用
addEventListener()
来处理,这个方法需要三个参数:
1.事件的字符串,不要on
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false 默认 false,可以不填
-
使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
-
需要使用event来取消默认行为event.preventDefault();
-
但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
btn.addEventListener(‘click’ , function(){alert(“hello”);},false);**
-
但是要注意的是ie8以下的浏览器是不支持上边的方法的,需要使用
attachEvent
代替。 -
也可以使用
removeEventListener()
和detachEvent()
移除事件。
点我一下
6.事件处理中的this
-
在事件处理程序内的 this 所引用的对象即是设定了该事件处理程序的元素(IE的’attachEvent '里的this是window)。
-
也就是事件是给那个对象绑定的this就是哪个对象。
-
再循环中事件处理的回调函数多使用this ,慎用 for循环的index ,回调函数执行时,index已成为定值(循环结束后的值,不能如愿的根据index索引到指定元素删除),即使用的是let 定义的index ,也要慎用,尤其回调函数中有添加删除此类元素节点的操作
7.事件对象
-
在DOM对象上的某个事件被触发时,会产生一个事件对象Event,这个对象中包含着所有事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。
-
例如,鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持 event 对象,但支持方式不同。
-
DOM标准的浏览器会将一个event对象传入到事件的处理程序当中。无论事件处理程序是什么都会传入一个event对象。
-
可以通过这种方式获取:
btn.onclick = function(event){
alert(event.type);
};
- Event对象包含与创建它的特定事件有关的属性和方法。触发的事件类型不一样,可用的属性和方法也不一样。
Event对象的通用属性/方法
8.IE中的事件对象
-
与访问 DOM 中的 event 对象不同,要访问 IE 中 的 event 对象有几种不同的方式,取决于指定事件处理程序的方法。
-
在IE中event对象作为window对象的属性存在的,可以使用window.event来获取event对象。
-
在使用attachEvent()的情况下,也会在处理程序中传递一个event对象,也可以按照前边的方式使用。
Event对象的通用属性/方法(IE)
事件
-
事件对象
-
当响应函数被调用时,浏览器每次都会将一个事件对象作为实参传递进响应函数中,
这个事件对象中封装了当前事件的相关信息,比如:鼠标的坐标,键盘的按键,鼠标的按键,滚轮的方向。。
-
可以在响应函数中定义一个形参,来使用事件对象,但是在IE8以下浏览器中事件对象没有做完实参传递,而是作为window对象的属性保存
-
例子:
元素.事件 = function(event){
event = event || window.event;
};
元素.事件 = function(e){
e = e || event;
};
9.事件的触发
-
事件的发生主要是由用户操作引起的。
-
比如
mousemove
这个事件就是由于用户移动鼠标引起的,在鼠标指针移动的过程中该事件会持续发生。 -
当指定事件被触发时,浏览器就会调用对应的函数去响应事件,一般情况下事件没触发一次,函数就会执行一次。
-
因此设置鼠标移动的事件可能会影响到鼠标的移动速度。所以设置该类事件时一定要谨慎。
10.事件的传播
- 在网页中标签与标签之间是有嵌套关系的,比如这样一个页面:
sample
-
如果这时用户点击了sample按钮,则会以该按钮作为事件目标触发一次点击事件。
-
这时,事件的处理将会分为捕获阶段、目标阶段、事件冒泡这三个阶段。
事件的传播流程
- 捕获阶段
– 这一阶段会从window对象开始向下一直遍历到目标对象,如果发现有对象绑定了响应事件则做相应的处理。
- 目标阶段
– 这一阶段已经遍历结束,则会执行目标对象上绑定的响应函数。
- 事件冒泡阶段
– 这一阶段,事件的传播方式和捕获阶段正好相反,会从事件目标一直向上遍历,直至window对象结束,这时对象上绑定的响应函数也会执行。
取消事件传播
- 我们可以使用event对象的两个方法完成:
– stopPropagation()
:取消事件的进一步捕获或冒泡
– stopImmediatePropagation()
:取消事件的进一步捕获或冒泡
- 取消默认行为:
– preventDefault()
-
事件的冒泡(Bubble)
-
事件的冒泡指的是事件向上传导,当后代元素上的事件被触发时,将会导致其祖先元素上的同类事件也会触发。
-
事件的冒泡大部分情况下都是有益的,如果需要取消冒泡,则需要使用事件对象来取消
-
可以将事件对象的cancelBubble设置为true,即可取消冒泡
-
例子:
元素.事件 = function(event){
event = event || window.event;
event.cancelBubble = true;
};
11.常用的事件属性
MouseEvent - WheelEvent 继承MouseEvent
WheelEvent
只有事件wheel
属于这个对象
| 属性/方法 | 描述 |
| :-- | :-- |
| clientX
| 返回触发鼠标事件时,鼠标指针相对于当前窗口的水平坐标。 |
| clientY
| 返回触发鼠标事件时,鼠标指针相对于当前窗口的垂直坐标。 |
| offsetX
| 返回鼠标指针相对于目标元素边缘位置的水平坐标。 |
| offsetY
| 返回鼠标指针相对于目标元素边缘位置的垂直坐标。 |
| pageX
| 返回触发鼠标事件时鼠标指针相对于文档的水平坐标。 |
| pageY
| 返回触发鼠标事件时鼠标指针相对于文档的垂直坐标。 |
| screenX
| 返回触发事件时鼠标指针相对于屏幕的水平坐标。 |
| screenY
| 返回触发事件时鼠标指针相对于屏幕的垂直坐标。 |
注意
chrome的html无法触发onscroll事件,离谱的是chrome的html可以读取scrollTop属性,但是chrome的body不能读取
触发事件建议直接使用 document.onscroll
读取 scrollTop 使用 如下表达式
document.body.scrollTop || document.documentElement.scrollTop;
KeyboardEvent
这些事件类型属于 KeyboardEvent
对象:
| 事件 | 描述 |
| :-- | :-- |
| onkeydown
| 当用户正在按下键时,发生此事件。 |
| onkeypress
| 当用户按了某个键时,发生此事件。 |
| onkeyup
| 当用户松开键时,发生此事件。 |
| 属性/方法 | 描述 |
| :-- | :-- |
| altKey
| 返回触发按键事件时是否按下了 “ALT” 键。 |
| charCode
| 返回触发 onkeypress 事件的键的 Unicode 字符代码。 |
| code
| 返回触发事件的键的代码。 |
| ctrlKey
| 返回按键鼠标事件时是否按下了 “CTRL” 键。 |
| getModifierState()
| 如果指定的键被激活,则返回 true。 |
| isComposing
| 返回事件的状态是否正在构成。 |
| key
| 返回事件表示的键的键值。 |
| keyCode
| 返回触发 onkeypress 事件的键的 Unicode 字符码,或触发 onkeydown 或 onkeyup 事件的键的 Unicode 键码。 |
| location
| 返回键盘或设备上按键的位置。 |
| metaKey
| 返回按键事件触发时是否按下了 “META” 键。 |
| repeat | 返回是否重复按住某个键。 |
| shiftKey
| 返回按键事件触发时是否按下了 “SHIFT” 键。 |
| which
| 返回触发 onkeypress
事件的键的 Unicode 字符码,或触发 onkeydown
或 onkeyup
事件的键的 Unicode 键码 |
12.事件的委派
添加超链接
我是p元素
- 超链接一
- 超链接二
- 超链接三
13.案例
1).拖拽
取消浏览器鼠标默认行为
return false
IE:
设置某元素捕获所有鼠标按下的事件
-
一次性的
-
setCapture()
-
- 只有IE支持,但是在火狐中调用时不会报错,
-
而如果使用chrome调用,会报错
取消某元素捕获所有鼠标按下的事件
- releaseCapture();
我是一段文字
2).滚轮事件
-
使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
-
需要使用event来取消默认行为event.preventDefault();
-
但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
3).键盘事件
/*
-
键盘事件:
-
onkeydown
-
- 按键被按下
-
- 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
-
- 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快
-
这种设计是为了防止误操作的发生。
-
- keycode无法区分大小写
-
onkeyup
-
- 按键被松开
-
- keycode可以区分大小写
-
onkeypress 与onkeydown类似 ,但是无法监测功能键和和功能组合键
-
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
*/
/*
-
可以通过keyCode来获取按键的编码
-
通过它可以判断哪个按键被按下
-
除了keyCode,事件对象中还提供了几个属性
-
altKey
-
ctrlKey
-
shiftKey
-
- 这个三个用来判断alt ctrl 和 shift是否被按下
-
如果按下则返回true,否则返回false
*/
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
按键移动div
我是一段文字
2).滚轮事件
-
使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
-
需要使用event来取消默认行为event.preventDefault();
-
但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
3).键盘事件
/*
-
键盘事件:
-
onkeydown
-
- 按键被按下
-
- 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直触发
-
- 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他的会非常的快
-
这种设计是为了防止误操作的发生。
-
- keycode无法区分大小写
-
onkeyup
-
- 按键被松开
-
- keycode可以区分大小写
-
onkeypress 与onkeydown类似 ,但是无法监测功能键和和功能组合键
-
键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document
*/
/*
-
可以通过keyCode来获取按键的编码
-
通过它可以判断哪个按键被按下
-
除了keyCode,事件对象中还提供了几个属性
-
altKey
-
ctrlKey
-
shiftKey
-
- 这个三个用来判断alt ctrl 和 shift是否被按下
-
如果按下则返回true,否则返回false
*/
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
按键移动div
-