JavaScript:依赖HTML的脚本语言(网景公司的Netscape)
script标签:三种写法(行内,内联,外联)
外联后script里面不需要写代码
script可以和style一样放在页面任意位置
初期建议放在/body和/html之间
// /**/
单双引号尽量保持一种 分号可加可不加,要加都加,要不加都不加
本质就是存数据的容器—放在内存中
显示声明:var a = 5;
隐式声明:b = 5;
var a= b=c = 5;相当于 var a = 5;b = 5;c = 5;
一次性定义多个变量:var a = 3,b,c,d;
var a = 10;
若干个 任意字符 引号号包含起来
true,false
var a ;.//undefined
三种表现形式:
var arr =[1,2,3]
js进行小数计算会精度损失
var a = 0.2,b = 0.1; var c = a + b ; console.log(c);//0.30000000000000004方法一:乘以10除以10
var a = 0.2; var b = 0.1; var c = (a*10 + b *10) / 10; console.log(c);方法二:强直保留小数点后几位 console.log(c.toFixed(3));
跟任何数据饭都不相等,包括自己 isNaN():检测一个数字是不是数字//true不是一个数字,false是数字 100a时显示true
单引号和双引号不可以嵌套他们自身
原因:引号虽然是字符,但是有特殊含义
解决:单嵌套双或相反;转义字符
js可以输出标签的,doucment.write("
输出字符串长度:str.length
字符串也可以+=
= ,+=,-=,… 作用;将右边的值赋给左边的变量
+ - * / %
> <等等
其中 ==是比较值的, ===是先比较类型,再比较值
因为 == 和!=是会自动进行数据类型转换的,转成数字再比较
Number():字符串纯数字才可以转为数字型,不然NaN
布尔true为1,false为0
undefined转数字是NaN
null转数字是0
parseInt();字符串前面的整数获取到
parseFloat()字符串前面的小数获取到
Boolean(要转换的数据);
NaN,0,’’,undefined,null
String():就是加个引号 数据.toString(); 直接加上"";
字符串拼接时,一边为字符串,另一边转为字符串
比较运算时,左右有一个是数字,另一个也会被转为数字比较
当进行除了加法以外的数学运算,会将量两边转为数字再运算
&& 与 ||或 !非 通常连接两个表达式
控制台黑色数字为字符串类型,蓝色数字为数字类型
进行数字加法运算的时候一定要检测是不是数字类型
if(条件){满足条件执行} 小括号内自动转换为boolean型
if(条件){当条件满足执行}else{不满足时执行}
if (条件) { 代码块 } else if ( 条件 ) { 代码块 } else if ( 条件) { 代码 块 }…else { 代码块 }(最后这个可写可不写)
分支语句可以简写
类似于多分支,只能判断一个变量跟某些值是否全等
var num =1; switch(num){//switch小括号里面的值只能是变量 case 1:num ===1;(重点) 执行语句; break; ... default: 执行语句;break; }break是可以省略的,称为case穿透
当num=2: case 2: console.log(“hello”);//这里省略break case 3:console.log(“hello”);break;//这个就不判断了 当num=3: case 3:跳过了case 2;但是倒过来写会执行case 2。注意:
switch的运行效率是高于分支的,因为直接到达符合条件的地方,不需要从上往下判断当判断是否相等时更加精确小括号里面的可以放任何值,最终都转为boolean类型
前缀先运算在操作,后缀先操作再运算
总结: 字符串的比较是逐位比较的,"|10">"2"为false switch倒着写可以实现累加的效果 剩下的多少秒:秒数%60 剩下小时 = 小时数 %24
目的:处理重复 循环小括号的变量为全局变量
至少执行一次
break:跳出当前循环; continue:跳出·此次循环,执行下次循环 continue的书写顺序要靠前,放在最后执行了效果等于没执行
for循环里面的还可以继续嵌套
目的:处理重复 可以重复利用的工具
语法:function 函数名(){ 代码段; }
函数的定义其实是赋值过程,在内存中开辟fn的空间,fn存放代码
函数名();//调用函数内部的代码 fn()中fn其实是数据类型(function),里面存放的是function后面的代码
定义一个函数:
function fn(){ console.log(123); }在内存的显示:
f fn(){ console.log(123); } function //返回类型形参:形式上的参数
实参:实际意义上的参数,用于给形参赋值,调用时候的小括号内,类型和个数需要和形参相对应 函数的优点:重复执行,模块化编程 函数的书写:先写核心代码,然后用函数包裹起来
使用场景:事件中
总结:函数可以没有名字,然后将函数赋值给一个变量----同样能使用
原因:函数的定义过程,其实就是在内存空间中开辟了空间,存放一段代码作为值
fn里面的值:
匿名函数的fn代表的是:
function(){ console.log(123); }那么fn()就是
(function(){ console.log(123); })();也可以写成:
! function(){ console.log(123); }();!可以换成~,能看懂别人这么写就可以
好处是什么?省去了调用
代码执行顺序:
从上而下,从左至右,逐字符依次执行。只有有名字的函数才叫函数的定义(打%的地方)。
从所有代码中找到变量的定义和函数的定义,找到了就会将变量的定义和函数的定义放到所有代码的最前面,然后再执行。
注意:函数的大括号可以约束声明提升,但是if语句等的大括号不具有约束性
var a = 10; 分为两个步骤:定义a,将a赋值为10运行结果: undefined 报错
fun(); var fn = function(){ console.log("我是fn函数"); } function fun(){ console.log("我是fun函数"); } fn(); fn = 100; fn();运行结果 我是fun函数 我是fn函数 报错
fn(); function fn(){ console.log("我是一个fn函数"); } fn(); var fn = 100; fn();运行结果 我会fn函数 报错
这里预解析的时候函数和变量重名,保留函数
var a= b; a = 0; b = 0; console.log(a); console.log(b);直接报错 因为b没被定义就被使用,一定要先定义再使用
var fun = 200; fun(); var fun = function(){ console.log("我是一个fun函数"); }直接报错,因为预解析后fun这个空间的值是200,不是函数,无法调用
function fn(a){ console.log("我是fn函数"); a(); functio a(){ console.log("我是函数a"); } } fn(10);我是fn函数 我是函数a
注意:形参赋值是在函数提升和参数提升之前的
console.log(num); if(false){ var num = 100; }undefined
注意:不会执行的代码也是要预解析的
让一个函数返回值,后面的语句都不会执行 return只能停止函数,break只能停止循环和switch 函数中的循环可以加return 循环中的函数可以加break;
没有return的函数默认返回undefined
能起作用的区域
在不同地方定义的函数和变量,起作用的范围是不同的
不在任何函数内定义的变量称为全局变量
在函数内定义的变量称为局部变量
全局变量在局部范围内有效 局部变量在全局范围内无效
函数定义好了就相当于创建了个作用域,任何函数都可以创建作用域
作用域可以嵌套成作用域链
赋值: 先从当前作用域查找变量的定义,没有找上一级,直到全局,全局有就赋值给全局变量;全局没有就隐式定义这个变量-----不过不存在提升过程。
运算、比较、输出等操作,先从当前作用域查找变量的定义,没有就杀上一级,直到全局,全局没有就报错,有则使用。
注意内存溢出错误(Maximum call stack size encoded)
先定义一个空函数,然后往空函数里面输入值:
function fn(){ if(num ==1){ return 1; } return num*fn(num-1); }注意一定要写return
匿名函数的应用:
事件源:
能触发某种行为的HTML标签事件类型:
拖拽,移动事件处理程序:
函数在js中使用标签id代表标签,不要使用常见的关键字(name,start,stop)
事件源.onclick = function(){ console.log(123); }
注意,知识点来了:事件的函数是由系统来调用的,事件的类型有系统提供的
第一种:
div.onclick = function(){ console.log(123); }第二种;
btn.onclick =fn; function fn(){ console.log(123); }第三种:行内书写
onclick ="javascript:console.log(123);"//只能写一个语句 onclick=onclick(){}this:在全局中表示window(浏览器窗口),在事件中代表事件源
对象分为数组/json对象/null
多个数据(键值对)组成的集合 直接定义:
var obj ={ name:"张三", age:12 }构造函数:
var obj =new Obj({ name:张三"" });键值对形式: 键必须是字符串,在定义的时候可以不加;键中包含连字符“-”,那就须要加上引号; 值是任意类型(可以是函数)
js提供了特殊的for
for(var attr in obj){ obj[attr]; }
attr是键,obj是对象
**注意:**错误写法如下
var a ="name"; obj.a;//这么写是错误的,因为obj里面没有a这个键正确写法:
var a = "name"; obj[a];对象的值如果是函数,那么这个键就叫做对象的方法
如果碰到多个键值对,就用对象
被用来new创建对象的函数都是构造函数
任意函数都可以new来当构造函数,当一个函数被用来创对象,就可叫构造函数
系统提供了一些构造函数来创建对象
//系统内置的构造方法 var num = new Number(12); String(); Booelan(); 这里的num是对象型,可以参与数学运算并得到结果原理:js的底层处理任何的数据都是对象处理的,为了让开发者更加接近于正常的理解,js提供了基本数据类型,供开发者使用。
也是多个数据的集合,但是相较于对象,数组在内存是按顺序排列的
一:直接定义
var arr=[1,2,3,4,5];
二:构造方法
var arr =new Array(5); 创建了5个empty 不建议使用
上面两种方式的区别只存在都给里面放个数字
var arr=['a']; vae arr = new Array('a'); //这两个是一致的数组对象里面有属性length,可通过arr.length获取数组长度
数组第一个下标为0,最后一个下标为arr.length-1
方法一:
var length = arr.length;//因为每次判断都要取值一次,浪费时间 for(var i = 0;i <length;i++){ console.log(arr[i]); }方法二:
for(var i in arr){ console.log(arr[i]); }这个方法是遍历对象的,当然可以遍历数组
数组的元素类型没有限制,所以是数组类型也可以
嵌套两层为二维数组,嵌套三层为多维数组
查看三维数组中的某个元素arr[0][2][1];
参数一和参数2必须写,参数三为可选项 最常用,插入删除修改数组
pop():删除最后一个元素 unshifted():开头加上元素 shift():开头减少元素 push():末尾加上一个任意类型元素
concat()数组拼接:var res =arr1.concat(arr2); var res1 = arr1.concat(“a”,“b”);
数组的排序sort:arr.sort(function(a,b){ return b-a;//降序 return a - b;为升序 })
连接join:arr.join("-") 按照指定字符拼接成字符串
栈内开辟空间,放入数据,b=a就是将a内存里面的数据复制一份到b
数组在栈内开辟空间,将数组内容放在堆内存,栈内存存放数据的地址,b=a赋值的是数组的地址,修改的是堆内存的数组,对a的值也会产生改变
算法原理:每相邻的两个元素比较大小,不符合规则就交换两个元素的位置
var arr=[1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2]; var length = arr.length; for(var i = 0; i<arr.length;i++){ for(var j = 0;j<length -1;j++){ if(arr[j]>arr[j+1]){ var tmp =arr[i]; arr[j] = arr[j+1]; arr[j+1] =tmp; } } } console.log(arr);原理:每次选择最小的或最大的值放在合适的位置
var arr = [1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2]; for(var j = 0; j <arr.length - 1 ; j ++ ){ var min = arr [j]; for(var i = j+1 ;i <arr.length; i++ ){ if(arr[j]> arr[i] ){ var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } console.log(arr);ES5 兼容性最好的版本
ES6也称为ES2005
ES:ECMAScript的简写
“use strict”;
在script的最前面或者在函数的最上面写上"use strict";
消除怪异语法,更加规范化 运行效率更高
严格模式也受到作用域限制
4.reduce方法:归并
arr.reduce(function(v,i,a){ return v<60; })a:第一次值为arr[0],之后是上一次函数的return,没有返回undefined b:a[次数];
map和filter用的最多
从左到右逐个字符比较的
字符大小规则遵循ASCII码
数字<大写字母<小写字母
排名越靠前越小(a<z)
for(var char of String){ console.log(“字符”+char); }
3.固定写法:String.fromCharCode()-----通过ASCII码返回一个字符
var num= 97; var s = String.fromCharCode(num); console.log(s);indexOf() 查字符在字符串中第一次出现的下标,没有返回-1
lastIndexOf(): 查字符串最后一次出现的下标,返回值为下标或者-1
substr(): 截取字符串,参数一开始截取的下标,参数二截取长度(不写默认截取到尾)
substring():截取字符 参数一:开始下标 参数二:结束下标(不写默认到结尾,不包含参数二的)
slice() 截取字符串,和substring一样的 截取从左到右,不是从右到左 开始下标为负数的话,-1表示倒数第一个 数组里面也有slice方法
split(): 把字符串转成数组(俗称“炸”) 使用指定的分隔符将字符串分割成很多小字符串,组成数组并返回 没有参数将整个字符串当做元素放入数组 split(""):每个字符都当成元素组成新数组
replace(): 替换字符串中的指定内容,只能替换一次,循环才可以替换多次 str.replace(“html”,“css”); var s = str.replace("")
trim() 去除左右的空格,可分为trimLeft()和trimRight()
toLowerCase();//全部小写 toUpperCase()//全部大写
math对象:系统内置的对象
math不像String和Date是对象的类,因此没有构造函数Math(),像Math.sin()这样的函数只是函数,不是某个对象的方法。无需创建,通过把慢作为对象使用就可以调用其所有的属性和方法
格式功能Math.PI圆周率Math.round()四舍五入Math.pow(底数,幂数)次方Math.random()获取随机数Math.floor()向下取整Math.ceil()向上取整Math.max()最大值Math.min()最小值Math.abs()求绝对值生成一个[a,b)的随机整数
除了十进制以外的进制都是字符串形式
10进制转为其他进制: num.toString(8);//转为八进制 其他进制转为10进制: var res = parseInt(str,n); //str为进制字符串,n为str是什么进制的
系统提供的构造函数
var date =new Date(); console.log(date);//当前时间
date对象在我们打印日期的时候自动调用toString方法。
格里尼治时间戳:从格林尼治的1970.1.1.0.0.0到现在的毫秒数,就是现在的时间戳
var date =new Date();
获取什么格式获取年var year = date.getFullYear()获取月var month = date.getMonth()获取日var day = date.getDate()获取时var hour = date.getHours()获取分var minute = date.getMinutes()获取秒var seconds = date.getSeconds()获取毫秒var milisecond = date.getMilliseconds()获取时间戳var timec = date.getTime()获取星期几var week = date.getDay()快速获取时间戳var res =+new Date();注意:js里面的月份是0~11,输出时需要加1
get改为set就可以了
星期是不可以设置的
设置时间戳:date.setTiems(0)//格林尼治时间 在线运行js
设置·指定时间的时间戳: var date = new Date(“2020-10-10 11:21:05”); var date = new Date(1010,10,10,0,0,0);
通过构造方法设置时间戳: var d = new Date(0);
格式化输出时间日期: date.toLocaleString();//只看年月日 date.toLocaleTimeString();//只看时分秒 date.toLocaleString();//都看
Browser Object Model
操作浏览器都是使用对象来操作的:window对象(浏览器窗口)
window有子对象,每个子对象都针对着一个操作
window.open(): window.location.href=“地址” window.location.assign(): window.location:
注:window可省略
没什么卵用,对于学爬虫的估计有用 window.navigator.appCodeName 浏览器内核名称 window.navigator.appName浏览器名称 window.navigator.appversion:浏览器版本 window.navigator.userAgent:浏览器信息
前进: history.back(); 后退: history.forward() 刷新: history.go();//正数前进,负数后退,0刷新当前页面
href属性: location.href是完整的地址栏地址,赋值可以实现跳转
search属性: 获取地址栏数据 location.search 也可以赋值设置,注意是键值对形式
hash属性: 获取地址栏的锚点: location.hash="#bottom"
页面重定向(跳转方法): location.assign(“地址”);
新地址替换当前地址: location.replace();
刷新当前页面: location.reload();
alert(); prompt(); confirm();
注意: 全局变量其实是window的属性,全局函数是window的方法,只不过平时省略了window,全局中的普通函数中的this代表的就是window对象。
innerWidth/innerHeight 包含滚动条,相当于视窗的宽高(去掉了window)
window.onload = function(){ //页面加载完再执行 //放在同步中就是同步加载完的最后,异步中就是异步最后 }
window.onreszize = function(){ //改变窗口大小就执行 }
window.onscroll = function(){ //浏览器滚动条滚动时执行 }
分两种:每隔一段时间执行一次和延时一段时间只执行一次
第一种:
var timer = window.setInterval (function( console.log(123); ),2000)清除:
clearInetrval(timer); //形参是当前页面第几个定时器,一般为定时器返回值或者数字,会执行一次注意:定时器一定要停,不然内存溢出
上一个(死循环,递归函数) 第二种:
window.setTimeout(function{ console.log(123); },2000) //也有返回值,也用来清除,同样代表第几个定时器清除:clearTimeout();
timer这个返回值其实是最后一次点击的定时器的返回值
清除定时器的时候,其实是清除了最后一个定时器,前面几次点击产生的定时器没有清除,也清除不掉了
同步: 上面的语句执行完,下面才会执行,排队等待 异步: 同时执行(和同步)
总结: 定时器和延时器不一定精准(因为异步的定时器会受到同步时间的耽误) 所有异步都是在同步执行完之后执行的 异步效率高
之前存在id名代表这个标签,如:
box.onclick (function(){ console.log(123); })注意:2,5,6条低版本IE不兼容
特殊的: img.src和input.value
最重要的:inout.checked
元素.innerText,值为标签内容,设置标签样式是不生效的 元素.innerHTML:标签内容,值为标签生效
特殊情况:
表单元素的值: document.querySelector(“input”).value; 0
写在行内的style标签里面的
标签.className:""; 这么写清空类名
当文档声明没有时,documentElement换成body
兼容写法:
var t = document.documentElement.scrollTop||document.body.scrollTop立即回到顶部:
t = 0;也可以定时器不断减少慢慢变化节点:html文档的组成部分
DOM节点分(了解): 元素节点(标签),属性节点(),文本节点(文本内容),注释节点(注释) 注意: 文本节点:标签内的文本和标签之间的换行空格(为什么写移动端最好别换行空格,因为算文本,会被当做文字放大)都算文本节点
上面的getElementById等都是获取节点,但是这里的获取节点是依靠关系,不是直接获取
重点:
获取什么怎么获取子节点childNodes子标签children父节点parentNode父标签parentElement第一个节点firstChild最后一个节点lastChild子元素中第一个标签firstElementChild子元素中最后一个标签lastElementChild获取上一个节点previousSibling获取下一个节点nextSilbling获取上一个节点元素previousElementSibling获取下一个节点元素nextElementSibling获取所有属性节点atributes都是属性,不是方法
写法作用nodeType获取节点类型nodeName获取节点名nodeValue获取节点值nodeType返回值: 1表示元素节点;3表示文本节点;8表示注释节点;2表示属性节点
nodeName: 标签节点为标签名的大写形式(DIV),文本节点为(#text),注释节点为(#comment)
nodeValue: 标签为null,文本节点为文本内容,注释节点为注释内容
复制节点传参true可以将里面的内容也复制
var styles = window.getComputedStyle(元素); styles.属性
低版本IE不兼容
兼容写法
function getStyle(){ try{ return window.getComputedStyles(ele[attr]); }catch(e){ return ele.currentStyles[attr];//IE兼容写法 }都是只读类型,offsetHeight对于行内一直为0
变量定义技巧
一个局部想要使用另一个局部的变量,可以将变量定义在全局
使用自调用函数传参(形成保留作用域)
for (var i = 0; i < ulis.length; i++) { ( function(i) { ulis[i].onclick = function () { that.className=""; that =this; for (var j = 0; j < ulis.length; j++) { ulis[i].className = ""; } this.className = "active"; for (var j = 0; j < olis.length; j++) { olis[j].className = ""; } olis[i].className = "active"; } })(i); }下拉框select>option里面的value可以
document.querySelector(“select”).value获取到
为了提高浏览器检索优先级:能不用标题标签就别用
事件:用户的动作(单击,右击等)
下面是事件类型:
相同点:没有子元素时候行为一致
mouseover用的比较多,mouseenter经常被忘掉
mouseenter不会冒泡,mouseover会
不论鼠标指针穿过被选元bai素或其子元素,都会du触发 mouseover 事件。对应mouseout 只有zhi在鼠标指针穿过被选元dao素时,才会触发 mouseenter 事件。对应mouseleave 这样的话,mouseenter子元素不会反复触发事件,否则在IE中经常有闪烁情况发生。(复制自百度)
区别自己百度,使用最多的是keyup
事件从开始触发到执行结束的流程(一连串的事情) 捕捉阶段:从文档由外向内找目标元素 目标阶段:找到目标文件,执行文件 冒泡阶段:执行完就要离开
事件外的元素也绑定了事件的话,冒泡阶段由内向外会触发外面的事件
onClick的缺点:一个元素绑多个onClick会被覆盖
事件侦听器(兼容性):
元素.addEventListener(“click”,function(){ //可以实现多个不覆盖,但是IE不行 }) 元素.attachEvent(onclick,function(){
})
function bindEvent(btn,type,handler){ try{ btn.addEventListenter("type",handler); }catch(e){ btn.attachEvent(on+"type",handler); } }第二种:
function bindEvent(btn ,type,hander){ if(btn.addEventListener){ btn.addEventListener(type,hander) }else if(btn.attachEvent)){ btn.attachEvent("on"+type,handler) }else{ btn["on"+type] = handler } }第三种:
function bindEvent(btn,type,handler){ try{ btn.addEventListener(type,handler) }catch(err){ try{ btn.attachEvent("on"+type,handler) }catch(e){ btn["on"+type] = handler }}}访问对象中不存在的属性是undefined
按钮能点击,说明加载到内存中了,所以点击才能生效
前提里面的函数不能是匿名函数了
var fn = function(){ console.log(123); } 解绑: 事件源.removeEventListener("click",fn); 事件源.detachEvent("onclick",fn);解绑又有兼容性问题----封装函数:
function unbindEvnet(ele,type,handler){ if(ele.removeEventListener){ ele.removeEventListener(type,handle) }else if(ele.detachEvent){ ele.detachEvent(“on”+type,handle); }else { ele[“on”+type] = null; } }事件时有系统调用的,不是我们手动调用的,系统将事件对象放在小括号内,存放和当前事件相关的一系列信息。
small.onclick = function(e) { console.log(e); e.stopPropagation();//阻止事件冒泡 }在IE中的兼容写法 事件对象:window.event 阻止冒泡:e.cancelBubble=true;
注意:键盘码低版本火狐不兼容 兼容写法:
var keycode =e.keyCode||e.which
链接的跳转,鼠标右键出现的窗口都是默认行为
return false(事件函数最后加上)e.preventDefaulte e.returnValue =false(IE中)(利用事件对象来阻止)将链接地址改为javascript:;将子元素的事件委托给父元素:例如点击事件,委托后每个子元素都可以有点击
好处:你新增的元素不需要再次单独绑定事件,十分方便
兼容写法:
target = e.target ||e.srcElement;(兼容低版本IE) target代表的是所有子元素
<ul> <li>11111111111</li> <li>22222222222</li> <li>33333333333</li> <span>4444444444</span> </ul> <button>添加</button> </body> <script> var ul = document.querySelector("ul"); ul.onclick = function(e){ var e = e||window.event; var target = e.target ||e.srcElement; if(target.nodeName=="LI"){ target.innerText="修改";//加条件限制target范围 console.log(target); } }注意点:
拖拽的时候一定是事件嵌套,事件的事件对象是不一样的mouseover和mouseout是一对,mouseenter和mouseleave是一对,尽量不要混用在head里面写script标签,要将代码写在这个事件内部;script在body的底部,就不要加了,加了也没用,还会覆盖前面的键盘事件通常是keyup获取键盘码时有些特殊键盘码无法显示,大小写有时候会混乱,不要研究为什么没有设置小盒子的时候,光标就是大盒子上的位置,就是offsetX 一旦设置了小盒子的位置,光标立马就会在小盒子上,此时的offset就是光标在小盒子上的位置。
拖拽效果不要使用offsetX/Y
e.clientX/Y都是只读数据
用处:验证字符串,提取满足的字符串,替换字符串
但是还有很多用法,无法说清,不仅仅只是简单地实现表单验证
创建: var reg =new RegExp(); var reg = /规则/;
可接受写法 var reg = /html/; var reg =/^html$/; var reg = /\w$/; var reg =/\d$/; var reg =/^\d{5,12}$/;
符号意义^放在规则前表示必须是这个开头$放在规则结尾表示必须以这个结尾{m,n}至少m个,至多n个{n,}至少n位,多了不限制{n}必须是n位\w任意字母数字下划线\d任意数字.代表一个字符(注意字符是重点)\s代表一个空格[a-z]小写a到小写z,不是固定解法,[a-zA-Z]表示任意一个字母\u4e00 -\u9fa5汉字,不要记,会查就行+至少一个?最少0个,最多1个*{0,},任意个()表示包起来的是一个整体,还有个用法是用来捕获变量方式一:
var str = "28715260980"; var reg =/^1[3-9][0-9]{9}$/; var res= reg.test(str); console.log(res);方式2:
var str = "28715260980"; var reg =/^1[3-9]\d{9}$/; var res= reg.test(str); console.log(res);注意: exec(): 正则方法 在字符串中找到匹配的为输出的数组第一个元素,找不到为null 如果想要具体的某个值,可以给那个值加上(),第二个元素为小括号内的值
表单验证要么都是失去焦点的验证,要么都是提交按钮的验证,不然冲突,失去焦点优先级高,提交按钮无效。
foreach:
arr.foreach(function(v,i,a){ console.log(v); })some:
var res = (function(v,i,a){ return v>30; })every:
var res = arr.every(function(v,i,a){ return v==60; })find:
var res = arr.find(function(){ return v>5; })var的特点:能预解析,全局变量属于window 两个关键字定义变量: const,let 特点:不能预解析;不在window上(因为自己的作用域) let定义的变量,创建了一个作用域
for(let i = 0; i<3;i++){}; console.log(i);//报错,表示i未定义let定义过的变量,不能重复定义: 好处:以前事件外循环参数需要函数传入,现在将循环参数改为let就可传入,因为let创建了个作用域
var button = document.querySelectorAll("button"); for (let i = 0; i < button.length; i++) { button[i].onclick = function () { console.log(i); } } function f2(){ var i = 5; for(var i=0;i<=10;i++){ } console.log(i); // 11 var j = 5; for(let j=0;j<=10;j++){ } console.log(j); // 5 } f2();const:常量,值可被初始化,但不能赋值。也不在window上,也不能预解析,不希望改变的量就用const来定义
形参列表只有一个参数,小括号可以省略 大括号内只有一行代码,省略大括号 若一行代码内只有return关键字,return关键字可以省略
let fn = res=> res; let fn= function (res){ return res; }function(a,b=10){ console.log(a,b);//b不传值就是10,传值10被覆盖 } 如果a有默认值,不想改变,可以实参传undefined
总结:实参分解形参合并,对象直接拆
注意变量名和键名需要保持一致
取别名: var {name:n,age:a,eat:e,sports:s}=zs; console.log(n,a,e,s); 套娃操作:
var {wife}=zs; var name={wife}; 简化套娃操作:var {wife:{name:n}} = zs;
数组结构:
var arr = [1,2,3,4]; var[a,b,c] =arr; var [a] =arr; //只想获取c var [_,_,c]=arr; //数组的多重解构(套娃) var arr =[ "马蓉", "王宝强", [ "贾乃亮", "PGOne", "李小璐" ] ] var [_,_,[a]] = arr;字符串是不支持多行定义的,使用模板字符串就可以了(反引号)
var name="张三"; var str=` 姓名:${name} `; name+str;返回值是boolean型: startsWidth:字符串是否以某个文字开头; 字符串是否以某个文字结尾; includes:判断字符串是否有某个字符(split炸要是成三段就是含有这个字符)
Object.portotype.toString.call(对象名);
是对象,像数组能遍历,但是不能用数组方法
之前getElementByTagNames等获取到的就是。
var arrv = Array.prototype.slice.call(obj);
for(var i = 0 ; i <obj.length;i++){ console.log(obj[i}); }
function fn(){ console.log(arguments); } fn(1,2,3);arguments是存放实参的伪数组
所有用对象调用的方法,this代表这个对象 函数定义不知道this是什么,只有调用的时候才知道。
点击调用函数的时候,相当于调用了document的onclick方法
for(var i=0;i<imgs.length;i++){ imgs[i].onclick = function(){ var path = this.src; //利用this获取变化的i值 document.body.style.backgroundImage = 'url('+path+')'; document.body.style.backgroundRepeat = 'no-repeat'; document.body.style.backgroundSize = '100% 100%'; box.style.height = 0; } }将fn中的this改为arr
感觉讲的非常详细,可以点这个链接去看看 undefined+undefined = NaN
也是调用函数,和call差不多,也能改变this
函数的实参会组成数组传入
var arr =[1,2,3]; var obj ={ name:"张三", fn(a,b,c){ console.log(c) } } obj.fn.apply(arr,[1,2,3]);复制函数,参数相当于复制出函数里面的this
下一篇:DOM高级-运动
注:全篇为个人笔记,仅供参考,如有错误请指出