JS基础一
了解:是一种嵌入嵌入在网页中的程序段,解释性语言,被浏览器解释执行。ECMA标准化。ES6深入理解及学习
作用:JS增删改查,在html网页动态写入文本,响应事件作出相应的处理。事件绑定,页面特效。本地存储,cookie的一些应用。服务端的应用,如node.js。第三方库中专业应用,如three.js,echar.js,baidumap.js,date.js。
JS基础二
架构体系
核心语言定义、原生对象和内置对象、BOM(Browser Object Model)、DOM(Document Object Model)、事件处理模型。
四种使用JS的方式
- 内嵌式
<script type='text/javascript'>
//...
</script>
- 引入外部JS文件
<script src=''></script>
- 直接编写在元素的事件属性中,on开头
<button onclick=''>Click me</button>
4.伪URL方法(a标签href属性写入js代码)
<a href="javascript:window.alert('Hello word')"></a>
注释、变量、标识符、输入输出
标识符:变量,常量,数组,函数,文件,类型名等
关键字:在JS系统中有特殊意义的单词。
保留字:关键字的备胎。
例:
关键字保留字等不可作为标识符。
const定义常量,常量名全部大写初始化后,不能修改
//单行注释
/*多行注释*/
//声明变量
var a = 1;
//定义常量,常量名全部大写初始化后,不能修改
const PI = 3.14
常用输入输出:
输出
document.write(),document.writeln()会输出一个值加一个空格,alert(),console.log()
输入
window.prompt()
<script type="text/javascript">
console.log('window.prompt()',window.prompt())
</script>
JS数据类型及转换
基本类型:
浮点数的四舍五入:
undefined:变量声明但未初始化,函数无明确返回值时。
null:从undefined派生出来的,表示不存在的对象。(空对象)
null==undefined true(值相同)
null===undefined false(类型不同)
细说null和undefined
- 定义
(1)undefined:是所有没有赋值变量的默认值,自动赋值。
(2)null:主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。
- 何时使用null?
当使用完一个比较大的对象时,需要对其进行释放内存时,设置为 null。
- null 与 undefined 的异同点是什么呢?
共同点:都是原始类型,保存在栈中变量本地。
不同点:
(1)undefined——表示变量声明过但并未赋过值。
它是所有未赋值变量默认值,例如:
var a; // a 自动被赋值为 undefined
(2)null——表示一个变量将来可能指向一个对象。
一般用于主动释放指向对象的引用,例如:
var emps = [‘ss’,‘nn’];
emps = null; // 释放指向数组的引用
- 延伸——垃圾回收站
它是专门释放对象内存的一个程序。
(1)在底层,后台伴随当前程序同时运行;引擎会定时自动调用垃圾回收期;
(2)总有一个对象不再被任何变量引用时,才释放。
两等号和三等号
- ===:称为等同符,当两边值的类型相同时,直接比较值,若类型不相同,直接返回false;
- ==:称为等值符,当等号两边的类型相同时,直接比较值是否相等,若不相同,则先转化为类型相同的值,再进行比较;
- NaN==NaN //返回false,NaN和所有值包括自己都不相等
值类型(栈存储从上往下)
定义为undefined、数字、字符串、布尔型、Symbol(‘s’)
引用类型(堆存储从下往上、栈存储,赋值的是内存地址)
对象、数组、null(特殊的引用类型,指针指向为空地址)、函数(特殊的引用类型)
<script>
//值类型
let a = 100
let b = a
a = 200
console.log(b) //100
//引用类型
let c = { age: 20 }
let d = c
c.age = 21
console.log(d.age) //21
</script>
typeof
typeof作用:识别所有值类型,识别函数、判断是否为引用类型(不可细分)object
typeof(NaN) // ‘number’
数值的转换
转为boolean值:
- string:有值为true,空字符串为false
- undefined,null转换都为false
- 数值:非0为true(如Boolean(-1.34)为true)
Boolean(string1,number1,boolean1,undefined,null)
Boolean("") //false
Boolean(" ") //true
Boolean(undefined) //false
Boolean(null) //false
Boolean(-1.34)//true
转为字符串
方法:String(),toString(),加法+
String(number) //'29'
String(boolean) //'true'
String(undefined) //'undefined'
String(null) //'null'
number.toString() //'29'
boolean.toString() //'true'
'123'+1 // '1231'
1+'123' // '1123'
'123'+true // '123true'
'123'+'a' // '123a'
一个变量未初始化为undefined不能使用toString()方法
空对象为null也不能使用toString()方法
转数字
方法:Number(),parseInt(),parseFloat()
-
Number():undefined——NaN,null——0,转为数字。
-
parseInt():undefined——NaN,null——NaN,转为整数。把字符串从左往右转换,遇到非有效数字符号停止转换,如果第一个字符就是非有效数字符号,则返回NaN,如果转换成功一部分则返回转换成功的数字,执行的是一种部分转换。
-
parseFloat():undefined——NaN,null——NaN,转为浮点数。把字符串转换为浮点数,有效数字符号包含小数点。
Number(true) // 1
Number('123') // 123
Number('a123') // NaN
Number('.123') // 0.123
Number('.123.1') // NaN
Number('-123.1') // -123.1
Number('+123.1') // 123.1
Number(undefined) // NaN
Number(null) // 0
parseInt('.123')//NaN
parseInt('123.123')//123
parseInt('asd.123')//NaN
parsenInt('-12hello123')//-12
parseFloat('.123')//0.123
parseFloat('123.123')//123.123
parseFloat('asd.123')//NaN
parseFloat('123.123.99')//123.123
parseFloat('.-12hello123')// NaN
parseFloat('.12hello123') // 0.12
parseFloat('-12hello123')//-12
JS中的特殊符号
空格,<,>,版权符号,&符号
 ;<,>,©,&
