JS不支持连续区间判断
三大组成部分
ECMAScript:JAVAScript中重要部分
dom:文档对象类型
bom:浏览器对象类型
三大书写方式
行内:a标签和非a标签
内联:header或者body中写
外链:<script src“ ”></script>
打印(输出)的三种方式
alert(内容):弹窗 console.log(’内容‘):控制台打印(推荐用这个) document.write(’内容‘):在网页上展示
//声明变量
var age:声明一个名称为age的变量
-
var是一个JS关键字,用来声明变量( variable变量的意思)。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管
-
age是程序员定义的变量名,我们要通过变量名来访问内存中分配的空间
eg:var age;(声明变量)
age = 18;(赋值)
console.log(age);(输出结果)
或
var age =18 ;
console.log(age);
//声明多个变量:中间用逗号隔开
var age = 18,
adddress = '火影'
//弹出信息框:prompt;
eg:var mgname = prompt('请输入名字')
alert(myname)=>>输入的结果
//变量命名规则
由字母(A-Za-z)、数字(O-9)、下划线_)、美元符号($ )组成
严格区分大小写,大写和小写是两个
不能以数字开头
不能是关键字、保留字
//变量命名规范
变量名尽量有意义
遵守驼峰命名法:
大驼峰:字母第一个都大写:UserName
小驼峰:首字母小写,后面单词的首字母需要大写:userNameKangbazi
数据类型
简单数据类型和复杂数据类型
简单数据类型
-
数值型(Number,默认值0)
进制:
二进制,八进制,十进制,十六进制(计算机以十进制输出)
二进制数字序列范围:0~1(前面加0b)
八进制数字序列范围:0~7(前面加0o)
十六进制数字序列范围:0~9以及A~F(前面加0x)
eg:
console.log(0b10101)
可变的量写法:eg:
x = 8
y = 8
alert(x+y)
数字型的最大值:console.log(Number.MAX_VALUE);
数字型的最小值:
console.log(Number.MIN_VALUE);
无穷大:
console.log(Number.MAX_VALUE*2);=>> Infinity
无穷小:
console.log(Number.MIN_VALUE*2);=>>--Infinity
非数字:
console.log('pink' - 100);=>>NAN
科学技术法 :
2e5=2*10的5次方
整数
浮点数(小数)
圆周率
-
字符串型(string=字符)
"" 、 ''、``(反单引号)
JS推荐使用单引号
'abc':反单引号中 原样显示 ,如果想解析变量 就要在变量外边加上 ${}
eg:console.log(`${day}天${hours}小时${minutes}分钟${seconds}秒`);= console.log(day+'天'+hours+'小时'+minutes+'分钟'+seconds+'秒');
-
布尔型(boolean=布尔,都要小写,默认为false)
true:正确
false:错误
-
null型(当跟数值进行 运算的时候 会把null 转成 0 )
null(空白),有值,但是是空值
派生出undefined,数值一样,类型不同
-
undefined(undefined=未定义)
undefined(表示没有值)
var test;
赋值又叫初始化
复杂类型 (引用类型)
object :类 数组 对象 function :函数 工具
判断数据类型:typeof(只有数据类型,没有变量类型,返回的结果一定是字符串类型)
// 第一种使用方式 var n1 = 100; console.log(typeof n1); // 第二种使用方式 var s1 = 'abcdefg'; console.log(typeof(s1)); 类型: number => 数值 string => 字符 boolean=> 布尔 undefined => 未定义 eg: var test = 0xabc console.log(typeof test) // number 数值 如果返回的是number 代表这是一个数值类型 prompt输出的一定是字符串类型 eg: var n=prompt("请输入你的名字") console.log(typeof n)//string
判断一个数值是不是NaN:isNaN(是否非数值)
//只要带is的工具 结果不出意外一定是布尔类型 //如果是NaN 则返回true 否则返回false // NaN 跟任何数字运算 结果一定是NaN // NaN不等于NaN // 如果变量是一个数字 var n1 = 100; console.log(isNaN(n1)); //=> false // 如果变量不是一个数字 var s1 = 'Jack' console.log(isNaN(s1)); //=> true
其他数据类型转成数值
-
Number(变量)
转换的内容当作一个整体来处理
如果可以转成一个合法数字,则转换成数字
如果不可以转成一个合法数字,则转换成NaN
可以把一个变量强制转换成数值类型
可以转换小数,会保留小数
能把true转换成 1 ,false 0 ( 隐形数值)
-
parseInt(变量)
不管转换什么 都是一位一位的对待
如果第一位不能转成合法的数字 那么就立马输出 NaN 然后停止转换
如果第一位能转成合法的数字 那么保留第一位 然后继续看第二位 ,以此类推直到结束
不认识小数点,只能保留整数
-
parseFloat(变量)
从第一位开始检查,是数字就转换,直到一个不是数字的内容
开头就不是数字,那么直接返回
NaN
识别小数点
其他数据类型转成字符串(可用于拼接)
-
变量.toString()
有一些数据类型不能使用
toString()
方法,比如undefined
和null
eg:
var b1=20;
var s=b1.toString()
-
String(变量)
所有数据类型都可以
-
使用加法运算
在 JS 里面,
+
由两个含义字符串拼接: 只要
+
任意一边是字符串,就会进行字符串拼接加法运算:只有
+
两边都是数字的时候,才会进行数学运算
其他数据类型转成布尔
-
Boolean(变量)
在 js 中,只有
''
(中间没有空格)、0
、null
、undefined
、NaN
,这些是false
其余都是
true
数学运算符
-
+
只有符号两边都是数字或者布尔的时候才会进行加法运算
只要符号任意一边是字符串类型,就会进行字符串拼接
-
-
都是数值或者布尔才会生效,否则就是NaN
会执行减法运算
会自动把两边都转换成数字进行运算
-
*
会执行乘法运算
会自动把两边都转换成数字进行运算
-
/
会执行除法运算
会自动把两边都转换成数字进行运算
-
%
会执行取余运算
会自动把两边都转换成数字进行运算
-
**
幂运算
赋值运算符
-
=
就是把
=
右边的赋值给等号左边的变量名var num = 100
就是把 100 赋值给 num 变量
那么 num 变量的值就是 100
-
+=
var a = 10; a += 10; console.log(a); //=> 20
a += 10
等价于a = a + 10
-
-=
var a = 10;
a -= 10; console.log(a); //=> 0
a -= 10
等价于a = a - 10
-
*=
var a = 10; a *= 10; console.log(a); //=> 100
a *= 10
等价于a = a * 10
-
/=
var a = 10; a /= 10; console.log(a); //=> 1
a /= 10
等价于a = a / 10
-
%=
var a = 10; a %= 10; console.log(a); //=> 0
a %= 10
等价于a = a % 10
-
**=
var a = 10; a **= 10; console.log(a); //=> 1000
a * *= 10等价于a = a * * 10
比较运算符
-
==
-
比较符号两边的值是否相等,不管数据类型 >
1 == '1'
两个的值是一样的,所以得到
true
-
-
===
-
比较符号两边的值和数据类型是否都相等 >
1 === '1'
两个值虽然一样,但是因为数据类型不一样,所以得到
false
-
-
!=
-
比较符号两边的值是否不等 >
1 != '1'
因为两边的值是相等的,所以比较他们不等的时候得到
false
-
-
!==
-
比较符号两边的数据类型和值是否不等 >
1 !== '1'
因为两边的数据类型确实不一样,所以得到
true
-
-
>=
-
比较左边的值是否大于或等于右边的值 >
1 >= 1
结果是true
1 >= 0
结果是true
1 >= 2
结果是false
-
-
<=
-
比较左边的值是否小于或等于右边的值 >
1 <= 2
结果是true
1 <= 1
结果是true
1 <= 0
结果是false
-
-
>
-
比较左边的值是否大于右边的值 >
1 > 0
结果是true
1 > 1
结果是false
1 > 2
结果是false
-
-
<
-
比较左边的值是否小于右边的值 >
1 < 2
结果是true
1 < 1
结果是false
1 < 0
结果是false
-
逻辑运算符(逻辑运算符的结果不一定是布尔类型,输出最后的结果)
-
&&
-
进行 且 的运算 >
符号左边必须为
true
并且右边也是true
,才会返回true
只要有一边不是
true
,那么就会返回false
true && true
结果是true
true && false
结果是false
false && true
结果是false
false && false
结果是false
遇到false停止
-
-
||
-
进行 或 的运算 >
符号的左边为
true
或者右边为true
,都会返回true
只有两边都是
false
的时候才会返回false
true || true
结果是true
true || false
结果是true
false || true
结果是true
false || false
结果是false
遇到true 停止
-
-
!
(输出结果是布尔类型)-
进行 取反 运算 >
本身是
true
的,会变成false
本身是
false
的,会变成true
!true
结果是false
!false
结果是true
-
优先级
逻辑非>逻辑与>逻辑或
自增自减运算符(一元运算符)
-
++
-
进行自增运算
-
分成两种,前置++ 和 后置++
-
前置++,会先把值自动 +1,在返回
var a = 10; console.log(++a); // 会返回 11,并且把 a 的值变成 11
-
后置++,会先把值返回,在自动+1
var a = 10; console.log(a++); // 会返回 10,然后把 a 的值变成 11
-
-
--
-
进行自减运算
-
分成两种,前置-- 和 后置--
-
和
++
运算符道理一样
-
IF 条件分支结构
if 语句
-
通过一个
if
语句来决定代码是否执行 -
语法:
if (条件) { 要执行的代码 }
-
通过
()
里面的条件是否成立来决定{}
里面的代码是否执行if (true) { alert(''); } else if(){ alert(''); } 或 (if不行,直接else,不判断) if (true) { alert(''); } else (){ alert(''); }
SWITCH 条件分支结构
-
也是条件判断语句的一种
-
是对于某一个变量的判断
-
break:阻断程序往下执行,如果不写,就会继续穿透到下一个结果
-
语法:
var ** =...... switch (要判断的变量) { case 情况1: 输出:情况1要执行的代码 break case 情况2: 输出:情况2要执行的代码 break case 情况3: 输出: 情况3要执行的代码 break default: 输出:上述情况都不满足的时候执行的代码 } break
-
例子
var week = 1 switch (week) { case 1: alert('星期一'); break; case 2: alert('星期二'); break; case 3: alert('星期三'); break; case 4: alert('星期四'); break; case 5: alert('星期五'); break; case 6: alert('星期六'); break; case 7: alert('星期日'); break; default: alert('请输入一个 1 ~ 7 之间的数字') } break;
三元运算
-
三元运算,就是用 两个符号 组成一个语句
-
三元运算只是对 if else 语句的一个简写形式
-
语法:
条件 ? 条件为 true 的时候执行 : 条件为 false 的时候执行
eg: var age = 18; age >= 18 ? alert('已经成年') : alert('没有成年') eg: var age = parseInt(prompt('请输入一个数字 0男 1女 输入1或者0')); if(age==0){ console.log('nan') } else{ console.log('nv') } var age = parseInt(prompt('请输入一个数字 0男 1女 输入1或者0')); age==0 ? console.log('nan'): console.log('nv')
object.is(数据1,数据2)
判断两个数据是否一致,返回的是一个布尔类型的结果 false不一致 true一致 alert(object.is(1,'1')) =>> false alert(object.is(1,1)) =>>true alert(undefined == null) =>>true alert(object.is(undefined,null)) =>> false alert(object.is (NaN,NaN) ) =>>true
循环结构
-
循环结构,就是根据某些给出的条件,重复的执行同一段代码
-
循环必须要有某些固定的内容组成
-
初始化
-
条件判断
-
要执行的代码
-
自身改变
-
WHILE 循环(先进行条件判断,满足就执行,不满足直接就不执行)
eg: var cout = 0; while(cout<10){ console.log('正在跑'+(cout+1)+'圈') cout++; }
死循环
只要while条件为true(或者1) 循环就会执行死循环就是条件永远为true while( true ){ console.log("死循环") }
DO WHILE 循环(先不管条件,先执行一回,然后在开始进行条件判断)
语法: do { 要执行的代码 } while (条件) // 下面这个代码,条件一开始就不满足,但是依旧会执行一次 do 后面 {} 内部的代码 var num = 10 do { console.log('我执行了一次') num = num + 1 } while (num < 10)
FOR 循环(确定数的时候建议用这个)
语法: for (var i = 0; i < 10; i++) { 要执行的代码 } //内部用;隔开,不是逗号 // 把初始化,条件判断,自身改变,写在了一起 for (var i = 1; i <= 10; i++) { // 这里写的是要执行的代码 console.log(i) } // 控制台会依次输出 1 ~ 10
语法: 外面是行数,里面是列数 for (var n = 1; n <= 5; n++) { for (var m = 1; m <= 15; m++) { document.write('*'); } document.write('<br/>'); }
BREAK 终止循环
for (var i = 1; i <= 5; i++) { // 没循环一次,吃一个包子 console.log('我吃了一个包子') // 当 i 的值为 3 的时候,条件为 true,执行 {} 里面的代码终止循环 // 循环就不会继续向下执行了,也就没有 4 和 5 了 if (i === 3) { break } }
CONTINUE 结束本次循环
//语法:跳过本次循环,继续下一个 for (var i = 1; i <= 5; i++) { // 当 i 的值为 3 的时候,执行 {} 里面的代码 // {} 里面有 continue,那么本次循环后面的代码就都不执行了 // 自动算作 i 为 3 的这一次结束了,去继续执行 i = 4 的那次循环了 if (i === 3) { console.log('这个是第三个包子,掉地下了,我不吃了') continue } console.log('我吃了一个包子') }
递归(★★★★★)
是什么 | 什么用 | 怎么用 |
---|---|---|
递归是一种函数的调用方式 (自己调用自己,或者互相调用) | 循环 | 将一个大的问题分解为许多个同样规则的小问题,设置好结束条件 |
求斐波那契数列
//1、1、2、3、5、8... function fibonacci(num) { if (num === 1 || num === 2) { return 1; } return fibonacci(num - 1) + fibonacci(num - 2) } console.log( fibonacci(num))
阶乘
function jc(num) { if (num === 1) { return 1; } return num * jc(num - 1); }
函数(js中分为两种:普通的工具函数和构造函数)
声明式
-
使用
function
这个关键字来声明一个函数 -
声明式函数: 调用可以在 定义之前或者定义之后
-
一般起名用动词,变量一般是名词
-
语法:
function fn() { // 一段代码 =>> console.log('这个是第三个包子,掉地下了,我不吃了') } fn() // function: 声明函数的关键字,表示接下来是一个函数了 // fn: 函数的名字,我们自己定义的(遵循变量名的命名规则和命名规范) // (): 必须写,是用来放参数的位置(一会我们再聊) // {}: 就是我们用来放一段代码的位置(也就是我们刚才说的 “盒子”)
赋值式
-
其实就是和我们使用
var
关键字是一个道理了 -
首先使用
var
定义一个变量,把一个函数当作值直接赋值给这个变量就可以了 -
赋值式函数: 调用只能在 定义之后
-
语法:
var fn = function () { // 一段代码 =>> console.log('这个是第三个包子,掉地下了,我不吃了') } // 不需要在 function 后面书写函数的名字了,因为在前面已经有了 //一般不用这种写法 var fn = function dance() { console.log('这个是第三个包子,掉地下了,我不吃了') } dance()//报错 fn() //正常 =>fu替换了dance()
return:返回值和终断函数
//返回值时 function sum(sum1, sum2) { return sum1 * sum2; } var n = sum(100, 200); document.write(n); //终端时 function fn(行参) { console.log(1) console.log(2) console.log(3) // 写了 return 以后,后面的 4 和 5 就不会继续执行了 return console.log(4) console.log(5) } // 函数调用 fn(实参) //实参是对行参的解释
立即执行函数:
匿名函数: 函数定义完,立即被调用, 立即执行函数往往只会执行一次。 eg: (function(){ alert(”123“) }) ()
预解析
1.函数定义阶段
function test(形参){执行的代码}
var test = function(形参){执行的代码 }
1.1在堆内存中开辟一个空间 栈内存开一个新空间存函数名
1.2把函数体内的代码 一模一样的存储到这个空间内
1.3将堆内存的地址 给到 函数名所在的栈内存空间
2.函数调用阶段
2.1 函数名所在的栈内存空间 按照地址找到堆内存空间
先判断 栈内存空间是否存在
再看 栈内存中的堆内存地址是否存在
2.2 在栈里边开辟一个新的空间 叫执行空间
2.3 在执行空间内部 对形参进行赋值
2.4 在执行空间内 进行函数内的预解析
2.5 预解析完成接下来就是在执行空间内部 把函数体内的代码挨个执行一遍
2.6 执行完毕以后 这个执行空间就会被销毁
构造函数:
var fun=new Function("console.log('Hello 这是我的第一个函数')") fun()
Function | 函数的构造函数 |
---|---|
Object | 对象的构造函数 |
Array | 数组的构造函数 |
Date | 日期的构造函数 |
-
所有对象都是Object的实例
-
所有函数都是Function的实例
-
函数也是对象
高阶函数
函数的参数又是一个函数,该函数称为高阶函数,也叫函数式编程 eg: function zs(x){ alert(x); } function fun1(fun){ fun('绝密信息') } fun1(zs) = fun1(function zs(x){ alert(x); }) //绝密信息
对象
是一种类型,即引用类型,而对象的值就是引用类型的实例
万事万物皆对象,凡是对象都能加,对象可当数组用
对象的组成
键:属性名
值:属性值
对象的两种分类
定义方式 | 示例 | 备注 |
---|---|---|
字面量 | var obj = {} | |
构造函数 | var obj= new Object() |
对象的第一种方法
var obj = {} =>> 空对象
{}里边写的是键值对
多对键值 键值对之间用,隔开
打印对象建议用 console.log(),其余两个打印出来是对象类型
键的名字要符合标识符的规则和规范
可以是用纯数字命名 不推荐 因为打印的时候回到最前面
可以是用特殊符号 ^$@ 如果使用必须使用单引号包裹 不推荐
因为阅读性不强
键可以加引号 也可以不加
推荐使用纯字符串不要加特殊符号,为了好阅读
特殊命名的键调用需要用obj['uname']这个方法调用
eg: var obj = { uname:'千锋', age:18, sayHi:function(){ ==>>在这叫方法 console.log('hi~'); } }
操作属性的方法(增删改查)
var person = { a: 1, b: 2, c: 3 } 增: person.weight = '60kg'; person.car = '库里南'; console.log(person); 删除: 删除对象的属性需要使用 delete 关键字 该关键字只能删除该对象本身的属性 无法删除原型链上的属性 delete person.a; // 删除a属性 delete person["b"]; // 删除b属性 修改: person['class-test'] = 123321; person.name = 'kangbazi'; 查看: console.log( person.name) 或 console.log( person['uname']) 或 person.sayHi()
增删改查
-
分为点语法和数组关联语法
-
区别:如果是完全符合变量命名规范规则 那么两者没区别
-
键是数字和 特殊符号 必须采用['']
-
涉及到变量 的时候必须采用 [变量] 不要加 ''
点语法
增: 对象名.键名 = 值 删: delete obj.键名 改: 对象名.键名 = *值* => 因为对象内键不允许重名 => 再次设置的时候, 就是修改 查: 对象名.键名 => 如果对象内有这个键名, *那么就是该键对应的值* => 如果对象内没有这个键名, 那么就是 undefined
数组关联语法
增: 对象名['键名'] = 值 删: delete 对象名['键名'] 改: 对象名['键名'] = 值 查: 对象名['键名']
eg: var test = { name:'zhangsan', age:18, 'height':'181cm' } var haha = 'name'; alert(test['num1']) // 因为不存在num1这个键 undefined 这是不可用的方式 console.log(test[haha]);// 等同于test['name'] //zhangsan
利用new Object创建对象
var obj= new Object(); //创建了一个空的对象 //添加属性 obj.uname = '千锋'; obj.age= '18'; obj.sayHi=function(){ console.log('hi~'); } console.log(obj.uname); //特殊的属性名的使用方式 obj["123"]=789; console.log(obj["123"])
-
利用等号赋值来添加对象的属性和方法
-
每个属性和方法之间用分号结束
构造函数创建对象
语法格式: function 构造函数名(){ this.属性 = 值; this.方法 = function(){} } new 构造函数名(); eg: 构造函数: function Star(uname,age,sex){ this.name = uname; this.age = age; this.sing = function(sang){ console.log(sang); } } 对象: var qf=new Star('千锋',18,'机构') console.log(qf.name); qf.sing('厉害')
-
构造函数名字首字母要大写
-
构造函数不需要 return 就可以返回结果
-
调用构造函数必须使用 new
-
只要 new Star()调用函数就创建一个对象
-
属性和方法前面必须添加 this
构造函数在被new时
-
在内存中创建一个新的空对象
-
与函数中的this进行绑定
-
悄悄的添加一个 proto 属性
-
执行构造函数里面的代码
-
悄悄的返回this(所有构造函数里面不需要return)
function People(name, age, sex) { // 函数里面的this是new完了之后的返回对象 this.name = name; this.age = age; this.sex = sex; } // p是一个变量 它保存了new People的返回值 new People也叫作实例化 p是People的实例 var p = new People("小明", 13, "男"); console.log(p) // 结果: People age: 13 name: "小明" sex: "男" [[Prototype]]: Object
遍历对象
语法: for in 循环 eg: var obj={ name: '千锋', age:18, sex:'机构', fn:function(){} } for(var 变量 in 对象) for(var k in obj){ console.log(k); ==>> k 循环变量,它会在for循环里面执行多次,每一次是不同的属性名 输出 得到的是属性名,类似for循环里的 i; console.log(obj[k]); ==>> obj[k] 得到的是属性值 } 复合使用:console.log(k,obj【k】) 变量可以随意起名字,一般用k或者key; 遍历对象时,k是键 遍历数组时,k是下标
另一种遍历对象
语法:with(){} eg: with(test){ var n = name; var a = age; var h = height; } console.log(n,a,h); //不需要加前缀,只需要键名
数组对象
语法: 用数组包裹对象 eg: var arr=[ { sid:'001', sname:'张三', age:'18', }, { sid:'002', sname:'张三', age:'18', } ] for(var i=0;i<arr.length;i++){ console.log("第"+(1+1)+"个学生信息"); for(var j in arr[i]){ console.log(j+":"+arr[i][j]) } }
instanceof
检查一个对象是否是一个类 eg: console.log(dog instanceof person)
原型
语法:prototype 作用:主要用来实现属性的继承,让实例对象能共享原型对象的属性,减少内存分配。 它是每一个函数都有的一个属性 对于普通函数来说没有任何作用 对于构造函数来说:共享实例方法和属性 原型有一个天生的属性 constructor 它指向构造函数。
数组
是什么 | 什么用 | 怎么用 |
---|---|---|
一堆连续变量的集合 | 装载多个数据 | 当需要装载多个数据的时候 |
定义数组
定义方式 | 举例 | 结果 | 备注 |
---|---|---|---|
字面量 | [1, 2, 3, 4, 5]; | [1, 2, 3, 4, 5] | |
构造函数 | new Array(1, 2, 3, 4, 5) | [1, 2, 3, 4, 5] | 仅有一个数字参数时,表示数组长 |
读取数组长度
语法:.length eg: var xiaobao = ['苏荃','双儿','方怡','曾柔','阿珂','建宁公主','沐剑萍']; alert(xiaobao.length); xiaobao.length = 3 // 本来它的长度是7 // 赋值为3 从后往前删除 只剩下前三个 xiaobao.length=10; // 如果赋值超出 原本的长度 超出的部分用empty 补齐 console.log(xiaobao);
原数组变化 结果放到一个新的数组中
数组常用方法之 push(栈方法:先进后出)
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
尾部增加 | 任意个,任意类型 | 往数组的尾部增加成员 | 数组的长度 | 改变原数组 |
var arr = ['张三', '李四', '王五', '赵六']; var length = arr.push('王二') console.log(length); // 5 console.log(arr); // ["张三", "李四", "王五", "赵六", "王二"]
数组常用方法之 pop(栈方法:先进后出)
-
pop
是用来删除数组末尾的一个元素var arr = [1, 2, 3] // 使用 pop 方法删除末尾的一个元素 arr.pop() console.log(arr) // [1, 2]
数组常用方法之 unshift(队列方法:先进先出)
-
unshift
是在数组的最前面添加一个元素var arr = [1, 2, 3] // 使用 unshift 方法想数组的最前面添加一个元素 arr.unshift(4) console.log(arr) // [4, 1, 2, 3]
数组常用方法之 shift(队列方法:先进先出)
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
头部删除 | 无 | 从数组的头部删除一项 | 被删除的项 | 改变原数组 |
var arr = ['张三', '李四', '王五', '赵六']; var result = arr.shift() console.log(result); // 张三 console.log(arr) // ['李四', '王五', '赵六'];
数组常用方法之 splice
数组的增删改(截取)
(0,0,0)
第一个0是开始的索引(开始的位置),第二个是删除几个,第三个是增加谁
var arr = ['张三', '李四', '王五', '赵六']; // 删除 var result = arr.splice(1, 2) console.log(result); // ["李四", "王五"] console.log(arr); // ["张三", "赵六"] // 插入 var arr = ['张三', '李四', '王五', '赵六']; var result = arr.splice(2, 0, '小绵羊'); console.log(result); // [] 因为没有删除 console.log(arr) // ["张三", "李四", "小绵羊", "王五", "赵六"] // 替换 var arr =['张三', '李四', '王五', '赵六']; var result = arr.splice(2, 2, '小绵羊', '大绵羊'); console.log(result); // ["王五", "赵六"] console.log(arr) // ["张三", "李四", "小绵羊", "大绵羊"]
数组常用方法之 reverse
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
倒序、翻转 | 无 | 将数组的成员倒序排列,不排序 | 翻转之后的数组 | 会改变原数组 |
var arr =['张三', '李四', '王五', '赵六']; var arr1 = arr.reverse(); console.log(arr) // ["赵六", "王五", "李四", "张三"] console.log(arr1) // ["赵六", "王五", "李四", "张三"] console.log(arr === arr1) // true
数组常用方法之 sort(默认排序字母)
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
排序 | function(a, b){ return a - b} | 升序排列数组中的成员 | 排序以后的数组 | 会改变原数组 |
function(a, b){ return b - a} | 降序排列数组中的成员 | 排序以后的数组 | 会改变原数组 | |
无 | 按照字符串规则排列数组中的成员 | 排序以后的数组 | 会改变原数组 |
// 正 交换 ;负 不动 升序案例: var arr = [1, 44, 6, -7, 99, 145, 5555, 0] var arr1 = arr.sort(function (a, b) { return a - b }) 或者: var arr1 = arr.sort(function (a, b) { if(a>b){ return 1; } return -1; }) console.log(arr) // [-7, 0, 1, 6, 44, 99, 145, 5555] console.log(arr1) // [-7, 0, 1, 6, 44, 99, 145, 5555]
原数组不变 结果放到一个新的数组中
数组常用方法之 concat
-
concat
是把多个数组进行拼接 -
和之前的方法有一些不一样的地方,就是
concat
不会改变原始数组,而是返回一个新的数组var arr = [1, 2, 3] // 使用 concat 方法拼接数组 var newArr = arr.concat([4, 5, 6]) console.log(arr) // [1, 2, 3] console.log(newArr) // [1, 2, 3, 4, 5, 6]
-
注意: concat 方法不会改变原始数组
-
数组常用方法之 join(数组转字符串的一个方法)
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
转字符串 | 无 | 将数组的每一个成员以逗号拼接成字符串 | 拼接完毕的字符串 | |
char(连接符) | 不以逗号拼接,而以char拼接 | 拼接完毕的字符串 |
var arr =['张三', '李四', '王五', '赵六']; var str = arr.join(); console.log(str); // 张三,李四,王五,赵六 var str1 = arr.join('+'); console.log(str1); // 张三+李四+王五+赵六 var str2 = arr.join('❤'); console.log(str2); // 张三❤李四❤王五❤赵六
slice() =>可用于复制
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
截取 | slice(0) | 从头截取到尾 | 新数组 | 不改变原数组 |
start | 从下标start截取到尾 | 新数组 | 不改变原数组 | |
start, end | 从start截取到end,不包含end | 新数组 | 不改变原数组 |
没有参数 var arr = ['张三', '李四', '王五', '赵六']; var arr1 = arr.slice(); console.log(arr1) // ["张三", "李四", "王五", "赵六"] 一个参数 var arr = ['张三', '李四', '王五', '赵六']; var arr2 = arr.slice(1); console.log(arr2) // ["李四", "王五", "赵六"] 两个参数 var arr = ['张三', '李四', '王五', '赵六']; var arr3 = arr.slice(1, 3); console.log(arr3) // ["李四", "王五"] //如果参数是负数 那么表示从后往前数 最后一个值是-1
indexOf()
作用 | 参数 | 结果 | 返回值 | 备注 |
---|---|---|---|---|
查找 | 数组 .indexOf('元素') | 从数组中查找元素的下标 | 下标值或-1 | 如果返回-1说明不存在 |
数组 .indexOf('元素','开始的位置') | 从开始的位置往后查找,元素在数组中第一次出现的位置 | 下标值或-1 | 如果返回-1说明不存在 |
var arr =['张三', '李四', '王五', '赵六']; var result = arr.indexOf('李四', 2); console.log(result); // -1 console.log(arr); // ['张三', '李四', '王五', '赵六']
lastIndexOf()
// 从右往左 语法: => 数组.lastIndexOf(数据) => 数组.lastIndexOf(数据, 开始的位置) 作用: 从右往左检索该数据第一次在该数组内出现的位置 返回值: => 如果在数组内找到了该数据, 那么就是该数据第一次出现的索引位置 => 如果在数据内没有找到该数据, 那么就是 -1
冒泡排序
-
先遍历数组,让挨着的两个进行比较,如果前一个比后一个大,那么就把两个换个位置数组遍历一遍以后,那么最后一个数字就是最大的那个了
-
然后进行第二遍的遍历,还是按照之前的规则,第二大的数字就会跑到倒数第二的位置以此类推,最后就会按照顺序把数组排好了
for(var i=0;i<arr.length-1;i++){ //多少趟,8个数字的数组,最多七趟 for(var j=0;j<arr.lenght-1-i;j++){//每一趟的次数 if(arr[j]>arr[j+1]){ //升序>降序< var temp = arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } }
选择排序
-
先假定数组中的第0个就是最小的数字的索引
-
然后遍历数组,只要有一个数字比我小,那么就替换之前记录的索引
-
知道数组遍历结束后,就能找到最小的那个索引,然后让最小的索引换到第0个的位置再来第二趟遍历,假定第1个是最小的数字的索引
-
在遍历一次数组,找到比我小的那个数字的索引遍历结束后换个位置
-
依次类推,也可以把数组排序好
eg: var arr = [9, 3, 6, 10, 2, 5, 11, 4, 1, 7]; for (var j = 0; j < arr2.length - 1; j++) { var minIndex = j; // 用来存放最小值的索引 for (var i = j+1; i < arr2.length; i++) { if (arr2[i] < arr2[minIndex]) { minIndex = i; } } var temp = arr[j]; arr[j] = arr[minIndex]; arr[minIndex] = temp; }
如何解决数组塌陷的问题
i--的方法: var arr = [2,4,5,5,6,6,6,6,7,7,7,8,8,8]; document.write(arr.length,'<br />') for(var i=0;i<arr.length;i++){ arr.splice(i,1); i--; } document.write(arr.length,'<br />') 倒着删除法 var arr = [2,4,5,5,6,6,6,6,7,7,7,8,8,8]; document.write(arr.length,'<br />') for(var i=arr.length;i>=0;i--){ arr.splice(i,1); } document.write(arr.length,'<br />')
ES5 中常见的数组常用方法
forEach(高阶函数)
-
forEach()
的时候传递的那个函数,会根据数组的长度执行 -
数组的长度是多少,这个函数就会执行多少回
-
和
for
循环一个作用,就是用来遍历数组的,是for的简化版,不可改变数据 -
语法:
arr.forEach(function (item, index, arr) {})
-
与getElementsByTagName获取数组时,需要加[]
var arr = [1, 2, 3] // 使用 forEach 遍历数组 arr.forEach(function (item, index, arr) { // item 数组中的每一项元素 // index 就是数组的索引 // arr 就是原始数组 console.log('数组的第 ' + index + ' 项的值是 ' + item + ',原始数组是', arr) }) // 数组的第0项的值是1;
map()
语法: 数组.map( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 映射数组,适用于整体加减 + 返回值: 和原始数组长度一样的数组, 只不过内部数据经过映射加工 + 注意: 映射条件以 return 的形式书写 eg: var arr = [1, 2, 3]; var arr1=arr.map(finction(item){ return item+100; }) document.write(arr1) //[101,102,103]
filter()
语法: 数组.filter( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 过滤数组 + 返回值: 必然是一个新数组, 内部存储的是原始数组内过滤出来的部分数据 + 注意: 过滤条件以 return 的形式书写
var arr = [ { type: "大菜", name: "鱼香肉丝", price: 10 }, { type: "大菜", name: "红烧肉", price: 10 }, { type: "大菜", name: "香辣粉", price: 10 }, { type: "中菜", name: "小炒肉", price: 13 }, { type: "中菜", name: "云吞", price: 14 }, { type: "小菜", name: "雪糕", price: 15 }, { type: "小菜", name: "黄瓜", price: 16 } ] var arr1 = arr.filter(function(item) { return item.price < 13 }) console.log(arr1) //0: {type: '大菜', name: '鱼香肉丝', price: 10} //1: {type: '大菜', name: '红烧肉', price: 10} //2: {type: '大菜', name: '香辣粉', price: 10}
find()
语法: 数组.find( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 在原始数组内查找满足条件的第一项 + 返回值: 找到的数据 + 注意: 查找条件以 return 的形式书写
var arr1 = prompt('请输入一个科目') //语文 var arr = [ { '科目': '政治', '成绩': 98 }, { '科目': '语文', '成绩': 78 }, { '科目': '数学', '成绩': 58 }, { '科目': '历史', '成绩': 93 }, { '科目': '物理', '成绩': 95 } ]; arr1 = arr.find(function (item) { return item['科目'] == arr1; }); console.log(arr1.成绩) //78
findIndex()
语法: 数组.findIndex( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 在原始数组内查找满足条件的第一项的索引 + 返回值: 找到的数据的索引 + 注意: 查找条件以 return 的形式书写
var arr=[9,9,1,4,7,10,6]; var arr1=arr.findIndex(function(item){ return item % 10==1; }); console.log(arr1) // 2
every()
语法: 数组.every( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 判断数组内是否每一个都满足条件 + 返回值: 一个布尔值 => true, 说明数组内每一个数据都满足条件 => false, 说明数组内至少有一个是不满足条件的 + 注意: 判断条件以 return 的形式书写
var arr = [ { '科目': '政治', '成绩': 98 }, { '科目': '语文', '成绩': 78 }, { '科目': '数学', '成绩': 58 }, { '科目': '历史', '成绩': 93 }, { '科目': '物理', '成绩': 95 } ]; var arr1=arr.every(function(item){ return item.成绩>=60; }) console.log(arr1)
some()
语法: 数组.some( function (item, index, value) {} ) => item: 表示数组的每一项 => index: 表示数组每一项的索引 => value: 表示原始数组 + 作用: 判断数组内是否有某一个满足条件 + 返回值: 一个布尔值 => true, 说明数组内至少有某一个是满足条件的 => false, 说明数组内所有的项都不满足条件 + 注意: 判断条件以 return 的形式书写
var arr = [ { '科目': '政治', '成绩': 98 }, { '科目': '语文', '成绩': 78 }, { '科目': '数学', '成绩': 58 }, { '科目': '历史', '成绩': 93 }, { '科目': '物理', '成绩': 95 } ]; var arr1=arr.some(function(item){ return item.成绩>=60; }) console.log(arr1)
reduce(reduceAll可以全部替换)
+ 语法: 数组.reduce(function (prev, item, index, origin) {}, init) => prev: 表示初始值或者上一次的运算结果 => item: 表示数组的每一项 => index: 表示数组每一项的索引 => origin: 表示原始数组 + 作用: 用来实现叠加效果 + 返回值: 最终叠加结果 + 注意: 叠加条件以 return 的形式书写 + 注意: prev 的值, 如果你传递了 init, 就是 init 的值, 如果你没有传递 init, 那么就是数组 [0] 的值 + 注意: 如果你传递了 init, 循环执行 length 次, 如果你没有传递 init, 循环执行 length - 1 次, 少的是第一次
var arr = [ { '科目': '政治', '成绩': 98 }, { '科目': '语文', '成绩': 78 }, { '科目': '数学', '成绩': 58 }, { '科目': '历史', '成绩': 93 }, { '科目': '物理', '成绩': 95 } ]; var arr1=arr.reduce(function(prev,item){ return prev+item.成绩; },0) console.log(arr1) // 422
reduceRight
同reduce,只是从数组的末尾开始运算
基本包装类型
-
原本只有对象才可以调用自己的静态属性和动态方法,但是系统给予了跟对象一样的权限可以使用属性和方法,所以字符串又称为基本包装类型
-
字符串、数值、布尔又称为基本包装类型
-
把简单数据类型包装成复杂数据类型
字符串常用方法
-
通用语法: 字符串.方法名()
-
注意: 所有的字符串常用方法都会不改变原始字符串, 而是以返回值形式给出结果
-
如果结果是字符串 也是一个新的字符串
字符串的创建方式
-
字符串 例 var str1 = 'helloworld';
-
内置构造函数 =>>new String()
-
例 var str4 = new String('qfedu');
字符串的遍历
语法:.length 用法:索引【】 跟数组一样,下标也是从0开始 eg: var str1 = '单反穷三代,dota毁一生'; alert(str1[4]); // 三
charAt()
+ 语法: 字符串.charAt(索引) + 返回值: 该索引位置的字符 => 如果没有该索引位置, 返回的是 空字符串
eg: var str = 'andy' for (var i=0;i<str.length;i++){ console.log(str.charAt(i)) } var str = '今天天气不错' var c = str.charAt(3) console.log(c); // 气
charCodeAt()
+ 语法: 字符串.charCodeAt(索引) + 返回值: 该索引位置字符的 unicode 编码 => 如果没有该索引位置, 返回的是 NaN eg: var str2 = 'i love you forever'; alert(str2.charCodeAt(3)); // o的unicode编码 111 a 97 以此类推
fromCharCode
语法:将 Unicode 编码转为一个字符 eg: var n = String.fromCharCode(65); //A
toUpperCase()
+ 语法: 字符串.toUpperCase() + 返回值: 将原始字符串内的所有字母转换成大写
var str = 'aAbBcCdD' console.log(str.toUpperCase()) // AABBCCDD
toLowerCase()
+ 语法: 字符串.toLowerCase() + 返回值: 将原始字符串内的所有字母转换成小写
substr()
+ 语法: 字符串.substr(开始索引, 截取多少个(length) + 返回值: 返回[start, start+length)之间的元素
var str = 'hello world'; console.log(str.substr(3));// lo world console.log(str.subst(3, 7)); // lo worl 从三开始往后数7个 //substr(-3) => substr(8) console.log(str.substr(-3));// rld //substr(3, -4) => substr(3, 0) console.log(str.substr(3, -4)); // ""(空字符串)
substring()
+ 语法: 字符串.substring(开始索引, 结束索引) + 特点: 包前不包后 + 返回值: 截取出来的部分字符串
var str = 'hello world'; console.log(str.substring(3));// lo world console.log(str.substring(3, 7)); // lo w //substring(-3) => substring(0) console.log(str.substring(-3));// hello world //substring(3, -4) => substring(3, 0) =>substring(0, 3) console.log(str.substring(3, -4)); // hel
slice()
+ 语法: 字符串.slice(开始索引, 结束索引) + 特点: 包前不包后, 填写负整数 + 返回值: 截取出来的部分字符串
var str = 'hello world'; console.log(str.slice(3)); // lo world console.log(str.slice(3, 7)); // lo w //slice(-3) => slice(8) console.log(str.slice(-3)); // rld //slice(3, -4) => slice(3, 7) console.log(str.slice(3, -4)); // lo w
split() ==>>字符转换为数组
+ 语法: 字符串.split('分隔符') + 返回值: 一个数组 => 按照分隔符把字符串分开成为几段内容
eg: var str = '1+2+3+4+5+6+7' var arr = str.split('+') console.log(arr) // ["1", "2", "3", "4", "5", "6", "7"]
indexOf()
+ 语法: 字符串.indexOf(查找的字符, 从左往右开始索引) + 返回值: => 如果原始字符串内有该字符串片段, 那么是该字符串片段第一次出现的首字母索引位置 => 如果原始字符串内没有该字符串片段, 那么是 -1
eg: var str = '改革春风吹满地,春天'; console.log(str.indexOf('春',3)); ==>>从索引号第三个位置开始往后查找,3可以省略,默认第一位开始
lastIndexOf()
+ 语法: 字符串.lastIndexOf(字符串片段, 从右往左开始索引) + 返回值: => 如果原始字符串内有该字符串片段, 那么是该字符串片段第一次出现的首字母索引位置 => 如果原始字符串内没有该字符串片段, 那么是 -1
concat()
作用 | 参数 | 描述 | 返回值 | 备注 |
---|---|---|---|---|
拼接字符串 | 任意个、任意类型 | 将参数与原字符串拼接 | 新字符串 | 参数将转为字符串 |
var str = 'a'; var result = str.concat('b') console.log(result) // ab
includes()
+ 语法: 字符串.includes(字符串片段) + 作用: 该字符串中是否包含该字符串片段 + 返回值: 一个布尔值 => true 说明有该字符串片段 => false 说明没有该字符串片段 eg: var str='撒谎法兰克福'; document.write(str.includes('法')) //true
startsWith()
+ 语法: 字符串.startsWith(字符串片段) + 作用: 判断该字符串是否以该字符串片段开头 + 返回值: 一个布尔值 => true 说明以该字符串片段开头 => false 说明不以该字符串片段开头
endsWith()
+ 语法: 字符串.endsWith(字符串片段) + 作用: 判断该字符串是否以该字符串片段结尾 + 返回值: 一个布尔值 => true 说明以该字符串片段结尾 => false 说明不以该字符串片段结尾
trim()
+ 语法: 字符串.trim() + 作用: 去除字符串首尾空白 + 返回值: 去除首尾空白后的字符串
trimStart() / trimLeft()
+ 语法: => 字符串.trimStart() => 字符串.trimLeft() + 返回值: 去除开始位置空白以后的字符串
trimEnd() / trimRight()
+ 语法: => 字符串.trimEnd() => 字符串.trimRight() + 返回值: 去除结束位置空白以后的字符串
repalce()
+ 语法: 字符串.replace(换下字符, 换上字符) + 作用: 替换原始字符串内的片段 + 注意: 只能替换一个 + 返回值: 替换好的字符串
eg: var str = 'andy'; console.log(str.repalce('a','b')) //bndy eg: var str = 'andyadaknaf'; while(strl.indexOf('a')!==-1){ str=str.repalce('a','*') } console.log(str)
repeat()
作用:重复的作用 eg: nut.repeat(‘5’) 把nut重复5遍
字符串的类型
// 普通字符串 '!@#$%^&ASDFGZXCVBNwersd1f' //数字字符串 '12345678' // html 格式字符串 '<h1>asdfasdf</h1>' // 查询字符串 https://www.baidu.com/s?wd=%E6%96%B0%E4%B9%A1%E4%B8%96%E7%95%8C%E6%9D%AF&rsv_spt=1&rsv_iqid=0x9aab659e000468bc&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=ib&rsv_sug3=27&rsv_sug1=17&rsv_sug7=100 // https:// http:// 传输协议 //www.baidu.com 域名 => 19.47.85.192 // s 路径 search 等同于 http://www.qfedu.com/html5/ html5 // ? 后边是查询字符串 // wd=cba // rsv_spt=1 // ie=utf-8
json
本质是字符串,键一定是双引号,值如果是字符串 也是双引号 作用:用来进行前后端交互
json 格式转成 js类型的数据
语法:JSON.parse(json格式字符串) eg: var testjson = '{"name":"zhangsan","age":18}'; console.log(typeof testjson); //string var res = JSON.parse(testjson); console.log(typeof res); //object 对象
js类型的数据格式 转成 json格式数据
语法:JSON.stringify(js格式的数据) eg: var testscore = [{'学号':'02', '姓名':'李四', '分数':90}, {'学号':'03', '姓名':'王五', '分数':70}, {'学号':'01', '姓名':'张三', '分数':60}] console.log(typeof testscore); //object var res = JSON.stringify(testscore); console.log(res,typeof res); //string
内置对象
Math 是 js 的一个内置对象,提供了一堆的方法帮助我们操作 数字
Math.random()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
随机数 | 无 | 0-1之间的随机小数 | [0-1) | 无法随机出1 |
var res=Math.random() console.log(res) // 0 ~ 1 eg: Math.floor(Math.random()*总数+第一个数) 求1-33的数 Math.floor(Math.random()*33+1)
Math.round()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
四舍五入 | 数字 | 将参数数字四舍五入 | 数字 | 舍,往负方向靠近;入,往正方向靠近 |
console.log(Math.round(4.5)); // 5 console.log(Math.round(4.4)); // 4 console.log(Math.round(-4.5)); // -4 console.log(Math.round(-4.2)); // -4 console.log(Math.round(-4.6)); // -5
Math.ceil()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
向上取整 | 数字 | 将一个数字向上取整 | 整数 | "上"指的是数轴正方向 |
result = Math.ceil(3.9) console.log(result); // 4 result = Math.ceil(3.1) console.log(result); // 4
Math.floor()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
向下取整 | 数字 | 将一个数字向下取整 | 整数 | "下"指的是数轴负方向 |
var result = Math.floor(3.9); console.log(result);// 3
Math.sqrt()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
开平方根 | 数字 | 求参数数字的正平方根 | 数字 |
console.log(Math.sqrt(4)) // 2
Math.max()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
求最大值 | 任意个数字 | 求任意个数字里最大的数 | 数字 | 不支持数组 |
console.log(Math.max(1, 55, 6789, -3)) // 6789
Math.min()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
求最小值 | 任意个数字 | 任意个数字里最小的数 | 数字 | 不支持数组 |
console.log(Math.min(1, 55, 6789, -3)) // -3
Math.abs()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
求绝对值 | 数字 | 将参数数字求绝对值 | 数字 | 点到原点的位置 |
console.log(Math.abs(56)); // 56 console.log(Math.abs(-56)); // 56
Math.pow()
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
幂运算 | 数字 | 数字 |
console.log(Math.pow(3,3)); // 27 console.log(Math.pow(3,-3)); // 负数开导 //0.037037037037037035 console.log(Math.pow(1,3)+Math.pow(5,3)+Math.pow(3,3)); // 153
Math.PI
作用 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
圆周率 | 数字 | 常量 | 数字 | 不要加() |
console.log(Math.PI); // 3.141592653589793
数字转换进制
.toString()
含义:可以在数字转成字符串的时候给出一个进制数 语法:.toString(你要转换的进制) 返回值:以字符串形式返回转换好进制的结果 不支持 100.toString(你要转换的进制),需要把100放进变量里 eg: var num = 100 console.log(num.toString(2)) // 1100100 console.log(num.toString(8)) // 144 console.log(num.toString(16)) // 64
parseInt()
含义:可以在字符串转成数字的时候把字符串当成多少进制转成十进制 语法:parseInt(要转换的字符串,当作几进制来转换 返回值:转换好十进制以后的数字(其他进制转10) eg: var str = 100 console.log(parseInt(str, 8)) // 64 //把 100 当作一个 八进制 的数字转换成 十进制 以后得到的 console.log(parseInt(str, 16)) // 256 //把 100 当作 十六进制 的数字转换成 十进制 以后得到的 console.log(parseInt(str, 2)) // 4 //把 100 当作 二进制 的数字转换成 十进制 以后得到的 console.log(parseInt('100')) //不写第二个参数 ,默认为是十进制
.toFixed
含义:保留小数点的位数 eg: var num1=0.30000023; console.log(num1.toFixed(2)) //0.30
日期(是一个函数)
Date 是 js 的一个内置对象,提供了一堆的方法帮助我们操作 时间
语法:var times=new Date()
参数传递规则:
-
不传递参数得到当前日期
eg: var d=new Date() console.log(d)
-
传递两个数字,第一个表示年,第二个表示月份 ,0是一月,11是12月
var time = new Date(2019, 00)
console.log(time) // Tue Jan 01 2019 00:00:00 GMT+0800 (中国标准时间)
-
传递三个数字,前两个不变,第三个表示该月份的第几天,从 1 到 31
var time = new Date(2019, 00, 05)
console.log(time) // Sat Jan 05 2019 00:00:00 GMT+0800 (中国标准时间)
-
传递四个数字,前三个不变,第四个表示当天的几点,从 0 到 23
var time = new Date(2019, 00, 05, 22)
console.log(time) // Sat Jan 05 2019 22:00:00 GMT+0800 (中国标准时间)
-
传递五个数字,前四个不变,第五个表示的是该小时的多少分钟,从 0 到 59
var time = new Date(2019, 00, 05, 22, 33)
console.log(time) // Sat Jan 05 2019 22:33:00 GMT+0800 (中国标准时间)
-
传递六个数字,前五个不变,第六个表示该分钟的多少秒,从 0 到 59
var time = new Date(2019, 00, 05, 22, 33, 55)
console.log(time) // Sat Jan 05 2019 22:33:55 GMT+0800 (中国标准时间)
-
传递一个字符串作为参数得到指定的日期
console.log(new Date('2019-02-03 13:13:13'))
// Sun Feb 03 2019 13:13:13 GMT+0800 (中国标准时间)
8.传递一个数字作为参数,该数字表示时间戳
每一个日期都有一个时间戳它是从1970年1月1号0点 0分0秒开始的毫秒值数字(格林威治时间)
eg: var d = new Date( 1000) ; console.log(d)
日期对象的方法
方法名称 | 参数 | 描述 | 结果 | 备注 |
---|---|---|---|---|
getFullYear() | 无 | 获取年份 | 年份数字 | |
getMonth() | 无 | 获取月份 | 月份数字 | 月份从0开始 |
getDate() | 无 | 获取日期 | 日期数字 | |
getHours() | 无 | 获取小时 | 小时数字 | |
getMinutes() | 无 | 获取分钟 | 分钟数字 | |
getSeconds() | 无 | 获取秒 | 秒数数字 | |
getMilliSeconds() | 无 | 获取毫秒 | 毫秒数字 | |
getTime() | 无 | 获取时间戳 | 1970-01-01 0:0:0至今的毫秒值 | js是13位,其他语言有的是10位 |
getDay() | 无 | 获取星期几 | 星期几数字 | 0表示周末 1表示周一 2表示周二 ... |
setFullYear() | 数字 | 设置年份 | 修改当前日期的年份 | |
setMonth() | 数字 | 设置月份 | 修改当前日期的月份 | 月份从0开始 |
setDate() | 数字 | 设置日期 | 修改当前日期的天数 | |
setHours() | 数字 | 设置小时 | 修改当前日期的小时 | |
setMinutes() | 数字 | 设置分钟 | 修改当前日期的分钟 | |
setSeconds() | 数字 | 设置秒数 | 修改当前日期的秒数 | |
setMilliseconds | 数字 | 设置毫秒 | 修改毫秒 | |
setTime() | 数字 | 修改时间戳 |
eg: var time = new Date(2019, 03, 03, 08, 00, 22) console.log(time.getFullYear()) // 2019 console.log(time.getMonth()) // 3
时间戳
1970年到你设置的时间之间的毫秒
var test=new Date();
console.log(test.getTime()) =>>返回当前的时间戳
两个日期相减 得到两个日期相差的毫秒值
BOM
-
Browser Object Model浏览器对象模型
-
它是JS的一个组成部分,主要是与浏览器相关的功能操作。
-
简单来说,就是window。
-
包含的功能有: 弹框、获取浏览器的尺寸、获取计算后样式、文档对象、历史记录、地址栏、打开、关闭窗口
浏览器尺寸
属性名 | 作用 | 备注 |
---|---|---|
innerWidth | 获取视口宽度 | 包含滚动条 |
innerHeight | 获取视口高度 | 包含滚动条 |
eg: console.log(window.innerWidth) console.log(window.innerHeight)
浏览器的弹窗(弹出层)
1、alert 警告框:在浏览器弹出一个提示框 eg:window.alert('我是一个提示框') ○ 这个弹出层知识一个提示内容,只有一个确定按钮 ○ 点击确定按钮以后,这个提示框就消失了 2、confirm 询问框:在浏览器弹出一个询问框 eg:var boo = window.confirm('我是一个询问框') console.log(boo) ○ 这个弹出层有一个询问信息和两个按钮 ○ 当你点击确定的时候,就会得到 true ○ 当你点击取消的时候,就会得到 false 3、prompt 输入框:在浏览器弹出一个输入框 ○ 这个弹出层有一个输入框和两个按钮 ○ 当你点击取消的时候,得到的是 null ○ 当你点击确定的时候得到的就是你输入的内容
历史记录
history对象负责历史记录操作
方法名 | 参数 | 作用 |
---|---|---|
forward() | window.history.forward() | 历史记录前进一次 |
back() | window.history.back() | 历史记录后退一次 |
go() | go(数字,正整数前进,0刷新一次,负整数后退) | 前进或后退或刷新 |
地址栏 =>> window.location
该对象负责地址栏相关操作
属性名 | 描述 | 备注 |
---|---|---|
protocol | 协议 | |
host | 主机 | |
hostname | 主机名 | |
port | 端口 | |
search | 查询信息 | |
pathname | 路径名 | |
href | 存储的是浏览器地址栏内 url 地址的信息 | 赋值后跳到给的那个地址 |
reload() | 刷新 | 不要写在全局,不然浏览器就会一直处在刷新状态 |
eg: location.href的例子: console.log(window.location.href) // 存储url信息 window.location.href = './index.html' //跳转 location.reload的例子: window.location.reload()
跳转页面的三种方式
方式 |
---|
location = "百度一下,你就知道" |
location.href = "百度一下,你就知道" |
location.assign("百度一下,你就知道") |
浏览器事件
事件名称 | 触发时机 | 演示 |
---|---|---|
scroll | 页面卷动 | window.onscroll = function(){} |
resize | 页面尺寸更改 | window.onresize = function() {} |
onload | 页面资源加载完毕再加载js | window.onload = function() {} //<body οnlοad="xing()"> |
浏览器滚动的距离
方法名 | 作用 | 备注 |
---|---|---|
scrollTop | 获取的是页面向上滚动的距离 | |
scrollLeft | 获取页面向左滚动的距离 |
eg: window.onscroll = function () { console.log(document.body.scrollTop) console.log(document.documentElement.scrollTop) //有 DOCTYPE 声明的时候 } window.onscroll = function () { console.log(document.body.scrollLeft) console.log(document.documentElement.scrollLeft) }
打开/关闭页面
方法名 | 作用 | 备注 |
---|---|---|
open() | 打开页面 | |
close() | 关闭页面 | 必须得是open方法打开的页面 |
var win=window.open('http://www.baidu.com') window.close();
页面卷动方法(需要配合延迟器使用)
方法一:(数字) window.scrollTo(x, y)(将页面滚动到指定的位置,每次从开头计算位置) eg: setTimeout(function(){ window.scrollTo(0, 2000) },1000) 方法二:(对象) window.scrollTo({ left: x, top: y, behavior: "smooth"(平滑效果) | "instant" }) (通过 behavior 控制动画效果,每次从当前位置计算) eg: window.onload = function(){ var btn = document.getElementById('mybtn'); btn.onclick = function(){ // window.scrollTo(200,1800); window.scrollTo({top:500,left:0,behavior:'smooth'}); } }
本地存储
本地存储是HTML5中新增的一个API对象,是一种前端存储数据的方式
语法:localStorage
作用:在浏览器端存储内容,永久存储
特点:只能够存储字符串,直接跨页面通讯
注意:基本类型 不能复杂类型 如果非要存复杂类型 转成 json 格式
操作: key: 存储时的键 value: 存储的值 增: //window.localStorage.setItem(key,value); 删: // window.localStorage.removeItem(key); // window.localStorage.clear(); //作用:清空数据 改: //window.localStorage.setItem(key,value); 查: //window.localStorage.getItem(key); 没有则返回null
会话存储 (临时存储)
语法:sessionStorage
特点:
1、不能永久保存,关闭页面就消失
2、可以跨页面通讯 但是要求其他页面必须 从这个页面跳转过去的
操作:和上面的一样
cookie和storage的区别
1.出现时间
cookie 有js的时候就有了
storage h5出现才有 html4 不支持
2. 存储大小
cookie 4k
storage 20m 左右
3. 前后端交互
cookie 自动携带 程序员不用管
storage 不会跟随请求自动携带
4.过期时间
cookie 能手动设置过期时间 默认关闭浏览器就 失效
storage 不能手动设置
5.作用
cookie 登录注册
storage 保持登录时间 加入购物车
定时器(异步代码)
语法: setInterval(handler,time) handler:函数,该函数会多次执行,执行间隔由time决定 time:间隔时间,是一个毫秒值数字 eg: setInterval(function () { var d = new Date(); var d1 = new Date("2022-12-25 0:0:0"); // 更新之后可以两个日期直接相减 就是时间戳 // var time = d1 - d; // 先转换成秒 // var seconds = parseInt(time / 1000) % 60; // 再转换成分钟 // var minutes = parseInt(time / 1000 / 60) % 60 // 再转为小时 // var hours = parseInt(time / 1000 / 60 / 60) % 24 // 再转为天数 // var days = parseInt(time / 1000 / 60 / 60 / 24); // document.write(`${days}天${hours}小时${minutes}分钟${seconds}秒`)}, 1000)
函数名 | 参数 | 作用 | 返回值 |
---|---|---|---|
setInterval() | 函数,间隔时间 | 每隔一定时间,执行一次函数 | 数字(定时器编号) |
setTimeout() | 函数,间隔时间 | 一定时间后,执行一次函数 | 数字(定时器编号) |
clearInterval() | 定时器编号 | 清除定时器 | 无 |
clearTimeout() | 定时器编号 | 清除延时器 | 无 |
延迟器(异步代码)
语法: setTimeout(handler,time) handler:函数,该函数会在time时间之后执行一次,执行间隔由time决定 time:间隔时间,是一个毫秒值数字 eg: setTimeout( function () { console.log(1) }, 1000)
任务队列
-
js是单线程,但是浏览器的多线程,当执行setTimot或者setInterval的时候,其实是让浏览器帮忙计时,到了时间之后,浏览器就会把这个函数还给JS
-
任何异步代码,不管时间多短,只要是异步,一定在同步代码之后执行
问题: 如何还回来的是时候 JS正在执行代码怎么办? 答:浏览器会将函数放入JS的执行队列, 至于JS执行还是不执行与浏览器无关 ,于是可以得出结论,定时器和延时器的时间其实是放入队列的时间, 而不是执行时间
DOM(类数组也称伪数组)
操作元素样式(获取非行内)
语法:getComputedStyle() eg: <div id="box"></div> <script> var cssObj = window.getComputedStyle(box); // 获取box元素的CSS样式对象 console.log(cssObj.display) // 获取display属性 console.log(cssObj.backgroundColor) // css中的带-的属性 我们在js中要去掉- 并把后面的首字母转大写 console.log(cssObj['background-color']) // 或者使用方括号语法 </script>
特殊元素
元素名称 | 获取方式 | 备注 |
---|---|---|
body | document.body | |
head | document.head | |
html | document.documentElement | |
title | document.title | 文本 |
表单集合 | document.forms | |
表单中的表单元素集合 | form.elements |
eg: console.log(document.body)
通用方式(一般是获取行内)
获取方式 | 解释 | 返回值 |
---|---|---|
document.getElementById | 根据id获取 | 单个元素或者null |
getElementsByTagName | 根据标签名获取 | 类数组对象 |
getElementsByClassName | 根据类名获取 | 类数组对象 |
getElementsByName | 返回 带有指定name属性的节点列表 | 类数组对象 |
querySelector(静态,更接近纯数组) | 根据选择器获取一个 | 单个元素 |
querySelectorAll(静态) | 根据选择器获取一组 | 类数组对象 |
eg: 操作class类名 <div class="one"></div> <script> var one=document.getElementsByClassName('one') 或者 var one=document.querySelector('.one') </script>
元素属性
属性的划分:
-
HTML标准属性
-
自定义属性
HTML标准属性又分为:通用属性和特有属性
操作标准属性:直接打点或者方括号 eg: • div.id = "good"; • /div["id"] = "hello"
操作class的时候为了避免和JS中的class关键字冲突 改名为className • div.className = "good"
标准属性
划分 | 举例 | 操作方式 | 备注 |
---|---|---|---|
通用属性 | id、class、style、lang... | 方括号语法点语法 | 每一个元素都有的属性 |
特有属性 | src、type、value、href... | 方括号语法点语法 | 不是每一个元素都有的属性 |
自定义属性(以data- 开头)
操作方式 | 参数 | 作用 | 备注 |
---|---|---|---|
getAttribute | 属性名 | 获取属性指定的属性值 | 可以操作标准属性 |
setAttribute | 属性名,属性值 | 设置指定属性名和属性值 | 可以操作标准属性 |
removeAttribute | 属性名 | 移除指定属性 | 可以操作标准属性 |
操作自定义属性(原生属性也可以操作)
-
查看自定义属性
var xxx = div.getAttribute("data-xxx") console.log(xxx)
-
增加自定义属性
div.setAttribute("data-zzz", "千锋")
-
删除自定义属性
div.removeAttribute("data-xxx") console.log(div)
-
自定义属推荐以data-开头 浏览器会自动的把每一个data-开头的属性都放在该元素的dataset属性集合里面
console.log(div.dataset)
特殊的自定义属性
checked disabled selected 读取拿到布尔类型 写 也是给布尔类型 inputele=document.querySelector('input'); // alert(inputele.disabled) // 原声属性 元素.属性 true inputele.disabled = false
操作元素类名
className:元素.className=‘值’ //完全覆盖式的书写 追加元素:元素.className+=‘值’ classList: 追加元素:元素.classList.add(类名) 删除元素:元素.classList.remove(类名) 切换元素:元素.classList.toggle(类名)
操作元素内容
innerHTML:元素.innerHTML=‘值’ eg: h1.innerHTML = "<span> 321</span>" 如果包含标签的话 该标签会真的被当做HTML标签渲染,获得这个标签里面的全部内容 把元素设置到页面中 innerText:元素.innerText=‘值’ eg: h1.innerText = "<span> 321</span>" 不论是不是标签文本 统一当做纯文本处理,获得这个标签里面的文字 把元素设置到页面中 value(获取表单元素中的内容): 表单元素.value=‘值’
节点(Node)
节点分类和属性
(元素节点是标签)
节点分类 | 含义 | nodeType(节点类型) | nodeName(节点名称) | nodeValue(节点的值) |
---|---|---|---|---|
元素节点 | 页面上的标签 | 1 | 标签名(大写) | null |
属性节点 | 标签上的属性(不作为独立节点出现, 不和任何节点产生父子关系) | 2 | 属性名 | 属性值 |
文本节点 | 在标签对内的文本内容(包含换行和空格) | 3 | #text | 文本内容 |
CDTAT节点 | 4 | #cdata-section | CDATA区域的内容 | |
实体引用名称节点 | 5 | 引用名称 | null | |
实体名称节点 | 6 | 实体名称 | null | |
处理指令节点 | 7 | target | entire content cluding the target | |
注释节点 | (包含换行和空格) | 8 | #comment | 注释内容 |
文档节点 | 9 | #document | null |
以上节点中,只需要记忆 1 2 3 8 9 这五种节点即可。
eg: <div id="test" class="kangbazi"> hello <!-- 这是注释 --> <p>test</p> </div> var divEle = document.getElementById('test'); // 属性节点 var ele = divEle.attributes[1]; //文本节点 var text = divEle.childNodes[0]; //注释节点 var comment = divEle.childNodes[1]; // 元素节点 var childele = divEle.childNodes[3]; // console.log('元素节点:',childele.nodeType); 1 // console.log('文本节点:',text.nodeType); // console.log('属性节点:',ele.nodeType); // console.log('注释节点:',comment.nodeType); // console.log('元素节点:',childele.nodeName); p // console.log('属性节点:',ele.nodeName); // console.log('文本节点:',text.nodeName); // console.log('注释节点:',comment.nodeName); // console.log('元素节点:',childele.nodeValue); // console.log('属性节点:',ele.nodeValue); kangbazi // console.log('文本节点:',text.nodeValue); // console.log('注释节点:',comment.nodeValue);
节点关系(元素是节点,节点不一定是元素)
兄弟关系 | 节点释义 | 备注 |
---|---|---|
nextSibling | 下一个节点兄弟 | |
nextElementSibling | 下一个元素兄弟 | |
previousSibling | 前一个节点兄弟 | |
previousElementSibling | 前一个元素兄弟 | |
父子关系 | ||
childNodes | 所有的子节点集合 | 类数组对象 |
children | 所有的子元素节点集合(单指一个具体的) | 类数组对象 |
firstChild | 第一个子节点 | |
firstElementChild | 第一个子元素节点(单指一个具体的) | |
lastChild | 最后一个子节点 | |
lastElementChild | 最后一个子元素节点(单指一个具体的) | |
childNodes[下标] | 中间的需要这个来获取 | |
attributes | 节点的所有属性节点 |
子父关系 | parentNode和parentElement对于除了HTML元素之外的元素来说 都一样 |
---|---|
parentNode | 父节点(获取文档层次中的父对象) |
parentElement | 父元素(获取对象层次中的父对象) |
eg: <span>div的堂哥</span> <div class="test" id="box"> hello <p>你好</p> world <p>千锋</p> <!-- 我是注释 --> </div> <span>div的堂弟</span> var divEle = document.getElementsByTagName('div')[0]; // console.log(divEle.childNodes,divEle.childNodes.length); // 7
元素操作(只能通过父节点来操作子节点)
方法名称 | 参数 | 作用 | 返回值 |
---|---|---|---|
document.createElement(’元素‘) | 标签名字符串 | 创建元素节点 | 元素节点 |
document.createTextNone(‘文本’) | 文本字符串 | 创建文本节点 | 文本节点 |
document.createComment | 文本字符串 | 创建注释节点 | 注释节点 |
createDocumentFragment | 无 | 创建文档碎片(用于提高性能) | 文档碎片 |
父元素.appendChild(子节点) | 元素 | 将元素设置为最后子元素 | |
父元素.removeChild(子元素) | 元素 | 将元素从父元素中移除 | |
元素.remove() | 无 | 删除自身元素 | |
父元素.insertBefore(子节点,谁的前面) | 新元素,老元素 | 将新元素加入到老元素之前 | |
父元素.replaceChild(新元素,老元素) | 新元素,老元素 | 用新元素替换老元素 | |
节点.cloneNode(参数),参数默认是false,不克隆后代,true 克隆后代节点 | 布尔值 | 克隆一个元素 |
eg: <div>我是第一</div> var olds=document.querySelector('div'); var news=document.createElement('div'); news.innerHTML='我是第二'; olds.appendChild(news); //我是第一,我是第二 父元素.insertBefore(新的子元素,老的子元素) var p = document.createElement("p"); var box1 = document.getElementById("box1") var box2 = document.getElementById("box2") document.body.insertBefore(p, box2) 父元素.replaceChild(新的子元素, 被替换的子元素) var p = document.createElement("p"); var box1 = document.getElementById("box1") document.body.replaceChild(p, box1) 元素.cloneNode(boolean) boolean如果为true 会连子元素一起克隆 否则只克隆自身 var box1 = document.getElementById("box1"); var box1C = box1.cloneNode(true) console.log(box1C)
快捷尺寸(★★★)
属性名 | 释义 | 备注 |
---|---|---|
clientWidth | 内容宽与左右padding之和 | 只读 |
clientHeight | 内容高与上下padding之和 | 只读 |
offsetWidth | 内容宽与左右padding与左右border宽度之和 | 只读 |
offsetHeight | 内容高与上下padding与上下border宽度之和 | 只读 |
clientLeft | 左边框宽度 | 只读 |
clientTop | 上边框宽度 | 只读 |
scrollTop | 页面卷动值 | 可读可写 |
scrollY | 页面卷动值 | 不可修改 |
div { width: 100px; height: 50px ; padding: 20px; border: 20px solid red; }
var div = document.getElementById("div"); console.log(div.clientWidth); // 输出 140px console.log(div.clientHeight); // 输出 90px console.log(div.offsetWidth); // 输出 180px 内容宽 100 + padding 40 + border 40 console.log(div.clientWidth); // 输出 130px 内容高 50 + padding 40 + border 40
快捷位置(获取元素偏移量)
属性名 | |||
---|---|---|---|
定位父元素的概念 | 离自己最近的祖先元素中最先拥有定位属性的元素 | ||
offsetParent | 定位父元素 | 没有定位 也会找到祖先元素中距自己最近的拥有定位的元素,如果都没有 就是body | |
offsetLeft | 自己左边框到定位父元素的左边框 | ||
offsetTop | 自己上边框到定位父元素的上边框 |
获取可视窗口的尺寸
属性名 | 作用 | 备注 |
---|---|---|
clientWidth | 获取宽度 | 不包含滚动条宽度 |
clientHeight | 获取高度 | 不包含滚动条高度 |
其他属性
#console.log(e.ctrlKey , e.shiftKey, e.altKey) =>>这三个属性表示键盘上的ctrl shift alt键是否被按下 # ltarget 目标:console.log(e.target) # e.target可以利用它来实现委托模式 a(元素).classList.add( "classname1") ;添加一个类名 a.classList.remove( "classname2") ;去掉一个类名
事件
浏览器设计的一套处理用户行为的机制。
事件的组成(三要素)
元素(也叫作事件源) =>绑定在谁身上 |
---|
事件类型 =>什么事件 |
事件处理函数(事件函数) =>触发这个事件后,执行的函数 |
事件的分类
事件分类 | 事件名称 | 通俗称呼 | 事件触发时机 |
---|---|---|---|
鼠标事件 | (前面最好带个on)click | 点击事件 | 鼠标单击之后(抬起之后) |
ondblclick | 双击事件 | 鼠标双击之后 | |
onmousedown | 按下事件 | 鼠标按下之后(不必抬起) | |
onmouseup | 抬起事件 | 鼠标抬起之后 | |
onmouseleave | 离开事件 | 鼠标离开元素范围 | |
onmouseenter | 进入事件 | 鼠标进入元素范围(只会经过自身盒子触发) | |
onmouseout | 移出事件 | 鼠标移出元素范围 | |
mouseover | 进入事件 | 鼠标进入元素范围(鼠标经过自身盒子会触发,经过子盒子还会触发,支持事件冒泡) | |
contextmenu | 右击事件 | 鼠标右击之后(抬起之后) | |
onmousemove | 鼠标移动 | 鼠标移动 | |
键盘事件 | keydown | 按下事件 | 键盘键按下 |
keyup | 抬起事件 | 键盘键抬起 | |
keypress | 输入事件 | 有内容输入(功能键不会触发) | |
浏览器事件 | onload | 加载完成 | 页面资源加载完毕之后再执行js |
scroll | 页面卷动 | 视口在页面中上下滚动时 | |
resize | 尺寸改变 | 窗口的尺寸发生变化时 | |
表单元素事件 | onfocus | 获取焦点 | 获取焦点时 |
onblur | 失去焦点 | 失去焦点时 | |
change | 内容改变 | 内容改变 | |
oninput | 输入内容 | 输入内容时 | |
submit | 提交表单 | 提交表单时(必须绑定在form时有效果) | |
reset | 重置表单 | 重置表单时 | |
触摸事件 | touchstart | 开始触摸 | 接触到屏幕的瞬间 |
touchmove | 手指在屏幕上触摸移动 | ||
touchend | 手指离开屏幕的瞬间 | ||
拖拽事件 | dragstart | 即将进入移动状态的瞬间触发 | |
drag | 拖拽的元素在移动的时候 实时触发 | ||
dragend | 拖拽元素放手的时候触发 | ||
dragenter | 拖放 | 拖拽元素进入拖放元素范围的时候才触发 光标进入 | |
dranleave | 拖拽元素离开拖放元素范围的时候才触发 光标离开 | ||
dragover | 拖拽元素完全进入拖放元素范围的时候才触发 | ||
drop | 交换位置 | 必须要dragover事件触发 |
eg: inp. onblur = function( ) { console.log(1) } 一般事件后面都加一个 = function( ) {} onclick的操作: <body οnclick=""> 或者 <script> var zb; var yb; window.οnlοad=function(){ zb=document.... } </script> drop的操作:(第一和第二的图交换位置) <div draggable="true"></div> <p></p> var divEle = document.querySelector('div'); var pEle = document.querySelector('p'); pEle.ondragover = function(){ return false } pEle.ondrop = function(){ var left = window.getComputedStyle(divEle).left; var top = window.getComputedStyle(divEle).top; divEle.style.left = window.getComputedStyle(pEle).left; divEle.style.top = window.getComputedStyle(pEle).top; pEle.style.left = left pEle.style.top = top }
事件对象
当事件触发的时候 会产生很多的信息 这些信息被封装成一个对象 并传递到事件处理函数中
div.onclick = function(e) { // e 就是事件对象 我们可以根据它获取到许多的信息 }
鼠标事件对象属性 | 作用 | 备注 |
---|---|---|
altKey | 获取alt键是否按下 | 默认为false |
ctrlKey | 获取ctrl键是否按下 | 默认为false |
shiftKey | 获取shift键是否按下 | 默认为false |
offsetX/Y | 获取鼠标距元素左/上侧内边框的像素值 | 不包含边框 内边距 外边距 |
clientX/Y | 获取鼠标距视口左/上侧的像素值 | 鼠标在视口内的位置 |
pageX/Y | 获取鼠标距页面左/上侧的像素值 | 包含边框 内边距 外边距 |
target | 获取触发事件的元素(最精确元素) | |
currentTarget | 获取绑定事件的元素 | |
键盘事件对象属性 | ||
key | 获取键盘上的字符 | |
keyCode | 获取键盘上的字符对应的键码 |
事件绑定(DOM 0级)
-
绑定
-
事件源.on事件类型 = 事件处理函数
-
同一个事件源的同一个事件类型只能够绑定一个事件处理函数,因为它是对属性进行赋值
-
同一个事件源可以绑定多个不同的事件类型
-
-
移除
-
事件源.on事件类型 = null
-
缺点:1 可以直接被人得到
2 只能添加一个事件处理函数
3 不能添加到捕获阶段
事件监听(DOM 2级)
语法: 事件源.addEventListener(‘事件类型’,事件处理函数,布尔值(可忽略))
-
绑定
-
事件源.addEventListener(type, handler, boolean)
-
type: 事件类型字符串 不带on
-
handler: 事件处理函数
-
boolean: 布尔值 决定绑定到捕获阶段还是冒泡阶段 默认是false false表示冒泡,true绑定到捕获阶段
-
-
-
结论: 可以通过addEventListener方法进行多个事件函数的绑定 执行时是按照代码的书写顺序执行 因为代码的书写顺序决定了绑定顺序
-
移除
-
document.removeEventListener(type, handler, boolean);
-
type: 事件类型字符串 不带on
-
handler: 事件处理函数 一定要保证函数地址是绑定的那个(方法不加括号)
-
boolean: 布尔值 决定移除的是捕获阶段还是冒泡阶段 默认是false false表示冒泡,true绑定到捕获阶段
-
-
-
结论: 第二个参数是要移除的函数 函数是引用类型 引用类型的比较的是地址 所以一定要保证 移除的函数是当初绑定的那个函数本身
eg: <div></div> <button>解绑</button> var divEle = document.querySelector('div'); var btn = document.querySelector('button'); // btn.onclick = function(){ // console.log('被绑定了') // } // btn.onclick = null;//解除绑定 function test(){ alert('我是dom2') } btn.addEventListener('click',test); //不要加小括号 btn.addEventListener('click',function(){alert('我也是')}); btn.removeEventListener('click',test); // test方法不再执行 btn.removeEventListener('click',function(){alert('我也是')}); // 这种方式不能解绑,绑定和解绑的时候,要把函数单独写出来
事件流程(事件传播)
当同一系列的元素,都具备点击事件,且点击最内层的元素时,事件该如何触发?
可能性1:先执行最内层的点击事件,最后执行最顶层点击事件
可能性2:先执行最顶层的点击事件,最后执行最内层点击事件
事件流程 | 描述 | 备注 |
---|---|---|
事件捕获 | 事件从最顶层元素,逐层向下,直至最精确元素 | 先捕获 |
事件冒泡 | 事件从最精确元素,逐层向上,直至最顶层元素(默认为冒泡,false) | 再冒泡 |
阻止冒泡
-
高级浏览器中 可以通过e.stopPropagation() 进行阻止事件的冒泡
-
低级中,通过.cancelbubble=true进行阻止事件的冒泡
// 高级浏览器中 // box1是box2的父元素 var box1 = document.querySelector(".box1"); var box2 = document.querySelector(".box2"); box1.onclick = function() { console.log("这是BOX1"); } box2.onclick = function(e) { e.stopPropagation(); console.log("这是BOX2"); }
停止默认行为
浏览器的一些事件中,带有一些默认行为 比如a标签的点击事件中 会带有跳转页面的行为 表单的点击事件中 带有提交的默认行为 滚轮事件中 带有改变页面卷动值的默认行为
-
高级浏览器中 可以通过 e.preventDefault() 阻止默认行为
// 获取元素 var a = document.getElementsByTagName("a")[0]; // 设置点击事件 a.addEventListener("click", function(e) { console.log("点击了a标签1111"); e.preventDefault(); }, false);
-
DOM0级事件绑定方式中,可以通过return false进行阻止默认行为
// 获取元素 var a = document.getElementsByTagName("a")[0]; // 设置点击事件 a.onclick = function() { return false; }
-
加一个这个
<a href="javascript:;http...">
事件委托
事件委托也叫作事件代理,是一种设计模式,就算将事件委托给不可被移除的父元素。
三大优点:
-
减少事件数量
-
通过s脚本动态生成的元素也有事件
-
防止内存泄漏
target: ● target这个属性是事件对象里的属性,表示你点击的目标 ● 当你触发点击事件的时候,你点击在哪个元素上,target就是那个元素 eg: // 1 获取元素 获取不可能被移除的父元素 var tbody = document.querySelector("tbody"); // 2 给tbody绑定事件 tbody.onclick = function(e) { // e.target 这个属性指向触发事件的元素 console.log(e.target) // 判定 点击到的是什么 if (e.target.className === "del") { // 点击到的是移除按钮 e.target.parentNode.remove(); } }
循环绑定事件时i的问题
var arr = [li, li, li]; for (var i = 0; i < arr.length; i++) { arr[i].onclick = function() { console.log(i); } } 点击时发现问题:点击时因为循环已经结束,所以输出的是3。而不是预想中的 0 1 2.
解决方案1: 添加自定义JS属性 eg: for (let i = 0; i < arr.length; i++) { // 给每一个元素 添加一个自定义的JS属性 arr[i].dataset.index = i; arr[i].onclick = function() { // 再在函数中,通过this访问自定义属性 console.log(this.dataset.index) } } 解决方案2:数组的forEach方法: eg: arr.forEach(function(value, index) { value.onclick = function() { console.log(index) } })
严格模式
语法:'use strict' =>不再执行预解析 eg: <script> // 开启严格模式 //要求:必须在当前作用域的第一行(除了注释之外) 作用域分全局和局部 严格模式也就分了全局和局部 如果在全局中书写,则开启全局严格模式 如果在函数中书写,则开启局部严格模式 'use strict'; ... // 局部严格模式 var a = function () { 'use strict'; c = 10; } b = 10; a(); </script>
ES6
let关键字
-
用于定义变量
-
声明的变量的值可以改变
-
不允许重复声明变量
-
声明的时候可以不赋值
const关键字
-
用于定义常量
-
声明的变量的值不可以改变
-
不允许重复声明变量
-
声明的时候不可以不赋值
展开运算符
语法:[...变量] eg: var arr=[1,2,3]; console.log(...arr) = console.log(1,2,3) // 1,2,3
展开对象
语法:...对象名 eg: var obj1={ name:'小明', age:18, sex:'男' }; var obj2={ ...obj1, tel:'123124' }; console.log(obj2)
函数默认值
eg: function sf(n=1){ console.log(n*n); } sf(3); // 9 sf(); // 1
解构
数组不可间隔解构,对象可以 数组解构: leg arr=[1,2,3]; let [a,b,c]=arr; console.log(a,b,c) //1,2,3 对象解构: let obj={ name:'小明', age:18, sex:'男' } let{name,age,sex}=obj; console.log(name); //小明 console.log(age); //18
同构
数组同构 =>和之前无区别 对象同构: let sid='s002',sname='李四',age=20; let obj={sid,sname,age} console.log(obj)