应用
-
网页特效
-
数据验证
-
游戏
-
App
-
私下跟后端做些小事情
-
...
-
总之, Js 能干的事太多了, 甚至有人认为, Js一门语言干啥都够了.
历史
1992年, 一个叫 Nombas 的公司, 研发了一门语言叫 "C减减"(C-minus-minus, 简称"Cmm"), 是一款能够在浏览器端运行的脚本语言, 主要用于表单数据的验证, 例如 "密码是否相同", "是否有表单未填写"等. 后来由于 C减减的名字太特殊, 改名为 "ScriptEase".
后来, 最早的浏览器公司"网景" (Netscape) 发现网络越来越发达, 网页内容也越来越多, 表单验证的时间越来越长, 用户体验感极速下降. 于是也想开发一个类似于 ScriptEase 的语言, 来解决这样的问题.
1995年, 网景公司成功研发LiveWire脚本语言, 以代替ScriptEase, 应用于 Netscape Navigator 2.0, 后更名为 "LiveScript"
同年(95年), Netscape Navigator 2.0 Beta 3 发行时, 又将 "LiveScript" 更名为 "JavaScript", 目的是想蹭蹭 Java的热度, 当时导致了很多程序员对这门语言有诸多误解.
三分天下:
因为 Js 比较成功, 所以 "微软" 也来参了一脚, 发行"JScript"
Nombas 的 ScriptEase
Netscape 的 JavaScript
Microsoft 的 JScript
标准化:
由于三门语言效果一样 且 互不兼容, 所以在1997年, 为了有更统一的标准, ECMA协会综合多个大牛, 重新定义了名为 "ECMAScript" 的全新脚本语言, 简称 "ES"
至今, ES已经发展到了 ES6
由于ES 是Js提交的草案, 所以Es 有很多标准是采用的Js, 导致很多人把Js和Es就理解为一个人了. 所以我们现在所说的Js, 基本就是再说Es, 简单理解: Js是通俗说法, Es是标准说法.
Js 学习内容
1. 核心知识 ECMAScript
2. 文档对象模型 DOM
3. 浏览器对象模型 BOM
4. 框架
基础框架: JQuery, BootStrap
高级框架: Vue, React, Angular
注意点(记)
-
Js: 是一门客户端的脚本语言, 也有服务端的js版本, 例如 Node.js
-
Js: 是不能读写客户端上的文件(除了浏览器的cookie文件)
-
Js: 是不能写服务端上的文件, 但可以读取服务端的文件数据
浏览器引擎
-
每一个浏览器都有一个强大的内核, 来支撑着画面的渲染 和 数据的计算
浏览器的内核组成(记)
-
浏览器内核分成两部分: 渲染引擎 + Js引擎
渲染引擎
-
根据HTML代码, 向网页显示各种文字、图形, 也能给文字, 图形添加各种颜色, 还可以对文字、图形做各种排版
-
各大浏览器的渲染引擎:
-
IE - Trident引擎 -ms-
-
Firefox - Gecko引擎 -moz-
-
Chrome/Safari - WebKit 引擎 -webkit-
-
Opera - Presto引擎
-
Chrome + Opera 联合开发的 Blink引擎
-
Js 引擎
-
本来也是渲染引擎里面的一部分, 但后来Js越做越大, 便独立出来了. Js引擎读取网页中的 Js代码, 并对其进行处理. 例如 算术运算, 变量声明, 事件调用等等
-
各大浏览器的Js引擎:
-
旧IE - Jscript引擎
-
IE9 - Chakra引擎
-
IE Edge - Chakra引擎
-
Firefox - monkey引擎
-
Safari - SquirrelFish引擎
-
Opera - Carakan引擎
-
Chrome - V8引擎 ( Node.Js 也封装了V8引擎 )
-
-
Js使用方式
外部导入
<script src="css地址"></script>
可写在头部,也可写在body中 常写在最后面
原因
* 只有在js导入完成后 才执行后面的内容
* 当放到最后时,先执行js外部导入
内部现写js
<script>
alert('弹窗');
</script>
* 只有在js导入完成后 才执行body的内容
事件触发js
-
onclick 就是 html属性, 代表 单击事件
<button onclick="alert('通过点击按钮触发')">点我一下</button>
基础语法
分号
-
Js 的每条语句均以 分号 结尾. 代表该语句已经结束. 准备执行下一条语句
-
注
-
用分号可以将 多条语句 并列在一行. (不推荐)
-
推荐一条语句 独立占一行
-
一条语句 最好不要超过80个字符
<script>
alert('1111') alert('2222') // 报错
alert('1111'); alert('2222'); // 正常
alert('1111')
alert('2222') 换行算分号 不推荐
</script>
-
空格
-
在运算符的前后, 添加空格. 增加代码的可读性
-
<script>
alert(1 + 2);
</script>
代码块{ }
-
ES6 新增语法
-
作用: 多条语句进行捆绑执行
大小写
-
JS 严格区分大小写
控制台
-
F12----> console
-
控制台: 可以当场执行js代码, 可以查看所有的数据, 可以查看语法错误
保留字, 关键字
-
Js 引擎默认就有的词语, 是无法自定义 (将来的变量, 函数等无法使用)
break case catch continue default
delete do else finally for
function if in instanceof new
return switch this throw try
typeof var void while with
注释
-
单行注释: // 注释内容
-
多行注释: /* 注释内容 */
变量
定义
-
存储数据的容器, 类似于数学中的未知数
格式
-
var 变量名;
-
var 变量名 = 值;
-
var 变量名1 = 值1, 变量名2 = 值2, 变量名3 = 值3, ....;
-
注:
-
不要使用 var 变量名1 = 变量名2 = 变量名3 = 值;
-
js中同等级分隔开一般情况用, 隔开
-
变量输出
-
alert(变量)
-
console.log(变量1, 变量2, ...) 在控制台输出
-
document.write(变量) 在网页输出
-
会刷新页面后输出 比如原来的触发事件会被刷新
-
标识符,标记
定义
-
每个变量都有标记,称之为"变量名"
标记(变量)命名规范
-
可以包含数字, 字母, 下划线 和 $符号 (支持汉字,少用)
-
不能使用数字开头
-
不能使用关键字,保留字
-
区别大小写
-
取名要有意义, 提高代码的可读性
未定义变量
-
没有命名的变量,则称为"未定义变量"
-
未定义变量不要直接使用, 一旦使用则会报错
扩展-常用的命名规范
-
驼峰式命名法: addUserName
-
帕斯卡命名法: AddUserName
-
匈牙利命名法: sAge (第一个字母具有数据类型的意义 s: 字符串 i: 整数)
变量的提升 Hoisting
EC6 新增写法
var
-
全局变量
-
可以重复声明 var命名的重名变量,后面的或覆盖前面的
-
支持变量提升
let
-
只能在当前作用域中使用 body体包含块级 相当于最大块
-
不属于window, 严格意义上, 并非全局变量
-
不能重复声明
-
不支持变量提升
// window 全局
var x7 = 70;
let y8 = 80;
console.log(x7); //70
console.log(window.x7); //70 属于window全局变量
console.log(y8); //70
console.log(window.y8); //undefined let 变量 不属于window
const 常量
-
声明时, 必须初始化
-
声明时, 不能与其他变量重名
-
声明后, 不能修改值
-
作用域, 块级作用域
-
不支持常量提升
-
注:
-
变量定义未赋值 undefined
-
变量未声明就使用 不报错
-
document.write(m)// 更新页面输出 页面会刷新
-
数据类型
原始类型(基础类型)
-
string 字符串
-
number 数字
-
boolean 布尔
-
null 空
-
undefined 未定义
-
symbol ES6 新增类型
引用类型(复合类型)
-
array 数组
-
object 对象
-
function 函数
字符串 string
定义
-
包含数字, 字母, 下划线, 汉字, 标点等任意字符
格式
-
单引号 ''
-
双引号 ""
-
反引号 `` (识别变量) 格式: ${变量}
-
注:
-
单双引号不能自插, 只能互插
//变量识别 var address = '海底捞';
var str = `今天晚上准备去 ${address} 吃一顿 `;转义字符</pre>
-
转义字符
-
转义符: \
-
作用:
-
特殊符号 => 普通符号 \\ ' " ...
-
普通符号 => 特护符号
\n 换行 (常用) windows中windows中 \n\r 两者一起为换行 \r 回车 \t 水平制表
-
拼接符 +
-
字符串运算 只有 + , 是拼接,而非加法
-
可用于 字符串变量识别
var num = 50; console.log( `今天所有错题每道 ${num} 遍` ); console.log( '今天所有错题每道 '+ num +' 遍' );
字符串长度
-
字符串变量.length 换个算法, 不按字节数算
类型获取
-
typeof 变量
-
typeof ( 变量 )
-
typeof 具体值
-
typeof( 具体值 )
类型转换
-
String(变量)
-
String(具体值)
-
返回值: 字符串类型的变量
-
注
-
传给Strnig()的变量不会受到影响 给一个变量去接收
-
知识普及
最早的计算机, 只有128个字符, 别称之为 "ASCII"码, 不支持汉字 字母, 数字, 标点 占1B计算机普及, 全世界都在用计算机, 各个国家的语言不同, 所以各自发明自己国家的编码, 例如中国GBK. 导致语言不通, 一旦访问其他国家的网页时, 出现了乱码. Unicode 应运而生, 搜集全世界大多数的语言, 解决的乱码的问题. Unicode 的空间使用: 字母, 数字, 汉字, 日文, 韩文... 占多个字节(B) 由于 Unicode 的空间使用率极低, 优化Unicode, 从而出现 UTF-8 编码 字母, 数字, 标点 占1B 常规汉字占3B 僻字占4B 龘</pre>
数字 number
-
整数
-
浮点数( 小数 )
-
科学计数法 e
var x = 19; console.log( x, typeof x );//19 "number"
// 浮点数
var x = 1.5;
console.log( x, typeof x );//1.5 "number"// 科学计数法
var x = 2e3; // 2 乘以 10 的 3次方 字母e 不区分大小写
console.log( x, typeof x );2000 "number" -
无穷
-
正无穷 Infinity
-
超过 1.7976931348623157e+308(最大值) 即为无穷数 308次方
-
-
负无穷 -Infinity
-
-
5e-324(边界值)
-
超过 5e-324(边界值) 即为0 -324次方
-
5e-324+1 为1
-
5e-324-1 为-1
-
5e-325 为0
-
-5e-325 为-0
-
-
NaN
-
Not a Nunber 不是一个数
-
number 一种特殊形态, 只要不是数, 全部认为是NaN
-
isNaN() 判断是否是NaN
-
返回值: true 是NaN
-
false 不是NaN
-
-
NaN特性:
-
NaN 与 任何数(原始类型)运算, 结果都是NaN
-
NaN 与 任何数比,结果都是false
-
0/0 的结果是 NaN
console.log( NaN + 5 ); console.log( NaN + 10.5 ); console.log( NaN + true ); console.log( NaN + NaN ); console.log( NaN + null ); console.log( NaN + undefined ); console.log( NaN * 'abc' ); console.log( NaN * 0 ); console.log( NaN / 0 ); console.log( 0 / 0 ); // NaN console.log( 1 / 0 ); // Infinity console.log( NaN + 'a' ); // NaNa
console.log( NaN == 1 );
console.log( NaN == NaN );
console.log( NaN > NaN );
console.log( NaN < NaN );
console.log( NaN < 100 ); -
-
进制之间的转换
基数 前缀 二进制 0-1 0b 八进制 0-7 0 或 0o 十进制 0-9 十六进制 0-9 a-f 0x
-
进制转换
-
其余进制 => 十进制 parseInt()
-
parseInt(基数, 当前进制)
-
注: 当前进制可省略, 默认为10进制
-
-
十进制 => 其余进制 toString()
-
toString(进制)
-
-
浮点运算
-
浮点数在转为二进制时, 会有部分差异, 结果并不完全准确, 所以, 不推荐使用浮点进行 等值比较
<script> var num1 = 0.1; var num2 = 0.2; console.log( num1 + num2 );//0.300000000004if( num1 + num2 == 0.3 ){ console.log('Yes'); }else{ console.log('No'); } //No </script></pre>
类型转换
-
Number(内容)
-
parseInt(内容) Int 代表整数
-
parseFloat(内容) Float 代表浮点数
-
骚操作: 在数值前面加 + 号, 也能让数值转为number
<script> var num = '10.5'; var num2 = +num; console.log( num, typeof num );//10.5 string console.log( num2, typeof num2 );//10.5 number </script>
Boolean 布尔类型
-
只有两个值: true 或 false
-
分别代表两种不同的极端状态: 对/错, 是/否, 开/关
场景
-
常用于判断, 比较, 条件表达式
-
注:
-
区分大小写 ( boolean 只认识纯小写)
-
类型转换
-
Boolean(内容)
-
以下8种值通过 Boolean() 转换为false, 其余为true
-
Boolean(0)
-
Boolean(-0)
-
Boolean(0.0)
-
Boolean(NaN)
-
Boolean('')
-
Boolean(null)
-
Boolean(undefined)
-
Boolean(false)
-
-
易错题 返回为true
-
Boolean('0');
-
Boolean('false');
-
Boolean('null');
-
function 函数
定义
-
主要目的是为了将多条代码块进行捆绑封装, 形成一个完成的功能
目的
-
定义一个代码, 可多次使用
-
传入不同的参数, 可产生不同的结果
定义函数
-
function 函数名([参数1, 参数2, 参数3, ...]){ 代码块(功能) }
调用函数
-
函数名();
-
函数名(参数1, 参数2, ...)
返回值
-
格式: return 内容
-
作用1: 在代码块, 通过return返回数据 到调用函数的地方
-
作用2: 立马结束当前的函数, 提前返回到调用函数的地方
-
函数没有return时, 需要执行里面的所有代码块, 并返回undefined
// function 类型 function demo6(){ console.log(666); }// var x = demo6(); // 调用函数, x = demo6的返回值 var y = demo6; // 将 函数 交给 y, y = demo6函数本身, 所以y 也变成一个函数 demo6(); y(); //两者等价 console.log( typeof y );</pre>
Array 数组
定义
-
可理解为是: 大容器(书包, 箱子, 盒子)
定义数组
-
格式: [值1, 值2, 值3, ...]
获取数组中的一个数据
-
格式: 变量[索引]
-
出索引范围, 则返回undefined
新增数据
-
可通过 不存在索引 进行添加
-
格式: 变量[索引] = 值 不推荐
-
格式: 变量.push(值) 店长推荐
-
-
.push() 会在原有数组的最后面添加一个值, 不会发生断开的索引
-
不连续的索引, 中间会认为是undefined(empty的那些)
删除数据
-
格式: 变量 = [] 清空数据
-
格式: 变量.splice(索引, 长度) 不保留索引位置, 后面会向前挤
-
格式: delete 变量[索引] 保留索引位置, 后面不会向前挤
修改数据
-
可通过 已存在的索引 进行修改
-
格式: 变量[索引] = 值
-
类型转换
-
array的类型: object
-
历史遗留BUG, 本应是array, 但js中认为是object
-
在后期 一切皆对象
-
object对象
定义
-
对象也是大容器
-
Arary 给数据分诶索引
-
Object 给数据分配属性 (提高代码的可读性)
定义对象
{ 属性名: 属性值, 属性名: 属性值, ... 属性名: 属性值, 方法名: function (){ 代码块 } }
-
注
-
方法也是函数的一种
-
对象主要有 属性 和 方法组成
-
使用属性
-
对象.属性名
-
注: 属性名若由多个单词 或 奇怪的字符组成, 建议加引号
-
格式: 对象['属性名']
-
使用方法
-
对象.方法名()
<script> var woman = { 'name':'杨幂', 'age':18, job: '演员', '☆': '五角星', skill: function(){ console.log('腿长'); } };console.log( woman.name ); console.log( woman.age ); console.log( woman.job ); console.log( woman.skill() ); console.log(typeof woman); // 奇葩符号的读取 // console.log( woman.☆ ); console.log( woman['☆'] );
</script>
undefined
-
未定义, 不存在
-
由如下几种情况, 值为undefined
-
变量已经声明, 却没有赋值
-
对象属性为赋值, 则默认为undefined
-
调用函数时, 应提供的参数没提供, 则参数默认为undefined
-
默认没有返回值时, 默认返回undefined
-
null
-
定义: 空
-
一般情况, null 都是主动赋予的
-
作用: 占位
var woman = { 'name': '杨幂', obj': null, }
null 和 undefined 的区别
-
null 是关键字, undefined 不是关键字
-
null 和 undefined 是等价的, 只是数据类型不同
console.log( null == undefined ); // == 比较两边的值 是否相等 console.log( null === undefined ); // === 比较两边的值 是否相等 且 两边的数据类型是否相等
栈堆内存
数据类型分类
-
原始类型: string, number, boolean, null, undefined, symbol
-
引用类型: array, object, function
原始类型
-
原始类型的值称之为: 原始值
-
原始值 都存储在 栈内存中
-
栈内存中的数据都是直接访问的
-
效率较高
-
存储空间固定 且 小
引用类型
-
引用类型的值称之为: 引用值
-
引用值 都存储在 堆内存中
-
堆内存中的地址(指针)都是来引用 具体的值
-
效率较低
-
存储空间不固定 且 大
小结:
-
栈内存 是操作值
-
堆内存 是操作地址(指针)
类型转换
转为number
-
Number()
-
字符串: 只要字符串出现非数字之外的字符, 都是NaN(除了第一个字母e 或 第一个小数点)
-
布尔: true => 1
-
false => 0
-
-
其余: null => 0
-
undefined => NaN
-
-
-
parseInt()
-
字符串: 保留第一个非数字之前的所有数字, 其余抛弃
-
以非数字开头,直接认为是NaN
-
true, false, null, undefiined 都是NaN
-
-
parseFloat()
-
字符串: 保留第一个非数字之前的所有数字, 其余抛弃 (除第一个字母e 或 第一个小数点)
-
以非数字开头, 则认为是NaN
-
true, false, null, undefined 都是NaN
-
转为string
-
String() 任意类型都可以原样转为string类型
-
.toString() 任意数字, 字符串, 布尔均可以转为string 类型
转为 boolean
-
Boolean()
-
有8种情况会转为false, 其余都是true
-
0
-
-0
-
0.0
-
NaN
-
''
-
null
-
undefined
-
false
-
算术运算符
+ - * / / 不是整除 5 / 2 = 2.5; % 取模, 求余数 ** 指数
取模规律
-
规律1: 小数据 除以 大数据的余数 都是 小数据
-
console.log( 3 % 5 ); //3
-
-
规律2: x ~ y 取模的结果范围: 任意数 %(y-x+1) + x
%(y-x+1) + x 的结果: x~y// %5 的结果: 0~4
// %n+1 的结果: 0~n
// %n 的结果: 0~n-1//%6 + 5 的结果: 5~10
0 ~ n 0 + x = 5 ==> x = 5;
- x n + x = 10 ==> n = 5;
5 ~ 10 ==> 0 ~ 5 ==> %6 + 5
// 编程题: 判断一个数是否为偶数
function isEven( n1 ){
// 任意数 % 2的余数为 0, 则证明该数是 偶数, 否则都是奇数
if( n1 % 2 == 0 ){
return true
}
return false;
}
-
规律3: 取模结果的正负 完全取决于第一位数的正负
console.log( 5 % 3 ); //2 console.log( 5 % -3 ); //2 console.log( -5 % 3 ); //-2 console.log( -5 % -3 ); //-2
-
// 指数, 幂 console.log( 2 ** 3 ); //8
自增, 自减
-
++: 给自己+1
-
--: 给自己-1
-
写法:
-
a++ 先返回变量a, 在给a+1
-
++a 先给a+1, 在返回变量a
-
复杂运算画内存图
-
-
赋值运算符
-
= 先计算右边, 再赋值给左边
-
+= a += b ==> a = a + b;
-
-= a -= b ==> a = a - b;
-
*= a *= b ==> a = a * b;
-
/= a /= b ==> a = a / b;
-
%= a %= b ==> a = a % b;
// 带坑 var a = '10'; var b = 20; a += b; console.log(a, b);//1020 20
比较运算符
-
值: boolean
* > >= * < <= * == 判断两边的值是否相等 * === 判断两边的值是否相等 且 数据类型是否相等(全等, 恒等) * != 判断两边的值是否不等 * !== 只有两边全等时为false, 其余都为true
三元运算符
-
一元运算: a++
-
二元运算: + - * / == > <
-
三元运算: ?:
格式:
-
条件表达式 ? true环境 : false环境
三元运算规则
-
将条件表达式的最终 结果转为boolean,
-
如果是true, 则执行true环境
-
如果是false, 则执行false环境
-
三元可以嵌套 (使用频率较低)
// var lv = 6; // var lv = prompt('请输入您的等级'); // prompt() 输入框// console.log(lv == 1?'青铜':(lv == 2?'白银':(lv == 3?'黄金':(lv == 4?'铂金':(lv == 5?'钻石':(lv == 6?'星耀':(lv == 7?'王者':(lv == 8?'荣耀王者':(lv == 9?'巅峰王者':'职业王者')))))))));</pre>
-
注:
-
元仅仅适合简单的if判断
-
如果是复杂判断, 推荐使用if分支
-
逻辑运算符
运算符 运算规则 逻辑与 && 两边为真即为真(取最后一个真),一边为假即为假(取第一个假) 逻辑或 || 一边为真即为真(取第一个真), 两边为假即为假(取最后一个假) 逻辑非 ! 真即为假, 假即为真 (结果必然是boolean)
-
注:
-
优先级: 逻辑非 > 逻辑与 > 逻辑或
-
var x = 10; var y = 0; console.log( x && true ); //true console.log( y && true ); //0 console.log( true && x ); //10var x = 10; var y = 0; console.log( x || false ); //10 console.log( y || false ); //false var x = 10; var y = 0; console.log( !x ); //false console.log( !y ); //true</pre>
位运算符
运算符 运算规则 按位与 & 一个为0即为0, 否则为1 按位或 | 一个为1即为1, 否则为0 按位异或 ^ 相异为1, 相同为0 按位取反 ~ ~ x = -x - 1 左移 << 左移n位, 低位补0 右移 >> 右移n位, 正数: 高位补0 负数: 高位补1 >>> 右移n位, 高位补0, 带符号 (最高位是符号位: 0为正数, 1为负数)
-
注:
-
了解原码, 反码, 补码
-
-
<< 和 >> 和 >>> 的正数位移:
-
求原码
-
左右位移
-
-
<< 和 >> 的负数位移:(正数的补码即负数的原码)
-
把负数当正数用
-
求正数的补码
-
左右位移
-
减1
-
求反码
-
加符号位
-
-
负数位移>>>:
-
负数当正数用
-
求补码
-
左右移动
-
-
对于x << n ===> 即 x * 2 ** n 3 << 2 即 3 * 2 ** 2 = 12;
-
对于正数x >> n ===> x / 2 ** n 取整
var x = 13; console.log( ~x ); // -x-1 = -13-1 = -14var x = -13;
console.log( ~x ); // --13 - 1 = 12// 原码, 反码, 补码 (32位)
// 整数 38
// 原码: 00000000000000000000000000100110 (38的二进制)
// 反码: 11111111111111111111111111011001 (38的二进制全部取反)
// 补码: 11111111111111111111111111011010 (反码 + 1)//-38 << 1
//1.求正数的补码 38 = 32 + 4 + 2
原码: 00000000 00000000 00000000 00100110
反码: 11111111 11111111 11111111 11011001
补码: 11111111 11111111 11111111 11011010
//2.左移 111111111 11111111 11111111 10110100
//3.减1 111111111 11111111 11111111 10110011
//4.取反码: 000000000 00000000 00000000 01001100
//5.加符号位: -76var x = -42; //32 + 8 +2 10 1010
console.log( x >> 1 ); //-21
// 原码 00000000 00000000 00000000 00101010
// 反码: 11111111 11111111 11111111 11010101
// 补码: 11111111 11111111 11111111 11010110
// 右移1位 1111111 11111111 11111111 11101011
// 减1 1111111 11111111 11111111 11101010
// 求反码 0000000 00000000 00000000 0001 0101 ==>21
// 加符号位-21//-38 >>> 1
//1.求正数的补码
原码: 00000000 00000000 00000000 00100110
反码: 11111111 11111111 11111111 11011001
补码: 11111111 11111111 11111111 11011010
//2.右移1位: 01111111 11111111 11111111 11101101 0 ==> 2 ** 31 -1 -2 -16
其余运算符
-
void
-
意思: 无效的, 空白的
-
可理解为: 没有返回值 或 undefined
-
-
格式: void变量
-
格式: void(变量) 推荐写法
-
应用场景: 常被用于"禁止超链接的刷新"
//禁止刷新 <input type="text"> <a href="">baidu</a> <a href="javascript:void(0)">baidu</a>
-
new
-
意思: 实例化
-
格式: new 对象
-
-
应用场景: 面向对象时使用, 创建一个对象
var x = 10; console.log( void x );//undefined console.log( vo var x = 10; var y = new Number(10);/ console.log( x + y );//10 console.log( x == y ); //true console.log var z = new String('ab cef g9876 5'); console. console.log(z.length); //14 console.log(z.search('x')); //-1 console.log(z.substr(4,3)); //ef 有空格 console.log(z.split()); //[ab cef g9876 5] 默认全部 console.log(z.split(' ')); // [ab,cef,g9876,5] console.log(z.split(' ', 2));//[ab,cef]
运算符优先级
Js 运算符优先级 优先级 运算符 描述 关联性 20 ( ) 圆括号 19 . 成员访问 左 [ ] 数组 左 new( ) new( 带参数 ) xx() 函数调用 左 18 new New( 无参数 ) 右 17 ++ 递增 -- 递减 16 ! 逻辑非 右 ~ 按位非 右 + - 正负 右 typeof 类型符 右 void 空 右 delete 删除符 右 15 ** 幂 右 14 * / % 乘除 取模 左 13 + - 加减法 左 12 << >> >>> 按位左/右移 无符号右移 左 11 < <= > >= 比较 左 in 左 instanceof 左 10 == != === !== 比较 左 9 & 按位与 左 8 ^ 按位异或 左 7 | 按位或 左 6 && 逻辑与 左 5 || 逻辑或 左 4 ?: 三元 右 3 = += -= *= /= %= <<= >>= >>>= &= ^= |= 各种赋值 右 2 yield 生成器 1 , 逗号操作符 左
17 ++ 递增 -- 递减 16 ! 逻辑非 ~ 按位非 + - 正负 15 ** 幂 右 14 * / % 乘除 取模 13 + - 加减法 左 12 << >> >>> 按位左/右移 无符号右移 11 < <= > >= 比较 10 == != === !== 比较 9 & 按位与 8 ^ 按位异或 7 | 按位或 6 && 逻辑与 5 || 逻辑或 4 ?: 三元 3 = += -= *= /= %= <<= >>= >>>= &= ^= |= 各种赋值
运算技巧
倍数关系
-
<<n 乘以2的n次方
-
>>n
-
除以2的n次方 (抛弃小数位)
-
因为抛弃小数位, 右移0位, 可以实现取整效果
-
<script> // 左移 - 翻倍 var x = 20; console.log( x << 1); console.log( x << 2); console.log( x << 3);// 右移 - 缩小 var x = 20; console.log( x >> 1); console.log( x >> 2); console.log( x >> 3); // 取整 var x = 20.5; console.log( x >> 0); </script></pre>
取整
-
按位或0
-
按位异或0
-
双取反
-
右移0位
<script> var x = 10.5; console.log( x ^ 0 ); // 10 1010 0000 console.log( x | 0 ); // 10 console.log( ~~x ); // 10 console.log( x >> 0 ); </script>
奇偶数
-
按位与1
-
结果为0 : 偶数
-
结果为1 : 奇数
-
<script> console.log( 0 & 1 ); // 0 console.log( 1 & 1 ); // 1 console.log( 2 & 1 ); // 0 </script>
交换数据
-
经典写法 (采用临时变量, 也被称为之第三方变量)
-
效率写法 (三次异等)
<script> // 经典写法 var a = 5; v var tmp = a; a = b;console.log(a, b); console.log('------------- 分隔符 ------- // 效率写法 (没有申请第三个变量, 内存节省) var a = 5; v a ^= b; b ^= a; a ^= b; console.log(a, b);
</script>
简易DOM操作
获取标签对象
-
通过 id获取 document.getElementById('id名');
-
通过 class获取 document.getElementsByClassName('class名');
-
通过 标签名获取 document.getElementsByTagName('标签名');
-
id 得到的是一个 对象
-
class 得到的是一个 集合
-
标签 得到的是一个 集合
<script> // id 得到的是一个 对象 var books = document.getElementById('book'); console // class 得到的是一个 集合 var oneList = document.getElementsByClassName('one'); console.log(oneList); console.log(oneList[0]); console.log(oneList[1]); console.log( var fourList = document.getElementsByClassName('four'); console.log(fourList); console.log(fourList[0]); console.log(fourList[99]); // 超出范围的索引, // 标签 得到的是一个 集合 var list = document.getElementsByTagName('li'); console.log(list); </script>
查看对象
-
console.log(对象)
-
console.dir(对象) 详细的查看对象的属性和方法(并非所有的都是准确(兼容性))
console.log(books); console.dir(books);
设置css属性
-
元素对象.style.css属性名 = 属性值;
-
对象要具体, 不能个集合赋值
-
<script> books.style.color = 'red';oneList[0].style.color = 'blue';
// oneList.style.color = 'green'; oneList 是一个集合, 并非具体的元素对象
</script>
设置/获取对象属性
-
获取属性格式: 对象.属性名
-
设置属性格式: 对象.属性名 = 属性值;
-
注: 这里值的属性 不是 css属性
-
// 获取属性 console.log( tel.type ); console.log( tel.value ); console.log( tel.id ); console.dir( // 设置属性 tel.type = 'password';
获取/设置 对象的正文内容
-
获取内容格式: 对象.innerHTML
-
设置内容格式: 对象.innerHTML = 内容
// 设置内容 box.innerHTML = '打嗝要命, 饿了';// 获取内容
console.log( box.innerHTML);
循环结构-分支
分支结构
-
分支作用: 有选择的跳过部分代码
条件表达式
-
小括号() 中的条件表达式, 无论怎么变化运算, 最终只需要套上Boolean()转换一下
-
若是true, 则条件成立
-
若是false, 则条件不成立
-
代码块
-
大括号{} 中可以写一条, 两条, 更多条语句, 甚至没有语句
if 分支
单向分支
-
if(条件表达式) 一条语句
-
if(条件表达式){
代码块
}
双向分支
if(条件表达式){ 代码块(成立) }else{ 代码块(不成立) }
多向分支
if(条件表达式1){ 代码块(成立1) }else if(条件表达式2){ 代码块(成立2) }else if(条件表达式3){ 代码块(成立3) }else if(条件表达式4){ 代码块(成立4) }if(条件表达式1){
代码块(成立1)
}else if(条件表达式2){
代码块(成立2)
}else if(条件表达式3){
代码块(成立3)
}else{
接盘侠
}
-
注: else if 中间必须保留一个空格
巢状分支
if(条件表达式1){ if(条件表达式2){ if(条件表达式3){ 代码块(同时满足条件1, 2, 3) }else{ 代码块(满足条件1,2, 不满足3) } }else{ 代码块(满足条件1, 不满足2) } }else{ 代码块(不满足条件1) }
switch 分支
switch( 标志 ){ case 标志1: 代码块; break; case 标志2: 代码块; break; case 标志3: 代码块; break; ... case 标志n: 代码块; break; default: 代码块(接盘侠); break; }
-
注: * 当标记都无法进行匹配时, 才会执行default * switch是恒等关系
// 带坑 var x = 1;// switch( x ){//666
switch( x > 0 ){//111
case '': console.log('888'); break;
case true: console.log('111'); break;
case null: console.log('222'); break;
case false: console.log('333'); break;
case undefined: console.log('444'); break;
case '1': console.log('555');break;
case 1.0: console.log('666');break;
case 3-2: console.log('777');break;
default: console.log('000');break;
}
循环
-
符合循环条件之后, 重复执行{}中的代码, 直到条件不成立 或 遇到break 为止
-
总结:
-
功能相似, 位置相同, 用循环
-
功能相似, 位置不同, 用函数
-
常用循环
-
while
-
do / while
-
for
-
for / in
-
循环三要素
-
初始值
-
循环条件 (就是条件表达式)
-
循环增量 (不代表只能增, 也可以减, 乘, 除, 逻辑与或非 ... )
-
while循环
①初始化 while( ②循环条件 ){ ③代码块 }执行顺序: 1 -> 2成立 -> 3 -> 2 -> 3 -> 2 -> 3 ...
2不成立 -> 结束循环
do / while 循环
①初始值 do{ ②代码块 }while(③循环条件);执行顺序: 1 -> 2 -> 3成立 -> 2 -> 3 -> 2 -> 3 -> 2 ...
3不成立 -> 结束循环
-
while 和 do/while 之间的区别
-
while 是先判断, 再执行
-
do/while 是先执行1次代码块, 再判断,再执行
-
for循环
for( ①初始值; ②循环条件; ③循环增量){ ④代码块 }执行顺序: 1 -> 2成立 -> 4 -> 3 -> 2 -> 4 -> 3 ...
2不成立 -> 结束循环
for / in 循环
-
定义: 专门为遍历对象
-
格式:
for( 变量 in 对象){ 代码块 }
-
注:
-
属性名: 由 变量 获取
-
属性值: 由 对象[变量] 获取
-
-
流程控制符
-
continue 立马结束当前一轮循环, 准备执行下一轮循环
-
break 立马结束循环 or Switch分支, 准备执行循环/分支之外的代码
-
注:
-
break 不能结束if分支, 仅能结束循环 和switch
-
多重循环时, break 只能结束最近一个包含break的循环
-
break 和 continue 执行后, 后面的语句都不执行.
-
无限循环
-
俗称: 死循环
-
如何实现: 只需要 "循环条件永远成立" 即可形成无限循环
-
场景: 当不知道要循环多少次, 即可使用无限循环
获取三位数的个位,十位,百位
-
规律:
-
任意数 % 10 保留最后1位
-
任意数 % 100 保留最后2位
-
任意数 % 1000 保留最后3位
-
...
-
-
任意数 / 10 抛弃最后1位
-
任意数 / 100 抛弃最后2位
-
任意数 / 1000 抛弃最后3位
-
...
坑点
语法坑
-
初始化位, 可以为空
var i = 0;for( ; i < 10; i++ ){
document.write(i+' ');
}
document.write('<hr />');
-
增量位, 可以为空
for(var i = 0; i < 10; ){ document.write(i+' '); i++; } document.write('<hr />');
-
循环条件为空, 则默认为 条件成立
for(var i = 0; ; i++ ){ document.write(i+' '); }
-
多初始化 + 多增量
for(var i = 0, j = 9 ; i < 10 && j > 5 ; i++, j--){ document.write(i+' '); } document.write(i); document.write(j); document.write('<hr />');
-
作用域
for(var m = 0; m < 10; m++){
}
console.log(m); // 10for(let n = 0; n < 10; n++){
}
// console.log(n); // 报错
易错题
var x = 10; var x; console.log(x); // 10 注意: 不是undefinedfor(var i = 0; i < 10; i++){ document.write(i*2 + ' '); } document.write('<hr />'); for(var i = 0; i < 10; i++){ document.write(i++ + ' '); } document.write('<hr />'); for(var i = 0; i < 10; i+2){ document.write(i++ + ' '); } document.write('<hr / >');</pre>
-
临时变量标记的使用
-
星阵图 先行再列
* ** *** **** *****
i 控制行 j 控制列
i = 0 内循环要循环1次 j = 0; j < 1 ; j++ i = 1 内循环要循环2次 j = 0; j < 2 ; j++ i = 2 内循环要循环3次 j = 0; j < 3 ; j++ i = 3 内循环要循环4次 j = 0; j < 4 ; j++ i = 4 内循环要循环5次 j = 0; j < 5 ; j++ j = 0; j < i+1; j++ 初始值可随意, 只需保证循环次数正确即可 i = 0 内循环要循环1次 j = 10; j < 11 ; j++ i = 1 内循环要循环2次 j = 10; j < 12 ; j++ i = 2 内循环要循环3次 j = 10; j < 13 ; j++ i = 3 内循环要循环4次 j = 10; j < 14 ; j++ i = 4 内循环要循环5次 j = 10; j < 15 ; j++ j = 0; j < i+11; j++</pre>
***** **** *** ** *
***** -**** --*** ---** ----*
-
倒映数 3 2 1 0 1 2 3
<script>// -3 -2 -1 0 1 2 3 for(var i = -3; i <= 3; i++){ document.write(i+' '); } document.write('<hr />'); // 3 2 1 0 1 2 3 for(var i = -3; i <= 3; i++){ // 临时变量 var tmp = i; if(tmp < 0){ tmp *= -1; } document.write(tmp+' '); } document.write('<hr />'); </script></pre>
* ** *** **** *** ** * i=-3 tmp=3 循环1次 j=0; j<1 ;j++ i=-2 tmp=2 循环2次 j=0; j<2 ;j++ i=-1 tmp=1 循环3次 j=0; j<3 ;j++ i=0 tmp=0 循环4次 j=0; j<4 ;j++ i=1 tmp=1 循环3次 j=0; j<3 ;j++ i=2 tmp=2 循环2次 j=0; j<2 ;j++ i=3 tmp=3 循环1次 j=0; j<1 ;j++ j=0; j<4-tmp; j++<script> for(var i = -3; i <= 3; i++){ var tmp = i; if( tmp < 0 ){ tmp *= -1; } for(var j = 0; j < 4 - tmp; j++){ document.write('*'); } document.write('<br />'); } </script>类型转换
-
转为数字
-
undefined => NaN
-
null ==> 0
-
"" ==> 0
-
"one" => NaN
-
输出套用两层 为undefined
-
输出套用多层 为报错
-
函数
函数定义
-
函数声明
function 函数名( 参数 ){ 代码块 }
-
函数表达式 (匿名函数)
变量 = function ( 参数 ){ 代码块 }
-
构造器
变量 = new Function('参数1', '参数2', ... , '代码块')
-
箭头函数
-
数 ES6新增, 有简化, 有隐式返回等功能 变量 = (参数1, 参数2,...) => { 代码块 }
变量 = (参数1, 参数2, ...) => 结果 等同于 变量 = (参数1, 参数2, ...) =>{ return 结果 }
-
-
注
-
函数声明后, 是需要调用才会执行
-
函数表达式不需要再取一个有意义的函数名
-
构造器的参数和代码块 必须是 string类型出现(使用较少)
-
带箭头函数 ES6新增, 简化格式+隐式返回
-
<script> //无参函数function demo(){ console.log('无参函数的声明'); } demo()//调用 //带参函数声明 function demo2(n1, n2){ console.log('带参函数声明:'+(n1 + n2)); } demo2(2,3);//调用 //函数表达式 var x = function(n1, n2){ console.log('函数表达式:'+(n1 + n2)); } console.log(x,typeof x); x(1,2);//调用 //构造器 var x = new Function('n1', 'n2', 'console.log(n1 + n2);') console.log(x, typeof x); x(1,5); // 带箭头函数 var x = (n1, n2) => { console.log(n1 + n2); } x(1,4); var y =(n1, n2) => { return n1 + n2; } var y1 = y(1,2); console.log(y1); //隐式返回 省略{} 和 return var m = (n1, n2) => n1 + n2; var n = m(5,6); console.log(n); </script></pre>
函数使用
-
函数声明之后, 默认不会自动执行, 需要调用才能执行
-
调用函数: 函数名()
-
引用函数: 函数名
-
-
window对象
-
window 代表浏览器. 使用全局所有可用的变量, 函数
-
-
this对象
-
this 是关键字, 代表当前对象
-
-
注:
-
普通函数内的this, 代表window对象
-
事件函数内的this, 代表当前触发事件的对象
-
<script> function demo(){ return '这是 Demo函数'; }var x = demo();//调用 console.log(x); var y = demo;//引用 //如何使用 引用函数 console.log(y()); </script> <script> function demo2(){ return '这是 Demo2函数'; } demo2(); window.demo2(); console.log(window); </script> <ul> <li>李白</li> <li>阿珂</li> <li>兰陵</li> <li>韩信</li> <li>悟空</li> </ul> <script> function demo3(){ console.log(this);//window } demo3(); var obj = { '姓名': 'xxx1', '老婆': 'xxx2', desc:function(){ console.log(this);//当前对象 console.log(this.姓名+'sdsadasd'); } } obj.desc(); var list = document.getElementsByTagName('li'); console.log(list);//li集合 for(var i = 0; i< list.length; i++){ list[i].onclick = function (){ for(var j = 0; j< list.length; j++){ list[j].style.color='black'; } this.style.color = 'red'; } } </script> <div id="box1"> <img src="\resource\1.gif" width="200" > <img src="\resource\2.jpg" width="200" > <img src="\resource\2.png" width="200" > </div> <div id="box2"> <img src="\resource\1.gif" width="200" > <img src="\resource\2.jpg" width="200" > <img src="\resource\2.png" width="200" > </div> <script> var imgList = document.getElementById('box1').getElementsByTagName('img'); console.log(imgList); for(var i = 0; i<imgList.length; i++){ imgList[i].onclick = function(){ for (var j = 0; j < imgList.length; j++) { imgList[j].style.borderColor = 'transparent'; } this.style.borderColor = 'red'; } } </script></pre>
返回值
-
关键字 return
-
作用1: 将数据返回到 调用函数的地方
-
作用2: 立马结束函数
-
-
返回类型
-
可以返回任意类型
-
函数没有返回return时, 默认返回undefined
-
-
如何一次性返回多个值
-
将多个值 封装到数组, 对象中, 一次性进行返回
-
<script> //返回到调用函数的地方 function demo(n1, n2){ var sum = n1 + n2; return sum; } var x = demo(1,2); console.log(x);//立马结束函数 function demo2(n1, n2){ var sum = n1 + n2; return sum; sum **= 2; } var x = demo(2,3); console.log(x); </script> <script> function demo3(){ function demo4(){ return 999;} return demo4; return demo4(); return {'a' : 1}; return [1,2,3]; return undefined; return null; return true; return '10'; return 10; } var x = demo3(); console.log(x, typeof x); </script> <script> function demo5(){ var x =10; var y = 'abc'; // return x,y; // 只能return 最后一个数据 // return (x,y); // 只能return 最后一个数据 return [x,y];// 推荐使用 [10, "abc"] // return {x, y}; //可以返回 {x: 10, y: "abc"} // return {'num':x, 'str':y};//可以返回 {num: 10, str: "abc"} } console.log( demo5() ); </script></pre>
函数参数
-
参数分类
-
形式参数: 俗称"形参", 定义函数给的参数
-
实际函数: 俗称"实参", 调用函数给的参数
-
-
默认参数
-
形参没有默认值, 传递实参时, 却没有给实参, 那么形参默认为undefined
-
形参有默认值, 传递实参时, 却没有给实参, 那么形参采用 默认值
-
-
参数规则
-
不限制参数的数据类型
-
不检查参数的数据类型
-
不限制参数的个数
-
-
实参个数 = 形参个数 : 完美
-
实参个数 > 形参个数 : 先来后到, 抛弃其余的实参
-
实参个数 < 形参个数 : 先来后到, 多余的参数采用默认值 or undefined
-
实参个数不确定:
-
使用 arguments 对象
-
形参一个都不需要设置
-
<script> //n1, n2 是形参 function demo(n1, n2){} demo(10,20);// 10, 20 是实参 </script> <script> //n1 undefined n2 50 function demo2(n1, n2 = 50){ console.log(n1 + n2); } demo2();//NaN demo2(10);//60 demo2(10,20);//30 </script> <script> //实参个数 = 形参个数 function demo3(n1,n2){ console.log(n1); console.log(n2); console.log('------------- 分隔符 --------------'); } demo3(1,2);//1 //2 //实参个数 > 形参个数 function demo3(n1,n2){ console.log(n1); console.log(n2); console.log('------------- 分隔符 --------------'); } demo3(1,2,3,4);//1 //2 //实参个数 < 形参个数 function demo3(n1,n2){ console.log(n1); console.log(n2); console.log('------------- 分隔符 --------------'); } demo3(1);//1 //undefined //实参个数不确定: arguments 对象 function demo4(){ console.log(arguments); var arg = arguments; console.log( arg[0] );//10 console.log( arg[1] );//20 console.log( arg[2] );//30 console.log( arg[3] );//40 console.log( arg[4] ); // 超出范围 undefined console.log( arg.length ); // 一共有几个实参 } demo4(10,20,30,40); //累计n个参数的总和 function sum(){ //接收所有的实参 var arg = arguments; //累加器 var sum = 0; //循环求和 for (var i = 0; i < arg.length; i++) { sum += arg[i] } return sum; } console.log(sum(1,2,3,4,5,6,7,8,9,12)); console.log(sum(1,2,3,4)); console.log(sum(1,2,3,4,5)); </script></pre>
作用域
-
全局变量: 在函数外定义的变量
-
局部变量: 在函数内定义的变量
-
作用域链
-
当前作用域 -> 其他作用域
-
注: 可由内而外, 不能由外而内
-
局部环境输出 局部变量 √
-
局部环境输出 全局变量 √
-
全局环境输出 全局变量 √
-
全局环境输出 局部变量 x
-
优先从当前作用域中找, 找不到再去外面的作用域找
-
-
-
块级作用域 ES6
-
格式: {代码块}
-
在块级作用域中, 用 let声明变量, 那么只能在块级作用域中使用, 脱离块级作用域则无法使用.
-
用 var 声明变量, 不受块级作用域的影响, 依旧属于全局变量
-
在块级作用域外, 用let 声明变量和用 var声明变量 没有区别
-
底层的归属有点区别
-
var 归属window
-
let 不归属window
-
-
-
-
有var 和 没var 声明的区别
-
在局部环境中, 没有var 声明的变量, 即为全局变量
-
在全局环境中, 建议用var声明变量 -
-
delete 可以删除不用var声明的变量
-
delete 不可以删除用var, let声明的变量
-
<script> //全局变量 y //局部变量 x var x = 10;function demo(){ var y = 20; } // 对于big而言, x : 全局变量 // y : 局部变量 // // 对于small而言, y: 全局变量 // z: 局部变量 // x: 比y更大的全局变量 var x = 10; function big(){ var y = 20; function small(){ var z = 30; } } </script> <script> // 案例1 var x = 10; function big(){ var y = 20; console.log(y); // 局部环境输出 局部变量 √ console.log(x); // 局部环境输出 全局变量 √ } big(); console.log(x); // 全局环境输出 全局变量 √ // console.log(y); // 全局环境输出 局部变量 x console.log('------------- 分隔符 --------------'); // 案例2 // 优先从当前作用域中找, 找不到再去外面的作用域找 var x = 10; // 全局变量x function big(){ var x = 30; // 局部变量x console.log(x); // 局部环境输出 局部变量 √ } big(); console.log('------------- 分隔符 --------------'); // 案例3 var x = 10; // window的全局变量x function big2(){ var x = 20; // big2的局部变量x function small2(){ var x = 30; // small2的局部变量x console.log(x); // 30 } small2(); } big2(); console.log('------------- 分隔符 --------------'); // 案例4 var x = 10; // window的全局变量x function big3(){ var x = 20; // console.log(this.x); // 相当于window.x = 10 function small3(){ console.log(this.x); // 10 console.log(x); // 20 } small3(); } big3(); console.log('------------- 分隔符 --------------'); </script> <script> // 全局作用域 var x = 10; var y = 20; { // 局部作用域 console.log(x); // 10 var y = 30; console.log(y); // 30 var z = 40; console.log(z); // 40 } console.log(z); // 40 console.log('------------- 分隔符 --------------'); // 全局作用域 let x1 = 10; { // 局部作用域 console.log(x1); // 10 let y1 = 20; console.log(y1); // 20 } // console.log(y1); // 报错 console.log('------------- 分隔符 --------------'); // 归属问题 var x2 = 10; let y2 = 20; console.log(window.x2); // var变量属于window console.log(window.y2); // let变量不属于window </script> <script> function demo999(){ var m = 10; n = 20; // 在局部环境中, 没有用var声明的变量可当认为是 全局变量 } demo999(); // console.log(m); // 报错 console.log(n); console.log(window.n); console.log('------------- 分隔符 --------------'); var p = 10; delete p; console.log(p); // 删除失败 // q = 20; // delete q; // console.log(q); // 删除成功 let o = 30; delete o; console.log(o); console.log('------------- 分隔符 --------------'); </script></pre>
自执行函数
-
格式: ()()
-
注:
-
第一个() 里面是写: 匿名函数
-
第二个() 代表: 调用当前匿名函数, 可写实参
-
-
特性:
-
定义完函数时, 就立马自我调用
-
无需取名
-
自成一域 (独自创建一个局部作用域, 将形参与实参设为同名局部环境则无法使用外部重名变量, 从而避免变量污染)
-
-
变量污染: 函数内部使用函数外部的变量, 但是并不需要外部变量,此行为称之为"变量污染"
<script> //无参自执行 (function(){ console.log("嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻"); })();//传参 (function(n1,n2){ console.log(n1+n2); })(2,5); </script> <ul> <li>李白</li> <li>阿珂</li> <li>兰陵</li> <li>韩信</li> </ul> <script> var list = document.getElementsByTagName('li'); console.log(list); for (var i = 0; i < list.length; i++) { list[i].onclick=function(){ console.log(i);//4 } } for (var i = 0; i < list.length; i++) { (function(i){ list[i].onclick=function(){ for (var j = 0; j < list.length; j++) { list[j].style.color="black"; } list[i].style.color="red"; } })(i); } </script></pre>
闭包
-
在函数A中定义了函数B, 函数B使用了函数A的变量,并返回函数B, 即可形参闭包
-
优势
-
可使得函数A的变量的生命周期得到延长
-
-
劣势:
-
由于生命周期延长了, 内存不能及时释放函数A的变量, 导致内存消耗过大
-
<script> function run3(){ var count = 0;function demo(){ count++; console.log(count); } return demo; } var x = run3(); console.log(x, typeof x); x(); x(); x(); x();
</script>
call和apply
call
-
call()
-
作用: 对象A 通过call借用对象B,那么对象A里的this就不用代表A, 而是代表B
apply
-
apply()
-
作用: 对象A 通过apply借用对象B,那么对象A里的this就不用代表A, 而是代表B
call 和 apply 的区别
-
call 和 apply 作用一模一样
-
call 是分别接受参数
-
apply 是接收数组参数
<script> var A ={ 'name': '大哥', method: function (){ console.log('我是'+this.name); },method2: function (age, job){ console.log('我是' + this.name+', 今年' + age +'岁, 做'+ job +'的'); } } var B ={ 'name': '二哥', method: function (){ console.log('我是'+this.name); } } A.method();//this 指向A //我是大哥 B.method();//this 指向B //我是二哥 A.method.call(B); //我是二哥 A.method2.call(B, 18, '软件开发');//我是二哥, 今年18岁, 做软件开发的 console.log('------------- 分隔符 --------------'); </script> <script> var C ={ 'name': '大哥', method: function (){ console.log('我是'+this.name); }, method2: function (age, job){ console.log('我是' + this.name+', 今年' + age +'岁, 做'+ job +'的'); } } var D ={ 'name': '二哥', method: function (){ console.log('我是'+this.name); } } C.method();//this 指向C //我是大哥 D.method();//this 指向D //我是二哥 C.method.apply(D); //我是二哥 C.method2.apply(D, [18, '软件开发']);//我是二哥, 今年18岁, 做软件开发的 console.log('------------- 分隔符 --------------'); </script></pre>
对象
-
有属性和方法组成
-
属性: 对象有什么
-
方法: 对象会什么
对象定义
Json创建 (推荐)
var 变量 = { 属性名: 属性值, 属性名: 属性值, ... 方法名: function(){}. 方法名: function(){}, ... }
-
注:
-
在Json中, 属性名: 属性值 也被称之为: 键:值, 俗称"键值对"
-
对象构造器
对象变量 = new Object();对象变量.属性名 = 属性值;
对象变量.属性名 = 属性值;
...
对象变量.方法名 = function(){}
对象变量.方法名 = function(){}
...
自定义构造器
function 自定义对象名(){ this.属性名 = 属性值; this.属性名 = 属性值; ... this.方法名 = function(){} this.方法名 = function(){} ... }对象变量 = new 自定义对象名();
匿名构造器
对象变量 = new Function(){ this.属性名 = 属性值; this.属性名 = 属性值; ... this.方法名 = function(){} this.方法名 = function(){} ... }
<script> //对象构造器 var Dog = new Object(); Dog.name = '旺财'; Dog.run = function(){ console.log('10s跑1公里'); } console.log(Dog);//{name: "旺财", run: ƒ} //对象名可以小写//加原型链 Object.prototype.skill9 = function(){ return '修电脑'; } console.log(Dog.skill9()); //自定义构造器 function Cat(){ this.name = '加菲猫'; this.eat = function(){ return '吃鱼'; } } var x = new Cat(); console.log(x.name);//加菲猫 console.log(x.eat());//吃鱼 //加原型链 Cat.prototype.skill9 = function(){ return '修电脑'; } console.log(x.skill9()); //匿名构造器 var Person = new function(){ this.name = '小王'; this.age = 18; this.skill = function(){ console.log('吹牛逼'); } } console.log( Person.name );//小王 console.log( Person.age );//18 Person.skill();//吹牛逼 </script></pre>
对象使用
使用属性
-
对象.属性名
-
对象[属性名]
使用方法
-
对象.方法名()
-
对象.方法名(参数)
-
注
-
使用任意属性or方法, 必须先有一个对象才行
-
奇葩属性使用 [] 读取
-
<script> //属性 var obj = { 'name': '狗子', '职业': '看门', 'x2': 'x2',2: '纯数字2', '2B': '以数字开头的字符串', '☆': '五角星', '.*': '标点符号', '$2': '$符开头', '_2': '_符开头', 'function': 'function关键字' } console.log(obj.name); console.log(obj.职业); console.log(obj.x2); console.log(obj.$2); console.log(obj._2); console.log(obj.function); // console.log(obj.2); console.log(obj[2]); // console.log(obj.2B); console.log(obj['2B']); // console.log(obj.☆); console.log(obj['☆']); console.log(obj['.*']) ; console.log('------------- 分隔符 --------------'); //方法 var obj2 = { run: function(){ console.log('运行程序'); }, run2: function(){ console.log('再次运行程序'); } } obj2.run(); obj2.run2(); </script></pre>
原型 prototype
-
原型 prototype
-
能在原型对象上进行添加属性or方法
-
<script> function Dog(){ this.type = '泰迪'; this.skill = function(){ console.log('xxxxxxx'); } }var d1 = new Dog(); var d2 = new Dog(); //给d1添加新方法 d1.skill2 = function(){ console.log('PHP'); } //给d2添加新方法 d2.skill3 = function(){ console.log('区块链'); } //d1 的技能 d1.skill(); d1.skill2(); // d1.skill3();//没有 //d2 的技能 d2.skill(); d2.skill3(); // d2.skill2();//没有 //需求: 两只都有一个共同的技能 //给Dog原对象添加一个新方法, 从而影响所有从Dog实例出来的对象 Dog.prototype.skill9 = function(){ console.log('修电脑'); } d1.skill9(); d1.skill9(); </script></pre>
数组
创建数组
-
Json 方式 (推荐)
-
构造器
操作数组
读取
-
通过 已存在的索引 进行读取
-
对象[索引];
修改
-
对象[索引] = 值;
添加
-
对象[索引] = 值;
-
对象.push(值);
删除
-
delete 对象[索引];
-
对象.splice(索引,长度)
-
返回删除的元素数组
-
多维数组
-
将数组的值 指定为数组(数组嵌套数组)
-
数组的值: 任意类型
-
数组的值: 数组 (多维数组)
遍历数组
var arr = []; for(var i = 0; i < arr.length; i++){ arr[i]; }
字符串数组
var str = 'asfdghfjghjkjlkl'; for(var i = 0; i < str.length; i++){ str[i]; }
<script> //Json var x = []; console.log(x);//[]var x = ['a','b','c']; console.log(x);//["a", "b", "c"] //构造器 var x = new Array(); console.log(x);//[] var x = new Array('a','b','c'); console.log(x);// ["a", "b", "c"] </script> <script> var x =['a', 'b', 'c', 'd']; //读取 for (var i = 0; i < x.length; i++) { console.log(x[i]);//a b c d } console.log(x[x.length]);//undefined //修改 x[1] = 'x'; console.log(x);//["a", "x", "c", "d"] // 添加 x[4] = 'm'; console.log(x);//["a", "x", "c", "d", "m"] x.push('n'); console.log(x);//["a", "x", "c", "d", "m", "n"] // 删除 delete x[1]; console.log(x);//["a", empty, "c", "d", "m", "n"] //占位 x.splice(2,1); console.log(x);//["a", empty, "d", "m", "n"] //不占位 </script> <script> //多维数组 var list = [ ['a','aa','aaa'], ['b','bb','bbb'], ['c','cc','ccc'], ]; console.log(list);//[Array(3), Array(3), Array(3)] for (var i = 0; i < list.length; i++) { console.log(list[i]); //["a", "aa", "aaa"] //["b", "bb", "bbb"] //["c", "cc", "ccc"] for (var j = 0; j < list[i].length; j++) { console.log(list[i][j]); //a aa aaa //b bb bbb //c cc ccc } }
</script>
<script>
var str = 'sdasadasda';
for (var i = 0; i < str.length; i++) {
console.log(str[i]);
//s d a s a d a s d a
}
</script>
计时器
单次计时
-
setTimeout(功能, 时间)
-
意思: 多少时间之后,执行一次功能, 例如: 延迟
多次计时
-
setInterval(功能, 时间)
-
意思: 每隔多少时间, 就执行一次功能, 例如: 定时
-
时间单位: 毫秒
计时器ID
-
每个计时器都会返回一个 计时器id
清除计时器
-
通过 计时器id 来清除指定的计时器
-
clearTimeout(计时器id) 清除单次计时器
-
clearInterval(计时器id) 清除多次计时器
<script> //单次计时 // setTimeout(function(){ // console.log('3s 到了'); // },3000);// function demo(){ // console.log('3s 到了'); // } // setTimeout(demo,3000); // setTimeout(demo(),3000);//不能加() 会立马执行 //多次计时 // var seconds = 0; // setInterval(function(){ // seconds++; // console.log(seconds);//每隔1s输出 // },1000); </script> <script> //计时器ID // var seconds = 0; // var x = setInterval(function(){ // seconds++; // console.log(seconds,x);//每隔1s输出 // //x为对象id 不分setTimeout和setInterval // },1000); // function demo(){ // console.log('3s 到了'); // } // var x1 = setTimeout(demo,3000); // var x2 = setTimeout(demo,3000); // var x3 = setInterval(demo,3000); // console.log(x1,x2,x3); </script> <script> //清除计时器 // var s = 0; // var x = setInterval(function(){ // s++; // if(s == 5){ // clearInterval(x); // // 下一次计时被取消, 但是当前功能还是正常执行, 并不会立马结束 // return; // 具有立马结束当前函数的效果, 并不能终止 多次计时 // } // console.log(s); // },1000); //利用setTimeout 实现 setInterval // var s = 0; // function demo(){ // s++; // console.log(s,x);//每一个id都不一样 // x = setTimeout(demo, 1000); // } // var x = setTimeout(demo, 1000); </script> <div id="box"></div> <button id="btn">暂停</button> <button id="ctn">继续</button> <script> //显示时间 倒计时 有bug 点继续 疯狂加 // //拿到box // var box = document.getElementById('box'); // var s = 10; // box.innerHTML = s; // var timer = setInterval(function(){ // s--; // box.innerHTML = s; // },1000); // // 暂停 // var btn = document.getElementById('btn'); // btn.onclick = function(){ // clearInterval(timer); // } // var ctn = document.getElementById('ctn'); // ctn.onclick = function(){ // timer = setInterval(function(){ // s--; // box.innerHTML = s; // }, 1000); // } </script> <script> //显示时间 倒计时 解决bug // //拿到box var box = document.getElementById('box'); var s = 10; //表示继续能不能点 var flag = false; box.innerHTML = s; var timer = setInterval(function(){ s--; box.innerHTML = s; },1000); // 暂停 var btn = document.getElementById('btn'); btn.onclick = function(){ if(flag == false){ clearInterval(timer); flag = true; } } //继续 var ctn = document.getElementById('ctn'); ctn.onclick = function(){ if(flag == true){ timer = setInterval(function(){ s--; box.innerHTML = s; }, 1000); flag = false; } } </script> <div id="box2"></div> <script> // 显示当前时间: // 格式: xxxx/xx/xx xx:xx:xx function showTime(){ var time = new Date(); var y = time.getFullYear(); var m = time.getMonth() + 1; var d = time.getDate(); var h = time.getHours(); var i = time.getMinutes(); var s = time.getSeconds(); var day = time.getDay(); // 0~6 m = m < 10 ? '0'+m : m; d = d < 10 ? '0'+d : d; h = h < 10 ? '0'+h : h; i = i < 10 ? '0'+i : i; s = s < 10 ? '0'+s : s; var week; switch(day){ case 0: week = '星期天'; break; case 1: week = '星期一'; break; case 2: week = '星期二'; break; case 3: week = '星期三'; break; case 4: week = '星期四'; break; case 5: week = '星期五'; break; case 6: week = '星期六'; break; } document.getElementById('box2').innerHTML = `${y}/${m}/${d} ${h}:${i}:${s} ${week}`; } setInterval(showTime, 1000); </script></pre>
事件
事件绑定
-
事件属性
-
<开始标签 事件属性名='js代码'>
-
-
对象属性
-
对象.事件属性名 = 功能
-
-
事件监听
-
老IE: 对象.attachEvent('on事件', 函数名)
-
非IE: 对象.addEventListener('事件',函数名)
-
解除绑定
-
对象.事件 = null
-
对象.事件 = function(){}
-
老IE: 对象.detachEvent('on事件',函数名)
-
非IE: 对象.removeEventListener('事件',函数名)
<!-- 事件属性 --> <button onclick=" alert('点我一下'); ">点我一下</button><!-- 对象属性 --> <button id="btn">再点我一下</button> <script> var btn = document.getElementById('btn'); btn.onclick = function(){ alert('再点我, 就揍你') } </script> <!-- 事件监听 --> <button id="btn2">点最后一下</button> <script> var btn2 = document.getElementById('btn2'); btn2.addEventListener('click', demo); function demo(){ alert('监听到了'); } </script> <br> <button id="btn3">解除绑定</button> <script> var btn3 = document.getElementById('btn3'); btn3.onclick = function(){ btn.onclick = null; // 解除方式1 // btn.onclick = function(){} // 解除方式2 }; </script> <button id="btn4">解除监听</button> <script> var btn4 = document.getElementById('btn4'); btn4.onclick = function(){ btn2.removeEventListener('click', demo); }; </script></pre>
鼠标事件
-
onclick 单击事件
-
ondblclick 双击事件
-
oncontextmenu 右击事件
-
onmouseover 划入
-
onmouseout 划出
-
onmousedown 按下
-
onmouseup 松开
-
onmousemove 移动
event 事件对象
-
位置: 事件函数的第一个参数
-
取名: 一般为event, 可改为其他名字
-
兼容写法: event || window.event
-
event常用属性:
-
event.offsetX 鼠标相对于当前对象的横坐标
-
event.offsetY 鼠标相对于当前对象的纵坐标
-
event.clientX 鼠标相对于当前可视窗口的横坐标
-
event.clientY 鼠标相对于当前可视窗口的纵坐标
-
event.x 鼠标相对于当前可视窗口的横坐标 (IE)
-
event.y 鼠标相对于当前可视窗口的纵坐标 (IE)
-
event.screenX 鼠标相对于电脑屏幕的横坐标
-
event.screenY 鼠标相对于电脑屏幕的纵坐标
-
<style> #box{ width: 500px; height: 2000px; background: pink; margin: 100px auto; cursor: default; } #show{ width: 300px; height: 200px; border: 5px solid #ccc; position: fixed; left: 0; top: 40%; } </style><div id="box"></div>
<div id="show"></div><script>
var box = document.getElementById('box');// box.onclick = function(){ // this.innerHTML = '单击'; // } box.ondblclick = function(){ this.innerHTML = '双击'; } box.onmousedown = function(){ this.innerHTML = '按下'; } box.onmouseup = function(){ this.innerHTML = '松开'; } box.onmouseover = function(){ this.innerHTML = '划入'; } box.onmouseout = function(){ this.innerHTML = '划出'; } var show = document.getElementById('show'); box.onmousemove = function(event){ var event = event || window.event; show.innerHTML = 'offsetX:' + event.offsetX + '<br>' + 'offsetY:' + event.offsetY + '<br>' + 'clientX:' + event.clientX + '<br>' + 'clientY:' + event.clientY + '<br>' + 'screenX:' + event.screenX + '<br>' + 'screenY:' + event.screenY + '<br>' + 'x:' + event.x + '<br>' + 'y:' + event.y + '<br>'; }
</script>
键盘事件
键盘事件
-
onkeydown (支持功能键, 输出键) 蓄力
-
onkeyup (支持功能键, 输出键)
-
onkeypress (支持输出键)
-
注:
-
功能键: F1, F2, Ctrl, Alt, Shift, ESC 等按键
-
event 事件对象
-
event.keyCode 按键的ASCII码 (兼容IE) 字母是大写
-
event.which 按键的ASCII码 (不兼容老IE) 字母是大写
-
event.charCode 按键的ASCII码 (只有onkeypress可以触发) 字母小写
-
event.key 键盘上的真实符号 字母为小写
<script> // document.onkeydown = function(){ // var r = parseInt(Math.random()*256); // var g = parseInt(Math.random()*256); // var b = parseInt(Math.random()*256);// document.body.style.background= `rgb(${r},${g},${b})`; // } // document.onkeyup = function(){ // var r = parseInt(Math.random()*256); // var g = parseInt(Math.random()*256); // var b = parseInt(Math.random()*256); // document.body.style.background= `rgb(${r},${g},${b})`; // } // // document.onkeypress = function(){ // var r = parseInt(Math.random()*256); // var g = parseInt(Math.random()*256); // var b = parseInt(Math.random()*256); // document.body.style.background= `rgb(${r},${g},${b})`; // } </script> <script> // document.onkeydown = function(event){ // var event = event || window.event; // console.log( event.keyCode );//ASCII // console.log( event.which );//ASCII // console.log( event.charCode );//0 只支持onkeypress // console.log( event.key ); // console.log( event.which || event.keyCode );//兼容写法 // } // document.onkeypress = function(event){ // var event = event || window.event; // console.log( event.charCode ); // } </script> <!-- 通过按 上下方向键 调节音量的大小 --> <audio src="../resource/神话.m4a" controls id="music"></audio> <script> document.onkeydown = function(event){ var music = document.getElementById('music'); var event = event || window.event; if(event.keyCode == 38){ sound = music.volume; sound += 0.1; music.volume = sound >= 1.0 ? 1.0 : sound; console.log('加'); }else if( event.keyCode == 40 ){ sound = music.volume; sound -= 0.1; music.volume = sound <= 0.0 ? 0.0 : sound; console.log('减'); } console.log(music.paused); if(event.keyCode == 32){ // 获取 暂停状态 // true 暂停状态 => play() // false 播放状态 => pause() console.log(music.paused + '1'); if(music.pasued){ // console.log('开'); music.play(); }else{ music.pause(); } } music.playbackRate = 1.0;//速度 } </script></pre>
框架事件
-
onload 当前页面或图片加载完成时触发
-
onerror 当加载文档或图片失败时触发
-
onresize 当也页面大小发生改变时触发
-
onscroll 当页面发生滚动时触发
-
获取滚动条距离顶部的距离
-
IE: document.body.scrollTop
-
safari: window.pageYOffest
-
其余: document.documentElement.scrollTop
-
<script> window.onload = function(){ var box = document.getElementById('box'); console.log(box);//没加onload事件 显示null } </script> <!-- <div id="box"></div><img src="../resource/phone.png" width="200"> <img src="../resource/phone.p" width="200"> <img src="../resource/phone.p" width="200"> <img src="../resource/phone.png" width="200"> <img src="../resource/phone.png" width="200"> <img src="../resource/phone.p" width="200"> --> <script> var imgList = document.getElementsByTagName('img'); console.log(imgList); for(var i = 0; i < imgList.length; i++){ imgList[i].onerror = function(){ this.src = '../resource/5.jpg'; } } </script> <div id="nav"></div> <div id="main"></div> <script> window.onscroll = function(){ var nav = document.getElementById('nav'); //兼容写法 var st = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop; if( st >= 200 ){ nav.style.margin = '0px'; nav.style.position = 'fixed'; nav.style.left = '0px'; nav.style.top = '0px'; }else{ nav.style.marginTop = '200px'; nav.style.position = 'static'; } } </script>
表单事件
-
onfocus 获取焦点时
-
onblur 失去焦点时
-
onchange 内容发生改变时
-
oninput 输入时
-
onselect 选中(框中)内容时
-
onsubmit 提交时
根据 name 获取表单对象
-
document.getElementsByName('name名');
-
document.name名
-
注:
-
若 name 唯一:
-
document.getElementsByName() 得到 节点列表
-
document.name名 得到 一个表单对象
-
-
若 name 不唯一:
-
doucment.getElementsByName() 得到 节点列表
-
document.name名 得到 html集合
-
-
<style> input{ outline: none; border: 1px solid #ccc; padding-left: 5px; }input[type='submit']{ width: 216px; height: 30px; color: #fff; border-radius: 10px; background: #3DB3F9; border: none; } #show{ width: 500px; height: 50px; border: none; border-bottom: 5px solid black; font-size: 45px; } </style>
<!-- 表单 -->
<form action="" name="form">
<p>账号: <input type="text" name="userName"></p>
<p>密码: <input type="password" name="pwd"></p>
<p><input type="submit"></p>
</form>
<!-- 展示台 -->
<div id="show"></div><script>
//根据 name 来获取对象
console.log(document.getElementsByName('form')); //节点集合 长度1
console.log(document.form); //表单对象
console.log(document.form.userName); //name为userName的表单对象var userName = document.form.userName; console.log(userName);
//获取焦点触发事件
userName.onfocus = function(){
this.style.borderColor = 'red';
}//失去焦点时触发
userName.onblur = function(){
this.style.borderColor = "#ccc"
}//在展示台同步显示输入的内容
// userName.oninput = function(){
// var show = document.getElementById('show');// show.innerHTML = this.value; // }
//显示选中的内容
userName.onselect = function(){
var show = document.getElementById('show');show.innerHTML = window.getSelection().toString();//只用于现场输入的 cookie里的不能用 console.log(window.getSelection().toString()); }
//禁止/允许提交
var form = document.form;form.onsubmit = function(){ // return false;//禁止提交 return true;//允许提交 } </script> <br> <form action="" name="address"> <select name="province"> <option value="">江苏</option> <option value="">浙江</option> <option value="">安徽</option> <option value="">山西</option> <option value="">江西</option> <option value="">湖南</option> <option value="">新疆</option> <option value="">湖北</option> <option value="">上海</option> <option value="">黑龙江</option> </select> </form>
<!-- 选择项改变时触发事件 -->
<script>
// var pro = document.province;//undefined
var pro = document.address.province;
console.log(pro);//集合pro.onchange = function(){
//添加一个option
var opt = document.createElement('option');
opt.innerHTML = '云南';// this.add(opt); //默认为null // this.add(opt,null); //null 表示添加到最后 this.add(opt,pro[2]); //pro[2] 表示在pro[2] 前面添加 } </script></pre>
正则表达式
作用
-
创建一个句法规则, 用以文本搜索 or 文本替换
格式
-
/正则表达式/修饰符
-
注:
-
修饰符不是必需品, 可写可不写
-
正则严格区分大小写
-
正则匹配
-
对象.search(正则) 搜索指定字符的索引
-
搜索成功: 对应的索引
-
搜索失败: -1
-
-
对象.replace(正则,'替换的字符')
-
对象.match(正则) 匹配并返回匹配结果.
-
匹配成功: 返回数组
-
匹配失败: null
-
原子
-
原子是正则的最小单位
分类
-
可见原子: 输出之后肉眼能看见的字符. 例如: 数字, 字母, 标点, 汉字等
-
不可见原子: 输出之后肉眼看不见的字符. 例如: 空格, 回车等
修饰符
-
i 不区分大小写
-
g 全部匹配 match支持,search不支持
-
m 多行匹配, 一般需要有 \n 的内容
中括号
-
意思: 多选一
-
[abc] 匹配abc中的任意一个原子
-
[^abc] 匹配除abc之外的任意一个原子
-
[x-y] 匹配x~y之间的任意一个原子
-
[0-9] 匹配0~9之间的任意一个数字
-
[a-z] 匹配a-z之间的任意一个字母
-
[A-Z] 匹配A-Z之间的任意一个字母
-
-
[/u4e00-/u9fa5] 匹配所有汉字
-
注:
-
-
"-" 减号只能前后都有原子时, 才是范围匹配, 否则都只是普通 减号原子
-
-
竖线
-
意思: 多选一 (一: 整体)
-
格式:
-
正则1|正则2|正则3 ...
-
集合
-
意思: 多选一
\d 相当于[0-9] \D 相当于[^0-9] \s 相当于[ \n\t\r] 匹配任意一个不可见原子 \S 相当于[^ \n\t\r] 匹配任意一个可见原子 \w 相当于[0-9a-zA-Z_] \W 相当于[^0-9a-zA-Z_] . 除了 \n 不能匹配, 其余都能匹配
量词
-
连续匹配多个原子
a{n} 匹配前面一个原子a连续出现n次 a{n,} 匹配前面一个原子a至少出现n次 a{n,m} 匹配前面一个原子a至少出现n次, 至多出现m次a* 匹配原子a至少出现0次
a+ 匹配原子a至少出现1次
a? 匹配原子a至少出现0次, 至多出现1次.* 贪婪模式: 当匹配结果存在分歧时, 取其长
.*? 懒惰模式: 当匹配结果存在分歧时, 取其短
小括号
-
功能1: 将小括号的原子 当成一个整体, 可理解为一个大原子
-
功能2: 将小括号内匹配的结果存入 结果集(分组) (该行为称之为: 捕获)
-
拒绝存入 结果集
-
格式: (?:正则)
-
后向引用
-
后面引用前面的结果
-
格式: \索引
-
例如: 存入结果集的 \1: \1 与 第一个() 匹配的结果 一模一样 \1: \2 与 第二个() 匹配的结果 一模一样 ...
-
注:
-
在正则内部, 通过 \索引 来引用
-
在正则外部, 通过 $索引 来引用
-
预查模式
-
(?=正则) 正向预查 判断后面的符合正则
-
(?!正则) 反向预查 判断后面的不符合正则
边界
-
^a : 以 a 开头
-
a$ : 以 a 结尾
-
注:
-
^ 和 $ 一起使用, 能限制总长度 /^正则$/
-
正则对象
-
new RegExp(正则表达式, 修饰符)
-
注
-
使用RegExp 主要目的为了识别变量, 如果不需要识别变量, 推荐使用 /正则/ 写法
-
/正则/ 无法识别变量
-
new RegExp() 可以识别变量
-
<script> //基本用法 var str = 'abc789'; // var reg = new RegExp(/[a-z]/); // /正则/ 写法 // console.log(str.match(reg)); //["a", index: 0, input: "abc789", groups: undefined] var reg = new RegExp('[a-z]'); console.log(str.match(reg));//["a", index: 0, input: "abc789", groups: undefined]//转义符
var str = "abc9870";
var reg = new RegExp('[0-9]');
console.log(str.match(reg));//["9", index: 3, input: "abc9870", groups: undefined]var reg = new RegExp('\d');
console.log(str.match(reg)); //null //字符串 中的\d的\ 是转义字符
var reg = new RegExp('\d'); //正确写法
console.log(str.match(reg)); //["9", index: 3, input: "abc9870", groups: undefined]//识别变量
var str = 'abc987';
var x = 9;
var reg = new RegExp('[a-z]x'); //x
console.log(str.match(reg)); //nullvar reg = new RegExp(/[a-z]x/); //x
console.log(str.match(reg)); //nullvar reg = new RegExp('[a-z]'+x); //√
console.log(str.match(reg)); //["c9", index: 2, input: "abc987", groups: undefined]//修饰符
var str = 'abc987';
var reg = new RegExp('[A-Z]','gi');
console.log(str.match(reg)); // ["a", "b", "c"]
</script>
事件冒泡
事件冒泡
-
由内而外的传递事件 (后辈将事件传递给祖辈)
-
注
-
仅仅是传递事件, 而不是事件对应的函数
-
阻止冒泡
-
不会将事件传递给祖辈
-
非IE: event.stopPropagation()
-
IE: event.cancelBubble = true
事件监听
-
冒泡模式 false : 由内而外传递事件 (默认)
-
捕获模式 true : 由外而内传递事件
<style> #big{ width: 500px; height: 500px; background: #ccc; position: relative; }#small{ width: 200px; height: 222px; background: green; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); } #big1{ width: 500px; height: 500px; background: orange; position: relative; } #small1{ width: 200px; height: 222px; background: red; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); } </style> <div id="big"> <div id="small"></div> </div> <script> var big = document.getElementById('big'); var small = document.getElementById('small'); // console.log(big,small); big.onclick = function(){ alert('big'); } small.onclick = function(event){ alert('small'); //阻止冒泡 var event = event || window.event; event.stopPropagation(); event.cancelBubble = true; } </script> <div id="big1"> <div id="small1"></div> </div> <script> var big1 = document.getElementById('big1'); var small1 = document.getElementById('small1'); //冒泡模式 由内而外 先弹子再弹父 big1.addEventListener('click', function(){ alert('big1'); }, false); small1.addEventListener('click', function(){ alert('small1'); }, false); //捕获模式 由外而内 先弹父再弹子 big1.addEventListener('click', function(){ alert('big1'); }, true); small1.addEventListener('click', function(){ alert('small1'); }, true); </script></pre>
默认行为
-
指某些元素的默认效果
-
例如: a连接的跳转页面
-
submit 默认提交
-
-
取消默认行为
-
非IE event.preventDefault()
-
IE event.returnValue = false;
-
<a href="http://www.baidu.com" id="baidu">baidu</a> <script> var baidu = document.getElementById('baidu');baidu.onclick = function(event){ var event = event || window.event; event.preventDefault(); } </script> <form action="" name="form"> <input type="text" name="userName"> <input type="submit"> </form> <script> var form = document.form; form.onsubmit = function( event ){ // return false; var event = event || window.event; event.preventDefault(); } </script></pre>
BOM
-
浏览器对象模型
window
-
几乎所有浏览器都支持window
-
window: 浏览器窗口, 所有全局可以用的变量, 函数都属于window对象的属性or方法
浏览器尺寸
标准写法
-
window.innerWidth 浏览器当前可视窗口(包含滚动条, 不包含控制台,地址栏,标签页,任务栏)
-
window.innerHeight 浏览器当前可视窗口的高度(同上)
IE写法
-
document.documentElement.clientWidth
-
document.documentElement.clientHeight
兼容写法
-
document.body.clientWidth
-
document.body.clientHeight
-
注:
-
以上写法, 只能获取一页的宽高, 而非整个body的宽高
-
兼容写法获取整个body宽度, 且随着渲染内核变化而变化, 容易数值误差
-
通用写法
-
window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
窗口操作
-
window.open()
-
window.close()
弹窗
-
window.alert(); 提示框, 返回值: undefined
-
window.prompt(); 输入框, 返回值: 输入的值
-
window.confirm(); 确认框, 返回值: Boolean值
滚动条
-
获取当前滚动条距离顶部的距离
-
非IE document.documentElement.scrollTop
-
IE document.body.scrollTop
-
-
操作滚动条
-
window.scrollBy() 相对于当前位置进行滚动
-
window.scroolTo() 直接滚动到指定位置
-
<script> var x = 10; console.log(x); console.log(window.x);function demo(){ console.log("xxxx"); } demo(); window.demo(); // alert('xxx'); // window.alert('zzz'); </script> <script> console.log(window.innerWidth); console.log(window.innerHeight); console.log(document.body.clientWidth); console.log(document.body.clientHeight); </script> <button onclick="window.open('http://www.baidu.com')">在新窗口打开百度</button> <button onclick="window.open('http://www.baidu.com', '_blank')">在新窗口打开百度</button> <br> <button onclick="window.open('http://www.baidu.com', '_self')">在本窗口打开百度</button> <button onclick="window.open('http://www.baidu.com', '_blank', 'width=500, height=500')">指定窗口大小,打开百度</button> <br> <button id="open">新打开窗口</button> <button id="close">关闭本窗口</button> <script> var open1 = document.getElementById('open'); var x; open1.onclick = function(){ x = window.open('http://www.baidu.com'); } var close1 = document.getElementById('close'); close1.onclick = function(){ x.close(); } </script> <div style="height:3000px"></div> <button onclick="window.scrollBy(0, -100)">向上滚 100px</button> <button onclick="window.scrollTo(0, 100)">滚动到 100px</button> <button onclick="back()">返回顶部</button> <script> window.onscroll = function(){ console.log( document.documentElement.scrollTop); } function back(){ var top = document.documentElement.scrollTop || document.body.scrollTop; var speed = top; speed /= 70; window.scrollBy(0, speed * -1); if( top <= 0 ){ clearTimeout(timer); return; } timer = setTimeout(back, 1); } </script> <button onclick="window.print()">打印该页面</button></pre>
案例
敏感词处理
<style> #show{ width: 500px; height: 100px; background: #ccc; } </style><form action="" name="form"> 评论: <input type="text" name="context"> <input type="submit"> </form> <div id="show"></div> <script> var form = document.form; var context = form.context; var show = document.getElementById('show'); // console.log(form); // console.log(context); // console.log(show); form.onsubmit = function(){ // 准备敏感词 var keywords = ['沙雕', '草', '操', '干', '妈', '死', '尼玛']; //接收评论 var value = context.value; //循环敏感字 for (var i = keywords.length - 1; i >= 0; i--) { console.log(value); //敏感词正则 var reg = new RegExp(keywords[i],'ig'); // 统计敏感字长度len var len = keywords[i].length; //重复次数 var str = '*'; str = str.repeat(len); //替换* value = value.replace(reg,str); } show.innerHTML = value; return false; } </script></pre>
表单验证
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" href="../iconfont/iconfont.css"> <style> span{ display: none; } </style> </head> <body> <form action="" name="register"> <p> 手机号: <input type="text" name="tel"> <span class="iconfont" id="telNotice"></span> </p> <p> 密码: <input type="password" name="pwd"> <span class="iconfont" id="pwdNotice"></span> </p> <p> 确认密码: <input type="password" name="repwd"> <span class="iconfont" id="repwdNotice"></span> </p> <p><input type="submit" value="注册"></p> </form><script> var form = document.register; var tel = form.tel; var pwd = form.pwd; var repwd = form.repwd; // console.log(form); // console.log(tel); // console.log(pwd); // console.log(repwd); //正确 function right(notice){ notice.innerHTML = ''; notice.style.display = 'inline'; notice.style.color = 'green'; } //错误 function wrong(notice){ notice.innerHTML = ''; notice.style.display = 'inline'; notice.style.color = 'red'; } tel.onblur = checkTel; function checkTel(){ var notice = document.getElementById('telNotice'); value = tel.value; //手机正则 //简易版 var reg = /^1\d{10}$/; //向后兼容 var reg = /^1[3-9]\d{9}$/; //完整版 var reg = /^1(3\d|4[5-9]|5[0-35-9]|66|7[03-8]|8\d|9[98])\d{8}$/; if(value.match(reg)){ //成功 right(notice); return true; }else{ //失败 wrong(notice); return false; } } pwd.onblur = checkPwd; function checkPwd(){ var value = pwd.value; var notice = document.getElementById('pwdNotice'); var a = value.match(/[0-9]/); var b = value.match(/[a-z]/); var c = value.match(/^[A-Z].{5,11}$/); console.log(value); console.log(Boolean(a && b && c)); if( a && b && c ){ right(notice); return true; }else{ wrong(notice); return false; } } repwd.onblur = checkRepwd; function checkRepwd(){ var pwdValue = pwd.value; var repwdValue = repwd.value; var notice = document.getElementById('repwdNotice'); if( pwdValue == repwdValue ){ right(notice); return true; }else{ wrong(notice); return false; } } form.onsubmit = function(){ console.log(checkTel() && checkPwd() && checkRepwd()); return checkTel() && checkPwd() && checkRepwd(); } </script>
</body>
</html>DOM
-
文档对象模型 Document Object Model
-
将 HTML 中的所有元素都当成节点
节点分类
-
文档: document
-
元素: element (标签) body体里的主体内容
-
属性: attribute
-
文本: text (正文内容, 空格, 回车) 排版的空格也算
-
注释: comment
document
-
document 对象是 HTML文档的根节点
document 对象集合
-
document.all 获取document中所有的元素 (不存在的<x></x> 也会读取)
-
document.forms 获取document中所有的form元素
-
document.image 获取document中所有的img元素
-
document.links 获取document中所有的链接元素
document 对象属性
-
document.documentElement 返回当前文档的根节点
-
document.body 返回当前文档的body
-
document.title 返回当前文档的title
-
document.URL 获取当前文档的url地址
-
document.domain 返回当前文档的域名
-
document.cookie 返回当前的cookie
document 对象方法
-
document.getElementById()
-
document.getElementsByClassName()
-
document.getElementsByTagName()
-
document.getElementsByName
-
document.write() -
-
document.createElement() 创建一个标签节点
-
document.createAtribute() 创建一个属性节点
-
document.createTextNode() 创建一个文本节点
-
注:
-
创建任意节点 都不会直接显示在页面中
-
element 元素
-
所有的标签都是element
属性
-
元素节点.childNodes 获取该节点的所有子节点 (包含空格, 回车等)
-
元素节点.firstChild ...第一个子节点
-
元素节点.lastChild ...最后一个子节点
-
元素节点.previousSibling ...前面一个兄弟节点
-
元素节点.nextSibling ...后面的一个兄弟节点
-
元素节点.parentNode ...父级节点 -
-
元素节点.children 获取该节点的所有子标签
-
元素节点.firstElementChild ...第一个子标签
-
元素节点.lastElementChild ...最后一个标签
-
元素节点.nextElementSibling ...后面一个兄弟标签
-
元素节点.previousElementSibling ...前面一个兄弟标签 -
-
元素节点.tagName 获取/设置该节点的标签名
-
元素节点.id ... id名
-
元素节点.classList ... class 集合
-
元素节点.className ... class 字符串 -
-
元素节点.innerHTML 所有子节点的内容(空格, 内容, 标签, 属性等)
-
元素节点.innerText 所有标签内的正文内容
-
元素节点.textContext 该节点内的所有内容 ( 正文 + 空格 ) -
-
元素节点.clientWidth 该节点的宽度 (width+padding, 不包含border和滚动条)
-
元素节点.clientHeight 该节点的高度 (width+padding, 不包含border和滚动条)
-
元素节点.offsetWidth 该节点的宽度 (width+padding+border)
-
元素节点.offsetHeight 该节点的高度 (width+padding+border) -
-
元素节点.scrollWidth 获取该节点的滚动区间宽度 (不包含滚动条)
-
元素节点.scrollHeigth 获取该节点的滚动区间高度 (不包含滚动条)
-
元素节点.scrollLeft 获取该节点滚动条距离最左侧的距离
-
元素节点.scrollTop 获取该节点滚动条距离最顶部的距离
-
-
元素节点.NodeName 获取该节点的名字
-
元素节点.NodeType 获取该节点的类型
-
元素节点.NodeValue 获取该节点的值 -
-
参考地址: https://www.w3school.com.cn/js/js_htmldom_navigation.asp
方法
-
元素节点.hasChildNodes() 是否有子节点
-
元素节点.appendChild() 添加一个子节点
-
元素节点.removeChild() 删除一个子节点
-
元素节点.replaceChild(new, old) 替换一个子节点
-
元素节点.insertBefore(new, old) 插入一个子节点
-
-
元素节点.hasAttribute() 是否有子节点
-
元素节点.hasAttributes() 是否有属性 (不需要指定, 只要有任意一个属性即可)
-
元素节点.getAttribute() 获取属性
-
元素节点.setAttribute(属性名, 属性值) 设置属性
-
元素节点.removeAttribute() 删除属性
-
-
元素节点.closeNode(Boolean值) 克隆节点
-
true: 连同子节点一起拷贝
-
false: 只拷贝当前节点
-
-
元素节点.addElementListener() 添加监听
-
元素节点.removveElementListener() 移除监听
attribute
-
元素节点.attributes
-
元素节点.attributes[].name
-
元素节点.attributes[].value
-
元素节点.attributes.length
-
元素节点.attributes.item()
-
元素节点.attributes.getNameItem()
-
元素节点.attributes.setNameItem()
-
元素节点.attributes.removeNameItem() -
-
属性节点.name
-
属性节点.value
-
...
<style>
.x{
color: red;
}
#box3{
width: 200px;
height: 200px;
padding: 10px;
border: 20px solid black;
overflow: auto;
}
</style>
<div id="box"></div>
<form action="" name="form1"></form>
<form action="" name="form2"></form>
<form action="" name="form3"></form>
<img src="../resource/1.gif" height='200px'>
<img src="../resource/1.jpg" height='200px'>
<a href="http://aaa">baidu</a>
<a href="http://aaa">apple</a>
<x1> xxxx </x1>
<script>
console.log(document.all);
//HTMLAllCollection(16) [html, head, meta, title, style, body, div#box, form, form, form, img, img, a, a, x1, script, box: div#box, form1: form, form2: form, form3: form]
console.log(document.forms);
//HTMLCollection(3) [form, form, form, form1: form, form2: form, form3: form]
console.log(document.images);
//HTMLCollection(2) [img, img]
console.log(document.links);
//HTMLCollection(2) [a, a]
console.log(document.documentElement);
//整个HTML
console.log(document.body);
//body体
document.title = '淘宝一下';
console.log(document.title);
//淘宝一下
console.log(document.URL);
//file:///F:/%E5%AE%9E%E4%B9%A0%E5%9F%B9%E8%AE%AD/2019-12-27/%E9%99%88%E8%80%80%E6%B3%BD/%E7%AC%AC%E4%BA%8C%E9%81%8D/DOM.html
console.log(document.domain);
//域名
console.log(document.cookie);
//cookie
</script>
<button id='btn'>创建一个b标签</button>
<script>
var btn =