转义符:
JS运算符与表达式
赋值运算符:=
算术运算符:+,-,*,/,%(取模,求余数)
运算优先级:先乘除模后加减
注:
3/5:0.6
3%5:3
关系运算符:
!==:完全相等时为false
&&:
!优先级最高:
++、–
JS结构
-
顺序结构
代码按照由上到下的顺序一行一行地执行。程序执行过程中没有分支、没有重复,这种结构称为顺序结构 -
选择结构
通过对一定条件判断之后,选择将要执行的语句。它可以分为简单选择和多分支选择。
if else、switch(不写break继续执行后面的case语句) -
循环结构
循环结构也叫重复结构,是指重复执行一个或几个模块,直到满足某一条件为止。
while、for:先判断后做事。
do-while:先做事后判断。
switch与if else的区别
对于switch语句来说,起实际是使用一个跳转表实现分支结构,不需要一次进行比较每一个所需要的条件。进行比较的次数为1。很明显对于if else语句,最少的比较次数为1,跟switch相比,在时间方面,switch语句的执行速度比if else要快,但是在程序执行占用的空间方面,switch语句需要一张跳转表来维护。这个跳转,表的本质是一个拥有标号的数组,需要额外的存储空间,if else语句的空间效率更好一点。switch是一个很典型的空间换时间的例子。但是switch只能判断是一个指定值的数据,而不能对一个区间中的数据进行判断。这时候选择if…else语句是一个很好的选择。
Math
Math对象是一个内置对象,对象不需要使用NEW运算符来创建,使用时直接使用Math作为对象名。
Math.random
生成随机数:Math.random() // [0,1)
生成固定范围的随机数:
结论:parseInt(Math.random()*(大-小+1)+小)
Math.round
四舍五入
Math.round(12.445) // 12
Math.round(12.534) // 13
Math.ceil
向上取最小整数,比12.xxx大的数里面最小的
Math.ceil(12.034) // 13
Math.ceil(12.6649) // 13
Math.ceil(12.904) // 13
Math.floor
向下取最大整数,比12.xxx小的数里面最大的
Math.ceil(12.034) // 12
Math.ceil(12.6649) // 12
Math.ceil(12.904) // 12
Math.pow
求次方
Math.pow(3,5) //为3的5次方
Math.abs
绝对值
Math.abs(-1.231) // 1.231
Math.max Math.min
最大值,最小值
Math.max(3,5,-1,35) //35
Math.min(3,5,-1,35) //-1
数组
创建数组的方法
- 通过new运算符,从Array原型实例化一个数组实例对象
- []
- Array()把原型对象当函数来调用,返回一个空的数组。
var arr = new Array(); // [],一个长度为0的空数组
var arr2 = new Array(5); //返回一个长度为5的数组对象,但是没有数组元素
var arr3 = new Array(21,2,99,-1,85) // [21,2,99,-1,85]
var arr4 = [] // 直接创建一个空数组
var arr5 = Array() //
数组的相关属性
- length,获取数组长度。
var arr = [4,0,0,1]
arr.length //4
- 由下标获取数组的具体值,下标由0开始。当使用下标数字超出有效的下标范围时就叫下标越界。下标越界在JS中不报错,只是值为undefined。
var arr = ['哈哈','abc',0,1]
arr[0] //'哈哈'
- arr[arr.length]=‘newItem’,length当数组下标变量使用时,实现在数组末尾增加一个新的数组元素。
数组对象的常用方法
增加数组元素:push、unshift
- arr[arr.length]=‘newItem’:数组末尾新增数组元素
- Array.push(value,…):数组末尾新增数组元素,并返回数组新的长度。
var arr = [1,'ABC',000]
arr.push('add_push')
- Array.unshift(value,…):数组头部添加新的数组元素,并返回数组新的长度。
var arr = [1,'ABC',000]
arr.unshift('add_unshift')
删除数组元素:pop、shift
- Array.pop():删除数组的最后一个元素,并返回这个删除掉的元素
- Array.shift():删除数组的第一个元素,并返回这个删除掉的元素
Array.splice()添加删除替换任意元素
Array.splice(num1,num2,value,…) 范围:[从第几个开始,删除|替换的个数]
- 删除,返回删除的内容,原数组改变
var arr = ['今天','天气','特别','好','开心','啊']
//范围[1,2]
arr.splice(1,2)
- 添加,返回[],原数组改变
arr.splice(2,0,'牛逼','杠杠的')
- 替换,返回删除的内容,原数组改变
arr.splice(3,2,'我','最牛逼')
数组排序:sort
Array.sort() ,返回排序后的结果,原数组改变
var arr = [60,3,88,71,20,97,6]
var arr2 = arr
arr.sort() // 20, 3, 6, 60, 71, 88, 97
console.log(arr) // 20, 3, 6, 60, 71, 88, 97
console.log(arr2) // 20, 3, 6, 60, 71, 88, 97
- 升序,返回排序后的结果,原数组改变
arr.sort(function(a,b){return a-b}); - 降序,返回排序后的结果,原数组改变
arr.sort(function(a,b){return b-a});
以下数组方法不会改变原数组的值
拼接数组:concat
- Array.concat():拼接数组,返回拼接后的结果。
var arr1 = ['abc','bcd']
var arr2 = [123,456]
arr1.concat(arr2,'(๑•̀ㅂ•́)و✧','棒!')
判断数组元素是否包含:includes
- Array.includes():查找数组是否包含对应数组元素 true/false
arr2.includes(123) //true
数组变字符串:join
- Array.join():数组变字符串
截取数组:slice
- Array.slice(num1,num2):数组抽取一部分返回为新数组,范围[num1,num2)
var arr = [3, 6, 20, 60, 71, 88, 97]
//范围[3,5)
arr.slice(3,5) // [60,71]
数组在ES6中的方法
map、reduce、filter、forEach
数组的随机排序
数组去重的各种方法
冒泡排序
函数
抛出异常
throw new Error(“xxx”)
函数的作用:
重用,函数重用思想,代码重用,提高代码使用率,避免程序中出现重复代码。
分离:分离思想,以功能模块方式将代码分离,提高代码可读性,建立模块化编程结构。
函数的参数和返回值:
没有参数:无参函数
一个函数如果没有返回值,则默认为undefined,当有返回值时用return
函数的使用:
function 函数名(参数1,参数2,…){}
函数名(参数1,参数2,…);调用
函数的注释:
函数的arguments来接收参数:
arguments是一个伪数组,只有length可以用,Array的其他方法都不可用。
作用:接收任意个参数。
调用函数时,所有实参,都存储在arguments伪数组中。可以对arguments进行循环遍历,但是不能对它进行增添删除等。
function sum(){
var sum = 0;
var arr = arguments;
for(let i=0;i<arr.length;i++){
sum+=arr[i]
}
return sum
}
sum(1,2,3,4,5,6) // 21
函数表达式
注意:如果用 函数表达式(匿名函数赋值给的变量)来创建一个函数,只能在函数表达式之后调用此函数。如:
用函数表达式,报错:
不用函数表达式,成功:
全局变量,局部变量
没有var声明变量时,就默认把对应的变量生成为了全局变量。
当局部变量与全局变量重名时,在函数中选择使用局部变量。
return
一个函数中只允许一个执行return,但是可通过选择语句书写多个return。当函数执行return时会返回函数的调用点,并停止函数的执行。
let、const和var
var:他规定了只在函数内声明的变量时局部变量。可以跨块{},不能跨函数。
let:在ES6中凡是在块内{}中声明了变量,它只能在{}中使用。
const:只能在块内{}使用,必须指定初始值不能修改。
let和var作用域的对比:
let,var作用域应用对比:
Date日期对象
获取时间
let myDate = new Date();//返回当前日期时间对象
let oneDate = new Date(2020,10,1,14,58,59) //指定日期时间
let year = new Date().getFullYear();// 2020
//getMonth 0-11 月份
//getDate 日
//getDay 0-6 星期
//getTime() 返回毫秒数
//getMilliseconds 1秒为1000毫秒
修改时间
myDate.setFullYear(1998) //修改年份为1998
//setMonth(4) 5月
//setDate(20) 20号
日期转字符串
toDateString()
toTimeString()
toLocalString() //本机日期时间
toLocalDateString()
toLocalTimeString()
不需要new运算符就可以得到一个日期和时间对象:返回当前日期时间字符串,但不能当日期对象使用。
String字符串
String是不可变的。
创建
let s = new String('askh123132')
let s2 = '123678000'
返回指定字符charAt()
从一个字符串中返回指定的字符:
var str = '12345abc'
str.charAt(0) // '1'
str.charAt(10) // ''
返回下标indexof()
找字符第一个出现时的对应的下标,没有为-1
var str = '12145abc'
str.indexOf('1') // 0
拼接concat()
拼接字符串
var str = '12145abc'
var str2 = '哈哈哈'
str.concat(str2) // "12145abc哈哈哈"
截取字符串slice()
从一个字符串中返回指定位置和长度的子字符串
范围:[start,end),负数为倒数。
start可以为负,end不能为负。
var str = '123456789'
str.slice(3,6) //456
str.slice(3) //456789
str.slice(-8) //23456789
str.slice(-8,7) //234567
截取字符串substring()
从一个字符串中返回指定位置和长度的子字符串
范围:[start,end)
start、end不能为负。
var str = '123456789'
str.substring(5,8) //678
str.substring(5) //6789
截取字符串substr()
返回从start开始,length个输量的子字符串。
var str = '123456789'
str.substr(2,5) //34567
str.substr(2) //3456789
str.substr(-2) //89
str.substr(-6,2) //45
字符串变数组split()
var str = '123456789'
str.split("") // ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
str.split("5") // ["1234", "6789"]
var str = '12345655755589'
str.split("5") // ["1234", "6", "", "7", "", "", "89"]
trim()去掉字符串两端的空格,主要用于表单输入项。
str = ' 123 678 '
str.trim() // "123 678"
替代replace()
str = ' 123 678 '
str.replace(' ','A') //"A 123 678 "
//全局替换
str.replace(/ /g,'-') //"--123---678---"
str = ' 123 678 aa AA'
//全局替换忽略大小写
str.replace(/a/gi,'b') //" 123 678 bb bb"
查找match()
let str3 = 'A213AAkhA213AA'
str3.match('k') //["k", index: 6, input: "A213AAkhA213AA", groups: undefined]
str3.match(/A/g) // ["A", "A", "A", "A", "A", "A"]
str3.match(/A123/g) //null
查找search()
搜索子串,返回第一个匹配到的位置没有找到返回-1
let str3 = 'A213AAkhA213AA'
str3.search('kHa') //-1
str3.search('khA') //6
正则表达式
正则表达式就是一个字符串模板,其本身是一个字符串。是使用特定的符号来描述该组字符串的一种方法。
使用
var regExp = new RegExp(‘模板字符串’,‘参数’)
var re = /^hello$/;
方法 test()
var reg = new RegExp('abc')
str = 'abc123abc000'
reg.test(str) // true
或者使用:
var reg = new RegExp(/IJK/) //匹配有没有IJK
或者:
reg = /IJK/
元字符
^ $开始到结束
具有特殊含义的字符:
//^ $ 开始到结束字符
reg=/^IJK$/
str = 'abc123abcIJK'
reg.test(str)// false
str = 'IJK'
reg.test(str)// true
.任意键盘字符(除了换行和行结束符号)
var reg = /^a.$/
var str = 'abc'
var str2 = '2a1'
var str3 = 'ax'
var str4 = 'a\n'
reg.test(str) //false
reg.test(str2)//false
reg.test(str3)//true
reg.test(str4)//false
\w 匹配a-z,A-Z,0-9以及下划线字符
var reg = /^a\w$/
var str = 'ab'
var str2 = '2a1'
var str3 = 'a2'
var str4 = 'a\n'
reg.test(str) //true
reg.test(str2)//false
reg.test(str3)//true
reg.test(str4)//false
\d 匹配数字
只有数字0-9。
\s 匹配空白符号如\n,\r
\W,\D,\S和小写相反
[]:匹配[]里面任何一个字符集或元字符
var reg = /^a[IJK]b$/
var str1 = "aIb";
console.log(reg.test(str1)); //true
reg = /^a[a-zA-Z0-9\w]b$/
str2 = "a2b";
str3 = "aZb";
str4 = "a_b";
console.log(reg.test(str2)); //true
console.log(reg.test(str3)); //true
console.log(reg.test(str4)); //true
[^]:匹配除字符集中以外的字符
var reg = /^a[^IJK]b$/
var str1 = "aIb";
console.log(reg.test(str1)); //false
str1 = "a8b"
console.log(reg.test(str1)); //true
量词+ * ?{}:
量词:n表示任意的字符或元字符;在些表示是一个语法糖;
n+ 匹配任何包含**至少一个 n **的字符串。
var reg = new RegExp(/^a+$/);
var str = "a"
var str2 = "aaaaaaaaaaaa"
var str3 = "baaaaa"
console.log(reg.test(str)); // true
console.log(reg.test(str2)); //true
console.log(reg.test(str3)); // false
n* 匹配任何包含零个或多个 n 的字符串。
var reg = new RegExp(/^_a*_$/);
var str = "_a_"
var str2 = "_aaaaaaaaaaaa_"
var str3 = "__"
var str4 = "_x_"
console.log(reg.test(str)); // true
console.log(reg.test(str2)); //true
console.log(reg.test(str3)); // true
console.log(reg.test(str4));// false
n? 匹配任何包含**零个或一个 n **的字符串。
var reg = new RegExp(/^_a?_$/);
var str = "_a_"
var str2 = "_aaaaaaaaaaaa_"
var str3 = "__"
var str4 = "_x_"
console.log(reg.test(str)); // true
console.log(reg.test(str2)); //false
console.log(reg.test(str3)); // true
console.log(reg.test(str4));// false
n{X} 匹配包含 X 个 n 的序列的字符串。
var reg = new RegExp(/^_a{5}_$/);
var str = "_a_"
var str2 = "_aaaaaaaaaaaa_"
var str3 = "__"
var str4 = "_aaaaa_"
console.log(reg.test(str)); // false
console.log(reg.test(str2)); // false
console.log(reg.test(str3)); // false
console.log(reg.test(str4));// true
n{X,Y} 匹配包含 **X 至 Y 个 n **的序列的字符串。
var reg = new RegExp(/^_a{5,8}_$/);
var str = "_a_"
var str2 = "_aaaaaaaa_"
var str3 = "_aaaaaaaaaaaa_"
var str4 = "_aaaaa_"
var str5 = "_x_"
console.log(reg.test(str)); // false
console.log(reg.test(str2)); // true
console.log(reg.test(str3)); // false
console.log(reg.test(str4));// true
console.log(reg.test(str5));// false
n{X,} 匹配包含**至少 X 个 n **的序列的字符串。
var reg = new RegExp(/^_a{5,}_$/);
var str = "_a_"
var str2 = "_aaaaaaaa_"
var str3 = "_aaaaaaaaaaaa_"
var str4 = "_aaaaa_"
var str5 = "_x_"
console.log(reg.test(str)); // false
console.log(reg.test(str2)); // true
console.log(reg.test(str3)); // true
console.log(reg.test(str4));// true
console.log(reg.test(str5));// false
案例
var tel = "13258231798"
var reg = /^1[37859][0-9]\d{8}$/;
console.log(reg.test(tel)) //true
tel = "14258231798"
console.log(reg.test(tel)) //false
regId = /^(\d{18})$|^(\d{17}[xX])$/ ;
userId = "511000199910101234"
console.log(regId.test(userId)) // true
userId = "51100019991010123x"
console.log(regId.test(userId)) //true
userId = "251100019991010123x"
console.log(regId.test(userId)) //false