JS—01
一、js编写位置
1)将js代码写在标签中,属于结构与行为耦合,不方便维护,不推荐使用
示例:
<button onclick="alert('hello');">我是按钮</button>
<a href="javascript:alert('aaa');">超链接</a>
2)可以将js代码写在外部js文件中,然后通过script标签引入(src属性),该写法可以在不同的页面中同时引入,也可以利用浏览器缓存方式利用,推荐使用
示例:
<script type="text/javascript">//编写js代码</script>
3)也可以将js代码写入script标签中,但script标签一旦引入外部文件,就无法再写入js代码
示例:
<script type="text/javascript" src="文件路径"></script>
二、js基本语法
1)js代码严格区分大小写
2)js语句结束末尾都需添加 ;(封号)
因为不写分号,浏览器会自动添加,此举会消耗一些系统资源
3)js中会忽略多个空格和换行
三、标识符
在js中所有可以由我们自主命名的都可以称为标识符
——通常遵循的规则:
1)标识符中可以含有字母、数字、_ 、$
2)标识符不能以数字开头
3)标识符一般采用驼峰命名法
——首字母小写,每个单词首字母大写,其余小写
4)标识符不能是js中的关键字或保留字
四、数据类型
js中六种数据类型:(前五种属于基本数据类型,后一种属于引用数据类型)
1.String
字符串需要搭配引号使用
2.Number
1)js中整数和小数也属于Number数据类型
2)在js中整数运算基本可以保证精确,但位数不能太长
3)在js中千万不要进行对精确度较高的运算,因为结果可能不精确
3.Boolean
用来进行逻辑判断,只有两个值 true/false
4.Null
1)值只有一个,就是null
2)null这个值专门用来表示一个空的对象
3)使用typeof检查一个null值时,会返回object
5.Undefined
1)值只有一个,就是undefined
2) 使用typeof检查一个undefined值时,会返回undefined
3)当声明一个变量但未赋值时,值也是undefined
6.Object
五、强制类型转换
1.将其他类型转换为String:
方法一:
调用被转换数据类型的toString()方法
该方法不会影响到原变量,它会将转换的结果返回
但注意:null 和 undefined 这两个值没有toString()方法
示例:
var a = 123;
a = a.toString();
方法二:
调用String()函数,并将被转换的数据作为参数传递给函数
此方法也能转换null 和 undefined
示例:
var a = 123;
a = String(a);
2.将其他类型转换为Number:
方法一:
调用Number()函数(用法和String()函数相同)
示例:
var s = "123";
s = Number(s);
转换的情况:
- 字符串 > 数字 如果字符串是一个合法的数字,则直接转换为对应的数字 如果字符串是一个非法的数字,则转换为NaN 如果是一个空串或纯空格的字符串,则转换为0
- 布尔值 > 数字 true转换为1 false转换为0
- 空值 > 数字 null转换为0
- 未定义 > 数字 undefined 转换为NaN
方法二: 调用parseInt()或parseFloat()
parseInt()可以将一个字符串中有效的整数位提取出来,并转换为Number 示例:
var a = "123.456px";
a = parseInt(a); //123
parseFloat()作用和 parseInt()类似,不过它可以将有效的小数位提取出来 示例:
var a = "123.456px";
a = parseFloat(a); //123.456
补充:可以在parseInt()中传递一个第二个参数,来指定数字的进制
示例:
var a = "070"
a = parseInt(a,10) //70
a = parseInt(a,8) //56
十六进制表示:0x....(0x10)
八进制表示:0....(070)
二进制表示:0b...(0b10)
3.将其他类型转换为Boolean
方法一:
使用Boolean()函数 示例:
var s = "false";
s = Boolean(s); //true
转换的情况 字符串 > 布尔 除了空串其余全是true
数值 > 布尔 除了0和NaN其余的全是true
null、undefined > 布尔 都是false
对象 > 布尔 都是true
方法二:
为任意的数据类型做两次非运算,即可将其转换为布尔值 示例:
var a = "hello";
a = !!a; //true
六、运算符
运算符也称为操作符 通过运算符可以对一个或多个值进行运算或操作
1.typeof运算符
用来检查一个变量的数据类型 语法:typeof 变量 它会返回一个用于描述类型的字符串作为结果
示例:
var a = "hello"
console.log(typeof a) //string
2.算数运算符
+ 对两个值进行加法运算并返回结果 - 对两个值进行减法运算并返回结果 * 对两个值进行乘法运算并返回结果 / 对两个值进行除法运算并返回结果 % 对两个值进行取余运算并返回结果
除了加法以外,对非Number类型的值进行运算时,都会先转换为Number然后在做运算。 而做加法运算时,如果是两个字符串进行相加,则会做拼串操作,将两个字符连接为一个字符串。 任何值和字符串做加法,都会先转换为字符串,然后再拼串
3.一元运算符
一元运算符只需要一个操作数
一元的+
就是正号,不会对值产生任何影响,但是可以将一个非数字转换为数字 示例:
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的值是变量的原值(自减前的值)
4.逻辑运算符
! 非运算可以对一个布尔值进行取反,true变false false边true 当对非布尔值使用 ! 时,会先将其转换为布尔值然后再取反 我们可以利用 ! 来将其他的数据类型转换为布尔值
&& &&可以对符号两侧的值进行与运算 只有两端的值都为true时,才会返回true。只要有一个false就会返回false。 与是一个短路的与,如果第一个值是false,则不再检查第二个值 对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值 规则: 1.如果第一个值为false,则返回第一个值 2.如果第一个值为true,则返回第二个值
|| ||可以对符号两侧的值进行或运算 只有两端都是false时,才会返回false。只要有一个true,就会返回true。 或是一个短路的或,如果第一个值是true,则不再检查第二个值 对于非布尔值,它会将其转换为布尔值然后做运算,并返回原值 规则: 1.如果第一个值为true,则返回第一个值 2.如果第一个值为false,则返回第二个值
5.赋值运算符
=:可以将符号右侧的值赋值给左侧变量 +=
a += 5; 相当于 a = a+5;
-=
a -= 5 相当于 a = a-5
*=
a *= 5 相当于 a = a*5
/=
a /= 5 相当于 a = a/5
%=
a %= 5 相当于 a = a%5
6.关系运算符
关系运算符用来比较两个值之间的大小关系的 > >= < <= 关系运算符的规则和数学中一致,用来比较两个值之间的关系, 如果关系成立则返回true,关系不成立则返回false。 如果比较的两个值是非数值,会将其转换为Number然后再比较。 如果比较的两个值都是字符串,此时会比较字符串的Unicode编码,而不会转换为Number。
7.相等运算符
相等,判断左右两个值是否相等,如果相等返回true,如果不等返回false 相等会自动对两个值进行类型转换,如果对不同的类型进行比较,会将其转换为相同的类型然后再比较,转换后相等它也会返回true,null == undifined
!= 不等,判断左右两个值是否不等,如果不等则返回true,如果相等则返回false 不等也会做自动的类型转换。
=== 全等,判断左右两个值是否全等,它和相等类似,只不过它不会进行自动的类型转换, 如果两个值的类型不同,则直接返回false
!== 不全等,和不等类似,但是它不会进行自动的类型转换,如果两个值的类型不同,它会直接返回true
特殊的值: null和undefined 由于undefined衍生自null,所以null == undefined 会返回true。 但是 null === undefined 会返回false。 NaN NaN不与任何值相等,报告它自身 NaN == NaN //false
判断一个值是否是NaN 使用isNaN()函数
8.三元运算符
? : 语法:条件表达式 ? 语句1 : 语句2; 执行流程: 先对条件表达式求值判断, 如果判断结果为true,则执行语句1,并返回执行结果 如果判断结果为false,则执行语句2,并返回执行结果
优先级: 和数学中一样,JS中的运算符也是具有优先级的, 比如 先乘除 后加减 先与 后或 具体的优先级可以参考优先级的表格,在表格中越靠上的优先级越高, 优先级越高的越优先计算,优先级相同的,从左往右计算。 优先级不需要记忆,如果越到拿不准的,使用()来改变优先级。
JS—02
一、对象
1.对象简介
如果使用基本数据类型的数据,我们所创建的变量都是独立的,不能成为一个整体,而对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性
对象的分类:
1)内建对象:
由ES标准中定义的对象,在任何的ES的实现中都可以使用(比如:Math Sting Number Boolean......)
2)宿主对象:
由JS的运行环境提高的对象,目前来讲主要指由浏览器提供的对象(比如:BOM DOM)
3)自定义对象:
由开发人员自己定义自己定义
2.对象基本操作
四项基本操作:增、删、改、查
//创建对象
var obj = new Object();
/*
使用new关键字调用的函数是构造函数constructor
而构造函数是专门用来创建对象的
*/
//向对象中添加属性
//语法:对象.属性名 = 属性值
obj.name = "孙悟空";
obj.gender = "男";
//读取对象中的属性
//语法:对象.属性名
console.log(obj.name); //孙悟空
/*
若读取对象中没有的属性,不会报错,但会返回undefined
*/
console.log(obj.age); //undefined
//修改对象属性值
//语法:对象.属性名 = 新值
obj.name = "猪八戒";
console.log(obj.name); //猪八戒
//删除对象中的属性
//语法:delete 对象.属性名
delete obj.name;
3.对象中的属性名和属性值
属性名:
对象中的属性名不强制要求遵循标识符的规范,但还是尽量按照标识符的规范使用
/*
如果要使用特殊的属性名,不能采用.的方式来操作
而需要使用另外一种方式
语法:对象["属性名"] = 属性值
*/
obj.123 = 789;
console.log(obj.123); //报错
obj["123"] = 789;
console.log(obj[123]); //没有问题(怎么设置属性值就怎么读取属性值)
// 而且使用[]这种形式去操作属性,更加的灵活
obj["nihao"] = "你好";
n = 123;
console.log(obj[n]); //789
n = "nihao";
console.log(obj[n]); //你好
属性值:
属性值可以是任意的数据类型
in 运算符:
/*
in 运算符
通过该运算符可以检查一个对象中是否含有指定的属性
语法:"属性名" in 对象
*/
console.log(obj.age); //false
console.log(obj.gender); //true
4.创建对象的另外方式
1)使用字面量来创建对象
/*
使用对象字面量,可以在创建对象时,直接指定对象中的属性
语法:{属性名:属性值,属性名:属性值......}
对象字面量的属性名可以加引号也可以不加,建议不加
如果要使用一些特殊的对象名,则必须加引号
*/
var obj = {
name:"张三",
age:18,
gender:"男"
"!@#$":123 //特殊对象名
}
2)使用工厂方法创建对象
/*
使用工厂方法创建对象
通过该方法可以大批量的创建对象
但该方法所创建的对象都属于Object,无法进一步区分,所有不推荐使用
*/
function createObj(name,age,gender){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.gender = gender;
return obj; //注意:需要将新对象返回
}
var obj = createObj("张三",18,"男")
var obj2 = createObj("李四",28,"男")
var obj3 = createObj("王五",38,"男")
3)使用构造函数来创建对象
/*
语法:
function 构造函数名(){
this.属性 = 值;
this.方法 = function(){};
}
*/
/*
创建一个构造函数,专门用来创建可以区分出对象的
构造函数就是一个普通的函数,创建方式和普通函数没有区别
不同的是构造函数习惯首字母大写
构造函数和普通函数的区别就是调用方式的不同
普通函数是直接调用,而构造函数需要使用new关键字来调用
构造函数的执行流程:
1.立刻创建一个新的对象
2.将新建的对象设置为函数中的this,在构造函数中可以使用this
3.逐行执行函数中的代码
4.将新建的对象作为返回值返回
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类
我们将通过一个构造函数创建的对象,称为是该类的示例
*/
function Person(name,age,gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = funtion(){
alter(this.name);
}
}
var per = new Person("张三",18,"男");
function Dog(name,age){
this.name = name;
this.age = age;
}
var dog = new Dog("旺财",3);
console.log(per); //Person类型对象
console.log(dog); //Dog类型对象
二、函数
1.函数简介
函数也是一个对象,函数中可以封装一些功能(代码),在需要时可以执行这些功能
封装到函数中的代码不会立即执行,需要调用函数时才执行其中代码
2.函数的创建方式
1)函数声明
/*
使用函数声明来创建一个函数
语法:function 函数名([参数1,参数2,.....]){
代码...
}
调用函数语法:函数名()
*/
function fun(){
console.log("我是函数声明创建的函数");
}
fun(); //我是函数声明创建的函数
2)函数表达式
console.log("我是函数声明创建的函数")/*
使用函数表达式来创建一个函数
var 函数名 = function([参数1,参数2,.....]){
代码...
}
*/
var fun2 = function(){
console.log("我是函数表达式创建的函数");
}
fun2(); //我是函数表达式创建的函数
3.函数的形参与实参
/*
可以在函数的()中来指定一个或多个形参
多个形参之间使用,隔开,声明形参就相当与在函数内部声明了对应的变量,但没有赋值
*/
function sum(a.b){
console.log(a+b);
}
//在调用函数时,可以在()中指定实参
sum(1,2); //3
/*
调用函数时,解析器不会检查实参的数量
多余的实参不会被赋值
而如果实参的数量少于形参的数量,则没有对应实参的形参被赋值为undefined
*/
sum(1,2,3,4,5,6) //3
sum(1) //NaN
补充:实参可以是任意数据类型的数据
4.立即执行函数
函数定义后,立即执行,且只执行一次
(function(){
console.log("立即执行函数")
})();
//带参数的立即执行函数
(function(a,b){
console.log(a+b)
})(1,2);
5.枚举对象中的属性
for...in...语句
/*
语法 for(var 变量 in 对象){
代码...
}
for...in...语句 对象中有几个属性,循环体就会执行几次
*/
var obj = {
name:"张三",
age:18,
gender:"男",
address:"牢房"
}
for (var o in obj){
console.log(o) //依次输出对象中的属性名
console.log(obj.o) // undefined,obj对象中没有o这个属性名
console.log(obj[0]) //依次输出对应的对象名中的对象值
}
6.作用域
作用域指一个变量的作用的范围
1)全局作用域
—— 直接编写在script标签中的JS代码
—— 全局作用域在页面打开时创建,在页面关闭时销毁
—— 在全局作用域中有一个全局对象window(它代表的时一个浏览器的窗口,由浏览器创建我们可以直接使用)
—— 在全局作用域中:
创建的变量都会作为window对象的属性保存
创建的函数都会作为window对象的方法保存
—— 全局作用域中的变量在页面的任意部分都可以访问的到
2)函数作用域
—— 调用函数时创建函数作用域,函数执行完毕后,函数作用域消耗
—— 每调用依次函数就会创建一个新的函数作用域,它们之间是相互独立的
—— 在函数作用域中可以访问到全局作用域的变量
但在全局作用域中无法访问到函数作用域的变量
—— 当函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接用
如果没有则向上一级作用域中寻找,直到找到全局作用域
如果全局作用域中依然没有找到,则会报错
7.变量于函数的提升
1)变量提升
/*
变量的声明提前
使用var关键字声明的变量,会在所有的代码执行前被声明(但是不会被赋值)
*/
console.log(a); //输出undefined
var a = 1;
console.log(a); //会报错
a = 1;
2)函数提升
/*
函数的声明提前
使用函数声明形式创建的函数function 函数(){},它会在所有的代码执行前就被创建
*/
fun(); //我是函数声明所创建的
fun2(); //报错,因为undefined不是一个函数
function fun(){
console.log("我是函数声明所创建的");
}
var fun2 = function(){
console.log("我是函数表达式创建的");
}
注意:在函数作用域也有变量声明提前的特性
即使用var关键字声明的变量,会在函数中所有执行的代码之前被声明
在函数中,如果不使用var声明的变量,则会成为全局变量
8.提升练习
------------------------------------
var a = 123;
function fun(){
alter(a);
}
fun(); //123
------------------------------------
var a = 123;
function fun(){
alter(a);
var a = 456;
}
fun(); //undefined,在函数作用域中使用var声明了变量a
alter(a); //123,在函数作用域中使用了var声明变量a
------------------------------------
var a = 123;
function fun(){
alter(a);
a = 456;
}
fun(); //123,在函数作用域中没有使用var声明了变量a
alter(a); //456, 在函数作用域中没有使用var声明了变量a
------------------------------------
var a = 123;
function fun(a){
alter(a);
a = 456;
}
fun(); //undefined,实参数量小于形参
alter(a); //456
------------------------------------
var a = 123;
function fun(a){
alter(a);
a = 456;
}
fun(123); //123
alter(a); //123,因为在此函数作用域中已经存在变量a,所有不会找到全局作用域中的a
------------------------------------
9.this相关知识
解析器在调用函数每次都会向函数内部传递一个隐含的参数,
这个隐含的参数就是this,this指向一个对象,
这个对象就是我们称为函数执行的 上下文对象,
根据函数的调用方式不同,this会指向不同的对象
/*
this的情况:
1.当以函数的形式调用时,this是window
2.当以方法的形式调用时,谁调用方法this就是谁
3.当以构造函数的形式调用时,this就是新创建的那个对象
4.使用call()和apply()调用时,this是指定的那个对象
*/
function fun(){
console.log(this);
}
var obj = {
name:"张三",
sayName:fun
};
fun(); //此时this为window
obj.sayName(); //此时this为obj
10.原型对象(prototype)
问题:
在构造函数中定义方法,那么每创建一个对象就会生成一个对应的相同的方法,从而浪费大量的内存空间
而将函数定义在全局作用域,则污染了全局作用域的命名空间,且不安全
/*
原型prototype
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
这个属性对应着一个对象,这个对象就是我们所谓的原型对象
如果函数作为普通函数调用prototype没有任何作用
但当以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性(__proto__)来指向该构造函数的原型对象
*/
function Fun(){
}
var fun = new Fun();
var fun2 = new Fun();
console.log(fun.__proto__ == Fun.prototype) //true
console.log(fun2.__proto__ == Fun.prototype) //true
/*
原型对象就相当于一个公共区域,所有同一个类的实例都可以访问到这个原型对象,
所以我们可以将对象中共有的内容,统一设置到原型对象中
当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
如果没有则会去原型对象中寻找,找到则也直接使用
以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中去,
这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象拥有这些属性和方法了
*/
Fun.prototype.salary = 8000;
Fun.prototype.sayName = funtion(){
console.log(this.name);
}
注意:
使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
所以可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性
11.toSting()方法
当我们直接在页面中打印一个对象时,事实上是输出对象的toString()方法的返回值
/*
如果我们希望在输出对象时不输出[object object],可以为对象添加一个toString()方法
*/
function Fun(){
}
var fun = new Fun();
fun.toString = function(){
console.log("我是一个快乐又积极的person");
}
console.log(fun); //我是一个快乐又积极的person
JS—03
一、数组
1.数组简介
数组也是一个对象
它和我们普通对象功能类似,也是用来存储一些值的
不同的是普通对象使用字符串作为属性名,而数组使用数组作为索引来操作元素
数组中的元素可以是任意数据类型
2.数组的基本操作
/*
创建数组:
1)利用构造函数来创建数组对象
2)利用数组字面量来创建数组
*/
var arr = new Array();
var arr = [];
/*
向数组中添加元素
语法: 数组[索引] = 值
读取数组中的元素
语法 数组[索引]
如果读取不存在的索引,它不会报错而是返回undefined
*/
arr[0] = 0;
arr[1] = 1;
console.log(arr[0]); // 0
console.log(arr[2]); //undefined
/*
可以使用length属性来获取数组的长度
语法:数组.length
对于连续的数组,使用length可以获取到数组的长度
而对于非连续的数组,使用length会获取到数组的最大索引+1
*/
console.log(arr.length) // 2
arr[10] = 10
console.log(arr.length) //11
//向数组的最后一个位置添加元素
//语法:数组[数组.length] = 元素
arr[arr.length] = xxx
3.数组中的方法(常用)
var arr = [];
/*
push()
该方法可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
*/
arr.push(1);
var length = arr.push(2,3);
console.log(arr); // 1,2,3
console.log(length); //3
/*
pop()
该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回
*/
var result = arr.pop();
console.log(arr); // 1,2
console.log(result); // 3
/*
unshift()
向数组开头添加一个或多个元素,并返回新的数组长度
向前边插入元素以后,其他的元素索引会依次调整
*/
var length = arr.unshift(0);
console.log(arr); // 0,1,2
console.log(length); // 3
/*
shift()
可以删除数组的第一个元素,并将被删除的元素作为返回值返回
*/
var result = arr.shift();
console.log(arr); // 1,2
console.log(result); // 0
/*
slice(start,end)
可以用来从数组中提前指定元素
该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回
参数:
1.截取开始位置的索引(包含开始位置)
2.截取结束位置的索引(不包含结束位置)
当第二个参数省略不屑时,此时会截取从开始索引往后位置的所以元素
索引可以传递一个负值,如果传递一个负值,则从后往前计算
-1 倒数第一个
-2 倒数第二个
*/
var arr = [1,2,3,4,5];
var newArr = arr.slice(0,2);
console.log(arr); // 1,2,3,4,5
console.log(newArr); // 1,2
/*
splice(start,much)
可以用于删除数组中指定的元素
使用splice()会影响到原数组,会将指定元素从原数组中删除,并将被删除元素作为返回值返回
参数:
1.表示开始位置的索引
2.表示删除的数量
*/
var arr = [1,2,3];
var result = arr.splict(0,2);
console.log(arr); // 3
console.log(result); // 1,2
/*
concat()可以连接两个或多个数组,并将新的数组返回(该方法不会对原数组产生影响)
*/
var arr = [0];
var arr2 = [1];
var result = arr.concat(arr2);
console.log(result); // 0,1
/*
join()
该方法可以将数组转换为一个字符串
该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
如果不指定连接符,则,默认为连接符
*/
var arr = [1,2,3];
result = arr.join("-");
console.log(result); // 1-2-3
result = arr.join();
console.log(result); // 1,2,3
/*
reverse()
该方法用来翻转数组,会直接修改原数组
*/
var arr = [1,2,3];
arr.reverse();
console.log(arr); // 3,2,1
/*
sort()
可以用来对数组中的元素进行排序
会影响原数组,默认按照Unicode编码进行排序
所以我们可以自己来指定排序规则
我们可以在sotr()中添加一个回调函数,来指定排序顺序
浏览器会分别使用数组中的元素作为实参去调用回调函数
如果需要升序排列,则返回a-b
降序排列,则返回b-a
*/
var arr = [5,4,1,3,2];
arr.sort(function(a,b){
//return a-b;
return b-a;
})
//console.log(arr); // 1,2,3,4,5
console.log(arr); // 5,4,3,2,1
4.数组中的循环遍历(forEach)
/*
forEach()方法需要一个函数作为参数
像这种函数,由我们创建但是不由我们调用的,称为回调函数
数组中由几个元素,函数就会执行几次,每次执行时,浏览器都会遍历到的元素,会以实参的形式传递进来,我们可以来定义形参读取这些内容
而浏览器会在回调函数中传递三个参数:
第一个参数:就是当前正在遍历的元素
第二个参数:就是当前正在遍历元素的索引
第三个参数:就是正在遍历的数组
*/
var arr = [1,2,3];
arr.forEach(function(value,index,obj){
console.log(value); // 1,2,3
console.log(index); // 0,1,2
console.log(obj == arr); //true true true
})
二、call()和apply()
/*
call()和apply()
这两个方法都是函数对象的方法,需要通过函数对象来调用
在调用这两个方法时可以将第一个参数指定为一个对象
此时这个对象将会成为函数执行时的this
call()方法可以将实参在对象之后依次传递
apply()方法需要将实参封装到一个数组中统一传递
*/
function fun(){
alter("我是fun函数");
}
var obj = {
name:"张三",
sayName:function(){
alter(this.name);
}
}
var obj2 = {
name:"李四",
sayName:function(){
alter(this.name);
}
}
fun.call() //我是fun函数
fun.apply() //我是fun函数
fun.call(obj)或者fun.apply(obj) //张三
fun.call(obj2)或者fun.apply(obj2) //李四
三、arguments(封装实参对象)
在调用函数时,浏览器不止会传递this这个隐含参数,还会传递arguments这个隐含参数
arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
而调用函数时,我们所传递的实参都会在arguments中保存
arguments[0]表示第一个实参,arguments[1]表示第二个实参
其中有一个属性叫callee
这个属性对应一个函数对象,就是当前正在指向的函数对象
四、Date对象
/*
直接使用构造函数创建一个Date对象,则会封装为当前代码执行的事件
创建一个指定时间对象,需要在构造函数中传递一个表示时间字符串作为参数
格式:约/日/年/ 时:分:秒
*/
var d = new Date();
var d2 = new Date("2/23/2022 00:00:00");
/*
getDate()
获取当前日期对象是这个月中第几天
*/
var date = d2.getDate();
console.log(date); //23
/*
getDay()
获取当前日期对象是星期几
会返回一个0-6的值
*/
var day = d2.getDay();
console.log(day); //3
/*
getMonth()
获取当前时间对象的月份
会返回一个0-11值
*/
var month = d2.getMonth();
console.log(month); //1
/*
getFullYear()
获取当前日期对象的年份
*/
var year = d2.getFullYear();
console.log(year); //2022
/*
getTime()
获取当前日期对象的时间戳
指的是从格林威治标准时间的1970年1月1日,0时0分0秒到当前日期所花费的毫秒数
*/
/*
Date.now()
获取当前的时间戳
可以来测试执行代码的性能
*/
var date = Date.now();
for(var i=0;i<100;i++){
console.log(i);
}
var date2 = Date.now();
console.log(date2 - date)
五、Math对象
Math和其他的对象不同,它不是一个构造函数
它属于一个工具类,不用创建对象,它里边封装了数学运算相关的属性和方法
/*
abs()可以用来计算一个数的绝对值
*/
console.log(Math.abs(-1)); // 1
/*
Math.ceil():可以对一个数进行向上取整
Math.floor():可以对一个数进行向下取整
Math.round():可以对一个数进行四舍五入
*/
console.log(Math.ceil(1.1)); // 2
console.log(Math.cel(1.9)); // 2
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
console.log(Math.round(1.1)); // 1
console.log(Math.round(1.9)); // 2
/*
Math.random()
可以生成一个0-1之间的随机数
生成一个x-y之间的随机数
语法:
Math.round(Math.random()*(y-x)+x)
*/
console.log(Math.round(Math.random()*9+1)); //生成1-10之间的随机数
/*
Math.max() 可以获取多个数中的最大值
Math.min() 可以获取多个数中的最小值
Math.pow(x,y) 返回x的y次幂
*/
六、字符串相关方法(常用)
在底层字符串是以字符数组的形式保存的,所以大部分属性和方法都和数组类似
/*
charAt()
可以根据索引返回字符串中指定位置的字符
charCodeAt()
获取指定位置字符的字符编码(Unicode编码)
*/
var str = "Hello";
console.log(str.charAt(0)); // H
console.log(str.charCodeAt(0)); // 72
/*
concat()
可以用来连接两个或多个字符串,作用和+号差不多
用法和数组类似
*/
/*
indexOf()
该方法可以检索一个字符串中是否含有指定内容
如果字符串含有该内容,则会返回其第一次出现的索引,如果没有,则返回-1
可以指定一个第二个参数,那么会从指定位置开始查找
lastIndexOf()
该方法的用法和indexOf是一样的
不同的是从后往前找
*/
var str = "Hello";
console.log(str.indexOf(l)); // 2
console.log(str.indexOf(l,3)); // 3,此时从第二个l处开始查找
/*
slice()
可以从字符串中截取指定的内容,不会影响原字符串,而是将截取到的内容返回,和数组中用法类似
substring()
作用、用法和slice()方法类似
不同的是这个方法不能接受负值作为参数
如果传递了一个负值,则默认使用0
而且还会自动调正参数位置,从小到大调整
*/
/*
split()
可以将一个字符串拆分为一个数组
需要一个字符串作为参数,将会根据该字符串去拆分数组
*/
var str = "123,456,789";
console.log(str.split(",")) // 123,456,789
console.log(typeof str.split(",")) // Object
/*
toUpperCase():将一个字符串转换为大写并返回
toLowerCase():将一个字符串转换为小写并返回
*/
七、正则表达式
1.简介
正则表达式用于定义一些字符串的规则:
计算机可以根据正则表达式,来检查一个字符串是否符合规则
也可以将字符串中符合规则的内容提取出来
/*
创建正则表达式的两种方法:(使用字面量的方式创建更加简单,使用构造函数创建更加灵活)
1)构造函数法:
var reg(变量名) = new RegExp("正则表达式","匹配模式")
2)字面量法:
var reg(变量名) = /正则表达式/+匹配模式
可以传递一个匹配模式(两个一起也行)作为第二个参数:
i 忽略大小写
g 全局匹配模式
正则表达式的方法:
reg.test()
使用这个方法可以用来检查一个字符串是否符合正则表达式的规则
如果符合返回true,否则返回false
*/
2.正则语法
/*
检测一个字符串中是否含有a或b
使用 | 或 [] 表示或者的意思
[A-z] 表示任意字母
[^ ] 表示除了什么意外
*/
var reg = /[ab]/;
var str = "ac";
var str2 = "bc";
var str3 = "c";
console.log(reg.test(str)); // true
console.log(reg.test(str2)); // true
console.log(reg.test(str3)); // false
3.字符串和正则相关的语法
/*
split()
可以将一个字符串拆分为一个数组
方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串
*/
var str = "1a2b3c4d5e6f";
var reg = /[a-z]/;
console.log(str.split(reg)); // 1,2,3,4,5,6
/*
search()
可以搜索字符串中是否有指定内容
如果有,则会返回第一次出现的索引,如果没有,则返回-1
它可以接受一个正则表达式作为参数,任何会根据正则表达式去检索
*/
var str = "hello abc hello aec afc";
var reg = /a[bef]c/;
console.log(str.search(reg)); // 6
/*
match()
可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
默认情况下match只会找到第一个符合要求的内容,然后就停止搜索
我们可以将匹配模式设置为全局,这样就能匹配全局内容
match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
*/
var str = "1a2b3c4d5e6f";
var reg = /[a-z]/g;
console.log(str.match(reg)); // a,b,c,d,e,f
/*
replace()
可以将字符串中指定内容替换为新的内容
参数:
1.被替换的内容,可以接受一个正则表达式作为参数
2.新的内容
默认只会被替换第一个
*/
var str = "1a2b3c";
var reg = /[a-z]/g;
console.log(str.replace(reg,"=.=")); // 1=.=2=.=3=.=
4.正则表达式语法
量词:
通过量词可以设置一个内容出现的次数
量词只对它前边的一个内容起作用
{n} 正好出现 n 次
{m,n} 出现 m - n 次
{m,} 出现m次以上
+ 至少一个,相当于{1, }
* 0个或多个,相当于{0, }
? 0个或一个,相当于{0,1}
开头/结尾:
^ 表示开头
$ 表示结尾
如果在正则表达式中同时使用^ $,则要求字符串必须完全符合正则表达式
在正则表达式中使用 \ 作为转义字符
\ . 来表示 . (. 表示任意字符)
\ \ 来表示 \
\w 来表示:任意的字母、数字、_ [A-z0-9_]
\W 来表示:除了字母、数字、_ [ ^A-z0-9_]
\d 来表示 任意的数字
\D 来表示:除了数字
\s 来表示: 空格
\S 来表示:除了空格
\b 来表示:单词边界
\B 来表示:除了单词边界
5.正则相关练习
/*
创建一个正则表达式检测一个字符串中是否含有单词 xxx
*/
var reg = /\bxxx\b/;
console.log(reg.test("hello xxxren")); // false
console.log(reg.test("hello xxx ")); // true
/*
去除字符串中的前后空格(即使用""来替换空格)
*/
var str = " hel lo ";
console.log(str.replace(/^\s* | \s*$/g,"")); // hel lo
/*
判断邮箱的正则表达式:
只允许英文字母、数字、下划线、英文句号、以及中划线组成
*/
var str = "zhangsan-001@gmail.com";
var reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
console.log(reg.test(str)); // true
/*
判断手机号的正则表达式
*/
var str = "13567890123";
var reg = /^1[3-9][0-9]{9}$/;
console.log(reg.test(str)); // true
八、DOM
1.简介
DOM:全称Document Object Model文档对象
JS中通过DOM来对HTML文档进行操作
节点:Node——构成HTML文档最基本的单元
常用节点分为四类:
文档节点:整个HTML文档
元素节点:HTML文档中的HTML标签
属性节点:元素的属性
文本节点:HTML标签中的文本内容
2.事件
事件:就是用户和浏览器之间的交互行为
浏览器在加载一个页面时,是按照自上向下的顺序加载,即读取到一行就运行一行,如果将script标签写到页面的上边,那么代码执行时,页面还没有加载
而window.onload事件会在整个页面加载完成后才触发(这样可以确保我们的代码执行时所以的DOM对象已经加载完毕了)
3.DOM查询
获取元素节点:
1)getElementById()
通过id属性获取一个元素节点对象
2)getElemensByTagName()
通过标签名获取一组元素节点对象
3)getElementsByName()
通过name属性获取一组元素节点对象
4)getElementsByClassName() (有兼容性问题)
通过calss属性获取一组元素节点对象
获取元素节点的子节点:
1)getElemensByTagName()
方法,返回当前节点的指定标签名后代节点
2)childNodes
属性,表示当前节点的所有节点(包含换行文本节点)
3)firstChild
属性,表示当前节点的第一个节点(包含换行文本节点)
4)lastChild
属性,表示当前节点的最后一个节点(包含换行文本节点)
获取父节点和兄弟节点:
1)parentNode()
属性,表示当前节点的父节点
2)previousSibling()
属性,表示当前节点的前一个兄弟节点
3)nextSibling()
属性,表示当前节点的后一个兄弟节点
JS—04
一、事件对象
当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进相应函数(在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标,鼠标滚轮滚动的方向....)
获取的事件对象名称.绑定的事件 = function(e/event) {
alter(e/event); //其中e/event就是事件对象
}
二、事件对象相关知识
1.事件的委派
指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
事件委派是利用了事件冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
2.事件的绑定
使用 对象.事件 = 函数 的形式绑定响应函数
它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个
如果绑定多个,则后边会覆盖掉前边的
addEventListener()
通过这个方法也可以为元素绑定响应函数
参数:
1.事件的字符串,不需要使用on
2.回调函数,当事件触发时该函数会被调用
3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
而通过addEventListener()可以同时为一个元素的相同事件绑定多个响应函数
这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
3.事件的传播
1)捕获阶段
在该阶段时从最外层的祖先元素,向目标元素进行事件捕获
2)目标阶段
事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3)冒泡阶段
事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件
如果希望在捕获阶段就触发事件,可以将addEventListener()第三个参数设置为true
三、BOM
1.简介
全称: Browser Object Model ,浏览器对象模型
BOM可以使我们通过JS来操作浏览器,为我们提供了一组对象,用来完成对浏览器的操作
2.BOM对象
1)Window
代表的是整个浏览器的窗口,同时window也是网页中的全局对象
2)Navigator
代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
3)Location
代表当前浏览器的地址栏信息,通过location可以获取地址栏信息,或者操作浏览器跳转界面
4)History
代表浏览器的历史记录,但由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,且只在当次访问时有效
5)Screen
代表用户的屏幕信息,通过该对象可以获取到用户的显示器的相关信息
注意:BOM对象的使用自行了解!!!