JS基础知识

第一章 JS基础

javascript介绍

概述
是运行在客户端(浏览器)的一门解释型脚本语言
特点
1. 无需编译,由JavaScript引擎解释执行
2. 弱类型语言
3. 基于对象和原型

Javascript的组成

 ECMAscript  js标准语法(版本3,4,5,6,7)
 Dom 页面文档对象模型
 Bom 浏览器对象模型

Javascript的基本操作

书写方式
行内/内嵌/外部

注意点:
    1、推荐使用单引号
    2、引入js的script标签中不能在写代码
    3、多个script标签自上而下逐行执行
    4、每行代码需要;分号结束
注释代码压缩
通过工具去掉所有空格、tag、换行,以提高计算机效率

Javascript语法规范

语句规范

可以被JS解释器执行的代码叫语句

1. 由表达式、关键字、运算符组成;
2. 大小写敏感(严格区分大小写);
3. 使用分号结束
注释
 //    单行注释
 /**/  多行注释

Javascript常见输出方式

弹出警告框
 示例: alert("hello world");
页面输出

:除了输出内容外,还可以解析HTML源码

 示例:document.write("hello world");
 示例:document.write("<h1>hello world</h1>");
控制台输出
console.log("用于调试");

Javascript 变量

常量: Js中的并没有常量这个概念,但常量通俗来说指一个固定的数据值

变量定义和语法

变量是值可以被修改的数据容器

变量由 关键字Var标识符 组成 (标识符又叫变量名)

示例: Var num=100;
变量特点
1. 变量本质上是一个数据容器
2. 变量必须声明才能使用,否则会污染全局
3. 初始化:声明变量时,直接给变量赋值
4. 若没有赋值,变量默认值为underfined
5. 若没有赋值,将值设为null可提高程序效率
6. 变量是弱引用类型:赋值成什么数据类型就是什么数据类型(不建议改变变量的数据类型)
变量声明

使用关键字 var 声明变量

:var name="我的名字"

注: 使用var声明的变量的作用域是当前作用域


标识符命名规范

  • 不能使用关键字保留字
  • 可以包含字母数字下划线美元符号 $

  • 不能以数字开头

  • 常用于表示函数、变量等名称

  • 见名思意

  • 可以采用 小驼峰命名法,大驼峰命名法

小驼峰命名: userName (适用于函数和变量名)

大驼峰命名: UserName (适用于构造函数和类名)

关键字和保留字

关键字:

break 退出循环case 匹配值catch 处理错误continue 跳出当前循环default switch语句中的关键字
delete 删除dowhileelsefinally 最终
forfunctionifininstanceof 运算符
newreturnthisthrowtry
typeofvarvoidwhilewith

保留字:

abstract 提取Boolean 布尔值byte 字节char 字符class 类名
const 常量debugger 调试bugdouble 双倍enum 映射export 输出
extends 扩展final 最终float 浮点goto 跳转implements 工具
import 导入int 整形interface 接口界面long 长native 本机
package 插件组件private 私有protected 保护public 公用short 短路
static 静态super 超级synchronized 同步throws 丢弃transient 暂时
volatile 挥发let 声明yield

Javascript数据类型

基本数据类型 (6种)

基本数据类型又被称为 值类型 原始类型

Number类型

表示: 数字

特点: 可以进行算术运算

注: 整数 **小数 ** NaN **Infinity **都是Number类型

番外1: Java中 int整数 float浮点类型 double双精度浮点类型

​ **番外2: ** 通过函数isNaN可以判断是否为非数字,得到值为布尔值

String类型

表示: 字符串

特点: 被包裹在引号中的值 就是字符串类型

​ **番外: ** 在Java中 单引号表示字符 双引号表示字符串

Boolean类型

​ **表示:**布尔值

值: true(真) / false(假)

注: 在实际运算中会自动转成 01

Undefined类型

表示: 变量声明后还未赋值状态

		**值:**  undefined

注: 不推荐主动定义 无意义

Null类型

表示: 声明后的变量,将来可能会赋值,但现在还未进行赋值,为空的状态

值: null

注: 为什么null == undefined 为true?

	 	分析: null转数字0  undefined转数字NaN 为什么null == undefined 为真
	 	解答:  因为ECMAscript语法规定:在比较相等性之前,不能将null和undefined转换成其他任何值,因为语法规定他们相等的				   null和undefined都代表着无效的值。
Symbol

注: ES6 引入了一种新的原始数据类型,表示独一无二的值。

引用数据类型(3种)

引用数据类型又被称为复合数据类型

Object类型

表示: ** 可以存储多组键值对数据函数**的一个变量(对象名)

特点: 一切皆为对象 (所有引用数据类型和null都是对象)

Array类型

表示: 来存储一系列值的变量(数组名)

特点: 可以用变量名下标访问任何一个值

Function类型

表示: 完成特定功能的一段代码封装成的变量**(函数名**)

​ **特点: ** 可以重复调用

Javascript数据类型检测

typeof 关键字

​ **格式:**typeof 值/变量

​ **功能: **可以输出常量/变量的数据类型(一般用于检测基本数据类型)

 例:console.log(typeof 100);// 值为 : "Number"
	**注:**双重typeof输出的都是字符串

第二章 JS基础运算符

算术运算符


+ - ***** / % (模:取余符号) ******(幂运算符)

运算规则:

1. 一个数据为字符串,加法运算时,其他数据会转成字符串,进行拼接,并返回新的字符串

2. 一个数据为字符串,非加法运算时,字符串会转成数值(nan或者数字),在进行运算

​ 字符串由数字字符组成,转成数字

​ 字符串由非数字字符组成,转成NaN

3. 布尔值、Null、Undefined类型,在进行算术运算时,会先转成数字在进行运算

​ true 转为 1

​ false转为 0

​ null 转为 0

​ undefined 转为 NaN

4. NaN和任何数运算都是NaN(除和字符串加法外)

toFixed(n) 方法

​ 可以保留n位小数

一元运算符


一元自增运算符 ++

​ ++ 后置 : 先取a的值作为a++表达式的值,然后在对a进行+1

​ ++ 前置 : 先对a进行+1,然后将a作为++a表达式的值

一元自减运算符 –

​ – 后置 : 先取a的值作为–表达式的值,然后在对a进行+1

​ – 前置 : 先对a进行+1,然后将a作为++a表达式的值

一元加运算符 +

​ 把数据转成数值类型并加上正号

一元减运算符 -

​ 把数据转成数值类型并加上负号

运算规则

​ 如果自增或自减运算符不作为独立语句使用时,出现的前后位置会影响结果

符号前置 优先运算

		  **符号后置 优先使用值**
 console.log(a++ + a++ + ++a - a-- + ++a);   
 //          5   + 6   +   8 - 8   +  8
 //          6     7       8   7      8

关系运算符


> < >= <= == != === !==(等于、不等、恒等、恒不等)

关系运算的值: 返回一个布尔类型的值

​ **功能:**判断真假命题

运算规则:

​ 1:如果都是数值,比较数值大小

​ 2: 如果都是字符串,比较Unicode码值(单字符个直接比较,多字符逐个比较大小)

​ 3: 有一个是数值,两者都转为数值,再进行数值比较

​ 4: 有一个是布尔值,两者都转为数值在进行比较

​ 5: NaN和任何数据(包括NaN)比较都为false

Unicode编码:

​ 是一组数据数据的编码方式

​ 由0-65535数值代表不同的字符

	  **数字** **48** - **57**

字母(小) 97 - 122

字母(大) 65 - 90

逻辑运算符


	**&& 逻辑与**

​ **格式:**布尔表达式1 && 布尔表达式2
​ **规律:**只有两个表达式都为true的时整个表达式才为 true ,否则为false

console.log( 2 == 2 && 1 == 3);//返回值为 false

|| 逻辑或

格式: 布尔表达式1 || 布尔表达式2
**规律:**只有两个表达式都为false的时整个表达式才为 false ,否则为true

console.log( 1 == 2 || 2 == 2);//返回值为 true

短路逻辑:

​ 短路逻辑与:两侧只为普通表达式时,表达式1为false的时候,表达式2就不执行了,直接返回表达

	只要表达式1为true的时,表达式2就不执行了,直接得出结果为true

! 非

		  **格式:**  !表达式1
			**规律:**先将自动数据类型转换成布尔值,然后在取反
			**注:**其他数据类型转布尔值(非零即真,非空即真,特殊即假,对象即真)

赋值运算符


	**基本赋值运算符 =**
			**功能:**将=号右边的值,赋值给变量

复合赋值运算符 x=
x可以为 + - * / %
​ **例:**a += 5 等同于 a=a+5

条件运算符


条件运算符又称三目运算符和三元运算符

基本语法: 表达式1 ? 表示式2 : 表达式3 ;

运算规则:

	表达式1 是一个逻辑表达式(布尔表达式)

​ 当表达式1为真的时候,执行表达式2

​ 当表达式1为假的时候,执行表达式3

快速转换数据类型


一元+号 快速转数字

两个逻辑非!!快速转布尔值

使用 + ‘’ 拼接符 和空字符串快速转为字符串

对象转字符串为 [object object]

任何对象转数字都为NaN

隐式数据类型转换

核心思想: 运算规则中,除了字符串和字符串关系比较外,算术运算和关系比较都转成数值类型在进行运算比较。


  • 字符串连接符 + :只要两边有一个为字符串,则 + 为拼接符 进行字符串拼接

  • 算术运算符:除了字符串拼接符外的所有数据, 都会转成数值进行运算(包括转为NaN)

  • NaN和任何数据(包括NaN)比较都为false,运算则为NaN

  • 相等比较时,会进行隐式转换,都会转成数值比较是否相等(Null==undefined不会转换)

强制数据类型转换

Number() 强制转换为数值

​ 作用:将字符串解析成number ,如果无法解析则返回NaN

​ 代替: + 一元加号

Bolean() 强制转化为布尔值

​ 代替: 双逻辑非 !!

toString(n) 强制转换为字符串

​ 作用:将数据强制转为字符串

​ 作用:讲数据通过n转换为其他进制

​ 注意: null 和 undefiend并不支持此函数

​ 代替: + ‘’ 拼接空字符串

parseInt() 取整函数
作用:将一个字符串解析出整数部分取整,如果没有可解析的部分 则返回NaN
作用:将其他进制转成十进制(数据类型必须是字符串)

parseFloat() 取浮点数 (小数)

​ 作用:将一个字符串解析出浮点部分的数据(小数),如果没有可解析的部分则返回NaN

第三章 Js流程控制语句

程序 = 数据 + 算法

任何复杂的程序算法都可以通过“顺序”,“分支”,循环三种基本的程序逻辑组合实现

3种流程控制语句


​ **顺序语句:**从上朝下执行的代码就是顺序

​ **分支语句:**根据不同的情况,执行对应代码

​ **循环语句:**重复做一件事情

代码规范:
1. 运算符前后都要加空格
2. **;,**只需后面加一个空格

分支语句


分支语句三大类: 单分支 双分支 多分支

if语句 (单分支)
**语法:**
  	  **if( **表达式 **){**
   	     	执行语句:表达式为真的执行
   	 **}**
if-else语句 (双分支)
**语法:**
  	  **if( **表达式 **){**
   	     	执行语句:表达式为真的执行
   	 **}** **else{**  表达式为假时执行  **}**

​ **注意:**三目运算符可以代替部分简单的if-else语句

​ **编程习惯:**能写三目写三目,能写短路写短路(新手不推荐)

else-if语句 (多分支)
**语法:**
	  **if( **表达式 1**){**
   	  	执行语句1:表达式1为真执行
 	 **}**  **else if(** 表达式 2 **){**

​ 执行语句2:表达式1不为真,表达式2为真时执行

} else {

​ 执行语句:上述表达式都不成立时执行

}

​ **作用:**else-if 语句是为了解决if-else语句的嵌套问题

Switch语句 (多分支)

​ **作用:**解决双分支的嵌套问题,从某个可枚举的入口开始执行代码

语法:
switch(表达式/变量) {
case 常量1:
​ 执行语句1;
break;
case 常量2:
​ 执行语句2;
break;
​ …
default: 执行语句;(当上述所有的case选项匹配失败时,执行这里)
​ }

执行过程:

​ **case穿透:**省略break,可以多个case共用一个执行语句

​ break在switch中的作用是结束switch结构

					 如果case没有break语句 switch将自动向下穿透执行(直到遇到break为止)

					当所有的情况都无法满足时 则执行default语句
switch 和 if-else的区别
  1. if-else 适用性广 条件允许判断 相等 不相等 大小比较等情况

  2. switch-case 适用于匹配某个范围内确定的值(相等判断)

  3. if-else 多个条件依次遍历向下判断

  4. switch-case 直接选择 结构清晰 高效率

其他函数:

prompt() 弹出带输入框的警告框,返回字符串

循环语句

循环的概念

重复去做一件事情

循环的好处:

   	 1.代码简洁
	 2.代码不冗余
  	 3.后期维护方便

写循环的步骤:

   1. 确定循环的条件
      注:循环条件 可以写任意的表达式(表达式会自动数据类型转换为布尔值,真就循环,假就中止)
      注:不能让循环条件永远成立,会造成死循环

   2. 确定好每一次执行的代码


While 循环

  **格式**:
     while(循环的条件){
        循环语句;
    }

​ **执行:**如果循环条件成立就执行循环语句,直到循环条件不成立为止

do While 循环

格式:
​ do{
​ 执行语句
​ }while(循环条件);
​ **注:**do…while后的分号不要省略掉

while循环和do_while 循环的区别
while :先判断循环条件
do_while:先运行一次循环语句,再去判断循环条件是否成立

for 循环

格式:
​ for(表达式1; 表达式2; 表达式3;){
​ 执行语句;
​ }
​ **表达式1:**在循环开始之前只执行一次(通常是声明变量)
​ **表达式2:**循环的条件
​ **表达式3:**循环变量的递增等等

break和continue关键字

​ **break:**中止当前循环

 **continue:**跳过此次循环,继续执行下次循环
死循环

死循环产生条件:循环条件永远成立

**while(1){}**是最常用的死循环方式

do_while实现死循环:(循环条件写1或者true)

for实现死循环:(只写分号,三个表达式全部为空)

循环嵌套

  1. 循环可以互相嵌套

  2. 循环中用于计数的数,称为下标(通常i代表index)

  3. 下标命名:i k j l m n(避免冲突,嵌套时每个循环要使用不同的下标)

    **注:**循环嵌套不是语法,当需要循环的时候,就可以使用循环

第四章 函数

函数的简介

函数的概念:函数是由完成特定功能的一个或多个语句块组成的一个[独立实体]

函数的意义: 1. 对过程进行封装 2.对细节进行隐藏

函数的特点: 1. 需要调用才会执行 2.调用会改变执行顺序 3.函数具有复用性

方法(method): 在对象下通过点操作符使用的函数被称为方法 ,本质上也还是函数

函数的创建

ECMAScript 提供了两种创建方式:函数声明 / 函数表达式

函数的声明 使用关键字 function 声明函数

函数声明:

语法: 使用标识符作为函数名,并通过 函数名(); 调用

function fnName(){
    语句块
};

函数表达式(赋值式创建):

语法:将匿名函数赋值给一个变量, 通过 变量名(); 调用

var Myfunction =function(){
	语句块
};

注: Js中默认为顺序结构,函数表达式必须先赋值给变量,才能调用

函数的参数

**形参:**假设形式上的参数 (可以理解为局部的临时变量)

实参: 函数调用时给的实参数(可以是任意的数据类型)

**传参:**赋值操作,用实参给形参依次赋值

arguments对象:

arguments对象: 是内置在函数里用于存储参数的数据容器(类似数组)

arguments的访问方法: arguments.length(访问实参个数) arguments[下标/索引] :所在索引的参数值

**注: **优先使用形参, 除非不能确定参数的个数

函数的返回值

函数使用 return关键字 设置来函数的返回值

return后无数据,或没有return 默认返回undefined

return返回的可以是任意数据类型

函数遇到return时会终止运行

函数的预编译和声明提升

预编译和声明提升其实是同一个概念

由于JS是解释型语言,他的解释步骤为: 1 .语法分析 2.词法分析 3.预编译(部分预先执行)

**概念:**在当前作用域,声明的变量和函数,会将标识符提升在整个代码的最顶端声明(只声明,不赋值,所以在未赋值前为undefined)

函数名和变量的优先级:函数名的优先高于变量名,所以在变量未赋值之前,重名的标识符代表函数

作用域

Js有 全局作用域和函数作用域 两种

概念: JS的作用域是 静态作用域 (作用域是在定义时决定的 不是执行时决定的)

类型:

全局作用域: 定义好的变量或函数可以在任意位置被访问

函数作用域: 定义在函数内部的变量或函数 仅在函数内部有效

**注:**未声明的变量会默认为全局变量,应该避免使用,以防全局污染

作用域链

递归函数

递归概念: 就是函数自己调用自己,如果不设置出口,本质上是死循环。

递归的作用: 递归可以解决循环能做的所有事情,也可以做循环做不到的事情,但效率过低。

注意事项: 使用递归必须包括一个结束递归的条件,避免程序进入死循环。(递归结束的条件写在函数开头)

应用场景: 树结构遍历(目录结构遍历) /辗转相除法

使用方法(重要):

1.首先去找临界值(递归终止条件:可以轻松得出的值)

2.寻找这一次和上一次的关系

3. 假设当前函数已经可以使用,调用自身计算上一次

**番外:**公司明文禁止使用递归。(递归效率过低,且在边界条件保护不足的情况下会瞬间开辟大量内存空间,导致堆栈溢出)

辗转相除法:

利用辗转相处法计算最大公约数image-20210329215548690

function fn(m, n) {
     var r = m % n;
     m = n;
     n = r;
     if (r == 0) {
        return m;
     } else {
        return fn(m, n);
     }
}

 console.log(fn(27, 9));
匿名函数

**概念:**指的是定义函数时未给函数进行命名

优点:

  1. 匿名函数可以有效隔离作用域 避免作用域污染

    2.匿名函数仅在执行时临时创建作用域链对象

    3.在执行结束后自行销毁 更节省内存空间

**使用方式:**自执行函数(一次性函数) / 回调函数

自执行函数: 用于执行一个功能,并只执行一次

 (function(){})();
 !function(){}();
 ~function(){}();
回调函数

当一个函数作为参数使用时 就叫做回调函数

回调函数的传参是反向 将从内向外反向调用某个外部函数

关键字 callback (并不是关键字,只是约定俗成的写法)

回调函数的理解:

1.创建回调函数 2.在主函数登记回调函数名 3.调用主函数并传入回调函数名和值并触发回调事件 4.回调函数最后响应回调事件

 function title(value){//这是回调函数!!!!
			alert(value);
 }
 function main(title, value){//这个主函数:在参数列表中,title作为一个参数传递进来,也就是上文说的 参数化函数;然后value这个值正是title()函数中所需要的。
			alert("我是主函数");
			title(value);//这行这个title(),它就是回调函数
 }
 main(title,"我是回调函数");//title参数加上()后,就会变回一个函数,并会被执行一次。
//PS:看清楚,调用的是main()函数,意味着先执行main(),这时已经执行了主函数,title()被main()在函数体中执行了一次,因此title()是回调函数。

两种使用方法:

  • 将回调函数的参数作为与回调函数同等级的参数进行传递

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ou8yTN4r-1627574616864)(C:\Users\梦境半小时\AppData\Roaming\Typora\typora-user-images\image-20210329212249087.png)]

  • 回调函数的参数在调用回调函数内部创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6SHUEO1S-1627574616867)(C:\Users\梦境半小时\AppData\Roaming\Typora\typora-user-images\image-20210329212326718.png)]

惰性函数

惰性函数 是一种函数的高阶使用方式

特点:不知道自己的作用,需要执行一次才能决定自己的作用

原理: 先执行一次自己,如果满足某个条件,则将要做的事情函数赋值给自己,并将自己返回

案例1:利用惰性函数实现事件兼容

var addEvent = (function() {//惰性函实现兼容
    if (document.addEventListener) {
        return function(elm, eventType, fn) {
            elm.addEventListener(eventType, fn);
        }
    } else {
        return function(elm, eventType, fn) {
            elm.attachEvent('on' + eventType, fn);
        }
    }
})();
 window.onload = function() {//实际使用
     var btn1 = document.getElementById('btn1');
     var btn2 = document.getElementById('btn2');

     console.log(addEvent);
     addEvent(btn1, 'click', function() {
         alert(1);
     });

     addEvent(btn2, 'click', function() {
         alert(2);
     });
 }

第五章 函数与事件

JavaScript是可以由事件驱动执行(事件可以调用函数)

事件绑定三要素

​ 1. 事件源(html元素)

​ 2. 事件类型(onclick onmouseover onmousemove …)

​ 3. 事件处理函数(函数表达式 将一个函数赋值给事件属性)

加载事件:

window.onload(); 当页面资源加载完毕后触发

鼠标事件:
事件名称作用
onclick鼠标左键点击
oncontextmenu鼠标右键点击
onmousehover鼠标悬停
onmouseout鼠标移出
onmouseenter鼠标进入
onmouseleave鼠标离开
表单事件:
事件名称作用
onsubmit提交事件
onfocus获得焦点事件
onblur失去焦点事件
oninput输入事件
onchange改变事件(触发条件:内容改变、失去焦点)
键盘事件:
事件名称作用
onkeydown键盘按下事件
onkeyup键盘弹起事件

第六章 对象


对象是ECMAScript提供的一种 内置的引用数据类型

概念

对象是一组数据和功能的集合 (数据为键值对属性,功能为函数)

对象的创建:

​ 1.通过new运算符创建对象

       var obj = new Object();      

​ 2.通过大括号{}字面量创建对象

        var obj = {};     //在JS中使用{}大括号代表的是对象,这种语法被称为语法糖

对象的参数:

性(键值对)

属性使用和普通变量没有区别(必须依附对象使用)

​ object.属性名 = 数据 ;
​ object[‘属性名’] = 数据 ;

​ 对象的属性默认是字符串类型的

方法

使用和普通函数没有区别(必须依附对象使用)

​ object.方法名=function(){};
​ object[‘方法名’]=function(){}

对象的转换:

JSON.stringify()方法

使用JSON.stringify()方法可以将对象转成JSON格式的字符串

语法:JSON.stringify( Obj )

返回值:JSON格式的字符串

JSON.parse()方法

使用JSON.parse()可以将JSON字符串转成JSON对象

语法:JSON.parse( Str )

返回值:一个新的JSON对象

注意点:JSON字符串必须保证 外层单引号 内层双引号(确保格式)

对象的操作:

添加属性 为不存在的属性进行赋值操作

删除属性 使用delete关键字删除属性(只能删除可枚举属性,和不受保护的属性)

	**改** 修改属性 为已存在的属性进行赋值操作

访问属性 可以使用点操作符或中括号

对象的遍历 :

因为对象是无序排列,所以不能使用for循环遍历

in 关键字

in 关键字 用于检查对象中的属性是否存在

语法: 属性名 in 对象

​ **返回值: ** 布尔值

for in 遍历对象

forin 只能遍历可枚举属性和不受保护的属性

语法: for (var key in obj) {执行语句}

JSON数据格式:

Json是一种基于ECMAScript的数据交换格式

Json采用简洁的语法表示数据

使用 [] 表示数组

使用 {} 表示对象

键值对 使用 :" 名称 " : 值 (注意双引号)

多个并列的数据使用逗号 , 分隔

第七章 数组


概念

数组是指使用一个变量存储一系列数据的一种数据类型,它存储的每个数据叫做数组的元素,数组按照索引有序排列。

数组类型

ECMASCript 提供了两种数组类型 索引数组和关联数组

索引数组

通过访问索引值获得成员信息 有序

关联数组

关联数组 指的是在数组中存储键值对

通过key访问获得成员信息 无序

语法:	  var arr = [];
        arr['name'] = 'zhangsan';

注意: 由于关联数组的长度为0,所以关联数组需要使用for-in遍历

数组的创建

​ 1.通过new运算符 声明表达式 创建数组

       var arr = new Array(vlaue1,vlaue2....);   //当()中只有一个参数的时候,他表示该数组的长度length   

​ 2.通过中括号[ ]字面量创建对象

        var arr = [];     //在JS中使用[]中括号代表的是数组,这种语法被称为语法糖

数组的属性

length属性: arr.length 表示的是数组的长度

数组的访问

**索引/下标:**指的是元素在数组中占据的顺序位置,索引是从0开始的,且最大为 length-1

**arr[索引]:**访问数组的元素

数组的遍历

遍历概念:将数组中的元素从头到尾看一遍

for循环 遍历
语法:for (var i = 0; i < 数组名.length; i++){执行语句}   // 正序,倒序只需要将条件反一下
for…in 快速遍历
语法: for (var i in 数组名){执行语句}    //for-in 可以遍历对象中的可枚举属性

**注意:**遍历数组尽量使用for 遍历对象使用for-in

数组的方法(API)

API(Application Programming Interface,应用程序接口)通过API执行预先定义的功能,又无需访问源码

Array.prototype

在数组原型对象中存储了数组公用的属性和方法这些属性和方法,在任意一个数组的实例中都可以被访问

Array.prototype.push()

描述: 方法push将在数组的尾部依次插入元素(一个或多个)

语法: arr.push(element1[,element2,…elementN]);

参数: element(any) 任意类型 需要插入到数组尾部的内容

返回值:length(number) 插入数据后的数组新长度

注意点:直接修改源数组(推入的是数组时,并不会展开,而是作为一个整体推入)

Array.prototype.pop();

描述: 方法pop将用于删除数组中的最后一个元素

语法: arr.pop()

返回值: 被删除的元素(数组中没有元素则返回undefined)

注意点: 直接修改源数组

Array.prototype.shift()

描述: shift函数将数组的第一个元素移出数组,将数组中后面所有的元素向前移动一位

将数组的长度-1 如果没有可删除的元素则返回undefined

语法: arr.shift();

返回值: 数组中的第一个元素

注意点: 直接修改源数组

Array.prototype.unshift()

语法: arr.unshift(value[,value2,…valueN]);

参数: value(any) 需要添加到数组头部的值

描述: unshift方法将依次把value添加到数组的头部 并将数组原有元素向后移动

返回值: length(number) 添加内容后的数组长度

注意点: 直接修改源数组

Array.prototype.splice()

语法: arr.splice(start[,deleteCount[,value,…valueN]]);

参数: start(number) 开始索引

deleteCount(number) 删除个数

value(any) 插入的元素

返回值: array 包含所有被删除的元素 如果没有删除元素则返回 一个空数组

描述: 在指定的索引位置删除元素

​ 在指定的索引插入元素

​ 在指定索引位置替换元素

注意:会修改源数组

Array.prototype.slice()

语法:数组名.slice(start,end)
参数:起始元素下标和结束元素的下标如(如果是负数则是倒序的)
功能:基于当前数组获取指定区域元素 [start, end),将提取出来的元素生成新数组
返回值:提取出来生成的新数组
注:不修改源数组

Array.prototype.join()

语法:数组名.join(字符串)
参数:字符串的拼接符(用于分隔元素)
功能:将数组中的元素,用传入的拼接符,拼接成一个字符串
返回值:拼接好的字符串

Array.prototype.reverse()

​ 语法:数组名.reverse();
​ 功能:将数组下标逆序
​ 返回值:逆序后的数组

Array.prototype.concat()

描述: concat方法用于合并两个或多个数组

语法: arr.concat(value[,value2,…valueN]);

参数: value(any) 数组或值 所有value会被依次添加到新数组中

返回值: array 新数组

注意点: 此方法不修改源数组 而返回一个新数组(可用于复制数组:浅拷贝,如果元素是数组,仅仅是将数组的引用地址拷贝)

Array.prototype.sort()

描述:对数组按排序函数或默认进行排序 默认将数据转化成字符串,按第一个字符的ASCII码值从小到大排序排序

语法: arr.sort([compareFunction])

参数: 排序函数 或 无

返回值:排序后的源数组

注意:会修改源数组

排序函数:
    语法:function(a,b){return a-b}
    若a小于b,排序后a应该出现在b之前,则返回一个小于0的值,sort会进行升序排列
    若a等于b,则返回 0。
    若a大于b,则返回一个大于0的值,sort会进行降序排列
 使用sort实现类似于reverse的效果
   	    var arr4 = [5423, 61, 431, 33, 1, 786];
        arr4.sort(function() {
       		 return -1;
        });

 对数组进行随机排序(对数组实现乱序)
     var arr5 = [1, 2, 3, 4, 5, 6, 7];
     arr5.sort(function() {
		 return Math.random() - 0.5;
	 });

        // 如果添加了 compareFunction 那么数组会按该函数的返回值结果进行排序。
        // 即 compareFunction(a,b) 表示 a,b的比较结果,规则如下:
        // 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;
        // 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。
        // 备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);
        // 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。
        // compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

第八章 ES5新增的API

ES5: ECMAScript5

ES 指的是ECMA-262标准

传统上来说 版本是按照数字进行命名 发布顺序 1 2 3 4 5…

但从2015年开始 EMCA宣布 ES的版本号使用年份命名

ES6(ES2015) ES7(ES2016) … ES11(ES2020)

ES5新增7个数组API

ECMA5新增了 7个 数组的方法(indexOf/forEach/map/filter/some/every/reduce)

indexOf

功能 :从当前数组下标为 fromIndex的元素开始向后查找元素 searchElement,找到则返回第一次出现的下标,若没有则返回-1

语法: arr.indexOf(searchElement[,fromIndex=0])

语法简: 数组名.indexOf(item,start);

参数: searchElement 为任意要查找的数据
fromIndex 为开始查找的下标位置(下标可以不传,默认为0)

返回值:若找到返回所在的下标,若没有找到则返回 -1

注意点: this关键字出现在函数中 谁调用该函数 this就指向谁

原理:

var arr =[1,6,4,5,6,7,43,6];
Array.prototype.indexof=function(item,start){
    if(start){
        start=start
    }else{start=0}
    for(var i =0;i<this.length;i++){
        if(this[i]=== item) return i;
    }
    return -1;
}
console.log(arr);
console.log(arr.indexof(6));

find方法

功能: 遍历数组返回数组中满足提供条件的第一个元素的值。否则返回 undefined。

​ 语法: arr.find(callback);

​ 参数: callback(function);

​ 回调参数:

​ currentValue index array

​ 返回值: 返回第一个满足条件的值

findIndex方法

​ 描述: 返回数组中满足条件的第一个元素的索引 若没有找到对应元素则返回-1

​ 语法: arr.findIndex(callback);

​ 参数: callback(function)

​ 回调参数:

​ currentValue index array

forEach

功能 :遍历当前数据,并把每个元素都传递给调函数执行

语法: arr.forEach(callback)

语法简:数组名.forEach(function(item, index, arr){执行语句});

参数: 回调函数(需要执行的函数)

回调函数参数: currentValue 当前值

​ [index] 当前值对应的索引

​ [array] 当前数组

返回值:无返回值

原理:

var arr =[1,6,4,5,6,7,43,6];//将每个元素*3并输出
Array.prototype.forEach=function(val){
	console.log(val*3)
}

map

功能 : 映射关系 遍历当前数组,将每个元素传入参数中的回调函数,并返回函数的返回值,形成一个形成一个新数组

语法:数组名.map(callback);

语法简: 数组名.map(function(item, index, arr){retrun 表达式});

参数:回调函数

回调函数参数: currentValue 当前值

​ [index] 当前值对应的索引

​ [array] 当前数组

返回值:新数组

原理:

var arr = [1, 2, 3, 4, 5];
Array.prototype.Map=function(callback){
    var newArr=[];
    for(var i= 0;i<this.length;i++) {
        newArr.push(callback(this[i],i,this))
    } 
    return newArr;
}var newArr=arr.Map(function(val){
    if(val % 2){
        return val*3;
    }else{return val*4;}
});
console.log(newArr);

filter

功能 :遍历当前数组,然后调用参数中的函数,将符合函数条件的元素返回一个新数组

语法:arr.filter(callback);

语法简:数组名.filter(function(currentValue, index, arr){retrun 表达式});

参数:回调函数

回调函数参数: currentValue 当前操作的值

​ [index] 当前操作值对应的索引

​ [array] 当前数据

返回值:新数组

原理:

var arr=[12,32,3225,325,53,66,78,54];
        var newArr=arr.filter(function(item,index,arr){return item % 2 ==0;});
console.log(newArr);


Array.prototype.filter1 = function(callback) {
    var newArr = [];
    for (var i = 0; i < this.length; i++) {
        newArr.push(callback(this[i],i,this));
    }
    return newArr;
}
var newArr=arr.filter1(function(item){
    if(item % 2==0){
        return item;
    }else{return "  "};
})
console.log(newArr);

some

功能 :遍历当前数组,为每个元素执行回调函数,只要有有一个元素符合函数内的布尔表达式,就返回true,否则返回false

语法:数组名.some(callback(element[, index[, array]]))

语法简:数组名.some(function(item, index, arr){retrun 表达式});

参数:回调函数

返回值:布尔值

原理:


every

功能 :遍历当前数组,为每个元素执行回调函数,当每一个元素都符合函数的布尔表达式才返回true,否则返回false

语法:数组名.every(callback(element[, index[, array]]))

语法简: 数组名.every(function(item, index, arr){retrun 表达式;});

参数:回调函数

返回值:布尔值

原理:

// 数组内是否都是奇数
Array.prototype.every1 = function(callback) {
    var temp;
    for (var i = 0; i < this.length; i++) {
        temp = callback(this[i], i, this);
        if (!temp) return false; // 只要又一个是false就retrun结果
    }
    return true; //循环结束都没有false则返回true
}
var arr = [152, 221, 31, 77, 19];

var res = arr.every1(function(val) {
    return val % 2;
});
console.log(res);

reduce

功能 :用于归并

语法:arr.reduce(callback[,object]);

语法简:数组名.reduce(function(prev,next,index,arr){retrun prev+next;})

回调参数:

 prev  上一个

​ next 下一个

当拥有object参数时 回调参数:

object

​ currentValue

返回值:归并结果(没有设置return时返回undefined)

应用场景:统计 求和

//统计 统计有多少个奇数多少个偶数
var arr = [6, 54, 24, 325, 34, 5, 4363, 1654, 87, 6, 327];

var result = arr.reduce(function(obj, cur) {
    // console.log(obj, cur);
    cur % 2 ? obj.odd++ : obj.even++;
    obj.sum += cur;
    return obj;
}, {
    odd: 0,
    even: 0,
    sum: 0
});
console.log(result);
// 求和 求数组元素值的总和
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]

var result = arr.reduce(function(prev, next) {
    return prev + next;
});
console.log(result);

原理:

//统计 统计有多少个奇数多少个偶数
Array.prototype.reduce1 = function(callback, object) {
    var result; // 用于临时存放 结果对象
    if (typeof object === 'object' && object !== null) {
        for (var i = 0; i < this.length; i++) {
            result = callback(object, this[i]);
        }
        return result;
    }
}

var arr = [1, 2, 3, 4, 5, 6, 7];
var result = arr.reduce1(function(obj, current) {
    current % 2 ? obj.odd++ : obj.even++;
    return obj;
}, {
    odd: 0,
    even: 0
});

console.log(result);

第九章 字符串的API

常用的ASCII码值:

            0~9  48~57
            A-Z  65~90
            a-z  97~122

获取API

charAt()方法

​ 语法:字符串.charAt(下标)
​ 功能:获取下标位置的字符

CharCodeAt()方法

​ 语法:字符串.charCodeAt(下标)
​ 功能:获取下标位置字符的ASCII码值

【注】上述两个方法使用字符串对象调用

String.formCharCode()方法

​ 语法:String.formCharCode(码值1,码值2…)
​ 功能:将传入的编码值转换成字符
​ 返回值:组成的新字符串

查找API

indexOf()方法

​ 语法:字符串.indexOf(item,start);
​ 参数:第一个参数:查找的字符串
​ 第二个参数:开始查找的下标位置(可以省略,默认位置为0)
​ 返回值:查找到字符的下标 若没有则返回-1
​ 功能:在字符串中从start位置开始查找item字符第一次出现的下标位置

lastIndexOf()方法

​ 语法:字符串.lastIndexOf(item,start);
​ 参数:第一个参数:查找的字符串
​ 第二个参数:开始查找的下标位置(可以省略,默认位置为最后一个字符位置)
​ 返回值:字符串最后一次出现的下标 若没有则返回-1
​ 功能:查找字符串最后一次出现的位置

search()方法

​ 语法:字符串.search(item);
​ 参数:查找的字符串/正则表达式
​ 返回值:查找到字符的下标 若没有则返回-1
​ 功能:在字符串中查找item字符第一次出现的下标位置

提取方法API

substring()方法

​ 语法:字符串.substring(start,end);
​ 功能:将字符串中从[start,end)位置的字符提取出来,生成一个新字符串
​ 返回值:生成的新字符串

substr()方法

​ 语法:字符串.substr(start,length);
​ 功能:将字符串中从start位置开始的length个字符提取出来,生成一个新字符串
​ 返回值:生成的新字符串

slice()方法 (是数组的方法,但可以被字符串调用)

​ 语法:字符串.slice(start,end)
​ 功能:将字符串中从[start,end)位置的字符提取出来,生成一个新字符串
​ 返回值:生成的新字符串(不修改原字符串)

replace()方法 替换

​ 语法:字符串.replace(old,new);
​ 参数:old:字符串/正则表达式
​ 1.若old是字符串,则new只能替换第一次出现old字符串
​ 2.若想字符串中的old全部替换成new,则old要为 :/old/g (i忽略大小写,g全局匹配)
​ new:替换old的字符
​ 功能:用new替换old,生成新字符串(原字符串不会发生改变)
​ 返回值:替换成功的新字符串(不修改源字符串)

正则表达式:带超级功能的string

split()方法 字符串分割

​ 语法:字符串.split(分割符,length);
​ 参数:分割符/正则表达式
​ length:控制返回的数组个数,一般情况下不用
​ 功能:在原字符串中寻找分割符,以分割符分割原字符串,将分割下来的子串放在数组中返回
​ 返回值:数组(元素为子串)
​ 【注意】: 分割符为空字符串时,会将每一个字符分割

toLowerCase()与toUpperCase()方法

​ 语法:字符串.toLowerCase() 功能:转成全小写
​ 语法:字符串.toUpperrCase() 功能:转成全大写

concat()方法 字符串拼接

​ 作用:
​ 1.在数组中用于合并数组
​ 2.在字符串中用来拼接字符串
​ 语法:原字符串.concat(参数1,参数2…);
​ 返回值:拼接后的新字符串
​ 【注】:concat()方法拼接字符串并不常用,使用 + 号拼接更便捷

trim() 方法

语法: 字符串.trim()

功能: 去除字符串左右的空白符(空格)

返回值: 去除空白符后的新字符串

repeat() 方法

语法: 字符串.repeat(count);

参数: count(number) 重复的次数

返回值:新字符串

第九章 数据类型和结构


内存管理机制

在JS中内存分为两段,内存栈 和 内存堆

内存栈

内存栈中存储的都是基本数据类型,且一次只能存储一个基本类型的数据(空间不能改变)

内存堆

内存堆中存储的都是引用类型的数据实体,一次可以存储多个数据(空间随实体的大小而改变)

数据类型


JS有两大类数据类型基本类型引用类型

基本类型:Number String Boolean Null Undefined (其中string、number、boolean是基本包装类型)

引用类型:Object Array Function

引用类型

通过 new关键字声明的引用类型,会在内存堆中开辟一段空间,来保存新创建的对象,并将返回空间的地址(以便调用)

​ 把这段空间地址赋值给一个变量的操作叫引用

​ 将变量名赋值给其他变量时,其实就是把同一个地址赋值给其他变量,所操作的其实是同一个数据

基本包装类型

**定义:**基本包装类型是指可以 通过new关键字 将基本类型包装成引用类型

**作用:**由于基本类型没有属性和方法,所以将基本类型临时包装成对象,并提供了方法,并在方法使用完成后,销毁了这个对象,所以它的proto原型最终不会改变

三种基本包装类型: Number String Boolean

数据参数传递


当参数为引用类型时,传递的则是引用地址

当参数为基本类型时,传递的则是值

数据类型检测


Js是弱类型语言,所以数据类型检测尤为重要,可以避免许多BUG

Js提供的四种数据检测方式:typeof instanceof constructor Object.prototype.toString.call()

typeof 运算符

typeof 只适合检测基本数据类型,因为除了function 检测引用类型返回的都是object

**返回值:**字符串类型的(“number” “string” “bolean” “undefined” “function” “object” )

注意:由于null是一个空对象指针,表示指向一个 “空” 的对象,将来可能会存储数据。所以他的类型也是object

instanceof 运算符

弥补typeof的不足,可以检测所有的属性类型,当然傻逼的Null和Undefined并不在其中(JS设计缺陷)

**语法:**实例 instanceof 类;

描述: 实例 是否属于对应的类,如果属于返回true,如果不属于返回flase

**参数-实例:**必须是基本包装类型或者引用类型

参数-类: 可以为(Array Object Function RegExp )

**返回值:**布尔值 true / flase

**注意点:**当判断实例是否属于Object的时候,都会为true

constructor 检测法

constructor其实是一个属性,所有的数据类型都拥有该属性

**语法:**实例.constructor === 类

**参数-实例:**任意数据类型

参数-类: 可以为(Array Object Function String Number Boolean Null Undefined )

**返回值:**布尔值 true / flase

**注意点:**当把构造函数的原型指向Array的时候,依然不能很好解决

Object.prototype.toString.call()

原型链上的Object对象的toString方法 也可以称为自定义函数检测法 (目前最常用主流的检测法)

语法: Object.prototype.toString.call( 要检测的实例 )

返回值: 字符串类型的具体类型名

: console.log(Object.prototype.toString.call(o).slice(8,-1));    // [object Boolean]

数据结构(简)

数据结构:表示的是保存数据时采用特定的关系或结构

常见数据结构: 栈 堆 队列 树 哈希 链表 顺序表 散列表 字典 …

​ **注:**在计算机中 数组是采用索引有序排列的 ,而对象是采用键值对无序排列的

第十章 Math对象

Math对象提供了一系列常用数学函数和值

Math.random()         返回0-1之间的随机数
Math.max(num1, num2)  返回较大的数
Math.min(num1, num2)  返回较小的数
Math.abs(num)         绝对值(转换成正数)
Math.round(3.49)      四舍五入(成整数,只看小数点后一位)
Math.ceil(19.3)       向上取整
Math.floor(11.8)      向下取整
Math.pow(x,y)         x的y次方
Math.sqrt(num)        开平方

传入的参数:弧度
Math.sin()  正弦
Math.cos()  余弦
Math.tan()  正切

Math.PI=180弧度
1弧度=Math.PT/180;

第十一章 Date对象

Date对象用于处理日期和时间

语法格式:

通过new Date()声明 : var date=new Date();

参数

​ **1.**默认为系统当前时间
​ **2.**日期字符串 例:‘2000-01-01’ ‘2000/01/01’
​ **3.**多个整数 例:2000,0,1,10,30,45,150
​ **4.**时间戳

​ **注意点:**时间对象中,月份是从0-11代表的现实中的第1-12个月(纯粹设计失误导致…)

常用方法

set/getDate()

从Date对象中返回一个月中的某一天(1~31)

getDay()

从Date对象返回一周中的某一天(0~6) 根据月日计算出来的所以无法赋值

set/getMonth()

从Date对象中返回月份(0~11)

set/getFullYear()

从Date对象以四位数返回年份

set/getHours()

返回Date对象的小时(0~23)

set/getMinutes()

返回Date对象的分钟(0~59)

set/getSeconds()

返回Date对象的秒数(0~59)

set/getMilliseconds()

返回Date对象的毫秒

set/getTime()

返回1970年1月1日至今的毫秒数(又称时间戳:计算机中唯一不会重复的值)

now()

返回1970年1月1日至今的毫秒数(又称时间戳:计算机中唯一不会重复的值)

getTimezoneOffset()

返回本地时间与格林威治标准时间(GMT)的分钟差

注意:

​ set是对当前时间进行重新赋值,是操作

​ get是获取且有返回值

格式转换方法

d.toString();

​ 将日期对象转换成字符串

d.toDateString();

​ 格式:星期 月 日 年

d.toTimeString();

​ 格式:时 分 秒

d.toLocaleString();

​ 格式: 年 月 日 时 分 秒

d.toLocaleDateString();

​ 格式: 年 月 日

d.toLocaleTimeString();

​ 格式: 时 分 秒

计时器方法

周期性计时器

setInterval() 定时器 又称间隔调用

**开启语法:**setInterval(callback,delay);
**关闭语法:**clearInterval(定时器ID值);
**参数:**callback(function):执行函数 delay(number/ms):间隔时间
**功能:**按照指定的间隔重复的调用函数,直到clearInterval()被调用或窗口被关闭
**返回值:**id(number) 系统分配的定时器编号ID值

一次性计时器

**开启语法:**setTimeout(callback,delay);
**关闭语法:**clearTimeout(定时器ID值);
**参数:**callback(function):执行函数 delay(number/ms):延迟时间
**功能:**延迟时间后调用一次函数(只会调用一次)
**返回值:**id(number) 系统分配的定时器编号ID值

第十二章 单线程和异步操作

单线程

JavaScript 是单线程语言

因为Js运行在js引擎中,Js引擎是单线程环境,所以Js在同一个时间只能做一件事,单线程意味着,如果在同个时间有多个任务的话,这些任务就需要进行排队,前一个任务执行完,才会执行下一个任务。

**注:**Js 通过 web worker 可以支持多线程

同步和异步任务

JS提供了两个执行模式:同步(Synchronous)和异步(Asynchronous),

异步任务来源

因为JavaScript是单线程,所以在执行任务时,会按顺序一个一个执行,但如果前一个任务需要大量时间执行时,后面的任务执行就会受到影响,如果上一个任务没有完成,会造成 线程 I/O(Input/Output)阻塞 (所有的I/O都会造成线程阻塞)

为了解决这个问题,Js提出了异步操作, JS引擎使用了事件轮询(event loop)机制来处理线程 I/O阻塞的情况,将阻塞的任务变成异步任务并挂起到事件队列中,等主线程执行完后,在执行事件队列中的异步任务

同步任务

同步任务指 程序执行顺序与任务的排列顺序是一致的、同步的。只有前一个执行完,才会执行下一个(页面元素渲染就是同步任务)

注:同步任务会造成阻塞

异步任务(非常重要)

异步任务指 将任务放入到 事件队列 等待执行当主线程中任务执行完毕后 然后执行事件队列中的任务 (图片、音乐加载就是异步)

注:异步任务不会造成阻塞

计时器事件回调函数都属于异步任务

第十三章 BOM

BOM 是浏览器对象模型 Browser Object Model

BOM概念

**理解:**每一个浏览器窗口,就是一个BOM对象。

**主要内容:**BOM对象是操作浏览器窗口的一组对象和函数的统称

主要对象: window; history; location; navigator; document; screen; event

**根对象:**window对象

Window对象

定义

1. window对象是BOM的根对象(root),最高级别的对象
2. window对象在浏览器环境中是全局对象
3. 每新建一个浏览器窗口,其实就是新建了一个window对象
4. 在全局环境下,this 关键字指向window对象
5. window对象的子对象和属性都可以省略 window. 操作

this关键字

​ this 在JS中是一个关键字

它是一个动态的指针 它会指向某个对象

​ 它的指向不是由定义时决定的 是由执行时决定的

​ 在函数中 谁调用函数 this 就指向谁

全局属性(常用)

window对象的属性又称为全局属性 (因为window对象的子对象和属性都可以省略window.)

​ name 窗口名称

​ length 框架数量

​ innerHeight 显示区域的高度

​ innerWidth 显示区域的宽度

​ outerHeight 浏览器的高度

​ outerWidth 浏览器的宽度

全局方法(常用)

window对象的方法又称为全局函数或者全局API (因为window对象的子对象和属性都可以省略window.)

alert()

​ 弹出带提示和确认按钮的警告框

confirm()

​ 弹出带提示以及确认和取消按钮的对话框

prompt()

​ 弹出用户可以输入的对话框

close()

​ 关闭当前浏览器窗口

open()

​ 打开一个新的浏览器窗口 或查找一个已命名的浏览器窗口并打开它

blur()

​ 可把键盘焦点从顶层窗口移开

focus()

​ 把键盘焦点给予一个窗口

print()

​ 打印当前窗口的内容

Location对象

location 是全局对象 用于保存浏览器地址栏中URL(统一资源定位器)的相关信息

URL简介

URL:统一资源定位符
URL完整格式:
中文版本 协议://主机名(IP或域名)/:端口号/路径/?查询字符串#锚点
英文版本 protocol://hostname/:port/pathname/?search/#hash

**协议:**指定使用的传输协议 常见:file/http/https(证书协议)/FTP等
主机名:主机名指IP或者域名
**端口号:**是系统给当前电脑中使用网络的软件随机分配的编号 0~65535
**查询字符串:**用于前后端交互 格式:?键值对1 & 键值对2…
锚点:#后面的部分 可以直接定位到指定的资源

注: hostname:port 可以直接定位到当前使用网络的程序
**扩展:**系统软件和高频率软件一般有默认的端口号(浏览器:8080 http:80 https:443)
浏览器 8080
http 80
https 443

Locatin对象属性

location.href 获取完整的URL
location.protocol 获取协议
location.host 获取主机名和端口号
location.hostname 获取主机名
location.port 端口号(默认隐藏,地址栏中有端口号才能获取)
location.pathname 路径( 主机名后一个斜杠开始
location.search ?查询字符串
location.hash非常重要) 获取hash值(锚点地址)

location.hash 实现SPA单页面应用

SPA是指单页面应用,在不改变网页地址的情况下,更换页面内容,功能雷同HTML的iframe内联框架

应用SPA的实例:网易云音乐 美团 饿了么…

使用方式:通过超链接设置锚点,在通过点击超链接, 浏览器对地址栏有一个 hashchange 事件,利用hash值进行匹配对应的JS代码

history对象

保存当前窗口中加载过url的历史记录,并提供前进后退方法的对象, 对应浏览器窗口的前进后退键

属性:

​ history.length 当前窗口历史记录的条数

方法:

​ history.back() 返回上一条历史记录
​ history.forward() 前进到下一条历史记录
​ history.go()
​ 参数: 0 刷新当前页面
​ 正整数 前进n条记录
​ 负整数 后退n条记录

screen对象

提供设备的显示器信息

event对象

事件对象

Navigation对象

navigator对象包含浏览器的信息

常用于获取客户端浏览器和操作系统信息

应用场景:检测浏览器类型


var browser = {
    userAgent: function() {
        var ua = navigator.userAgent;
        var ualower = navigator.userAgent.toLocaleLowerCase();
        return {
            trident: ua.indexOf('Trident') > -1, // IE内核
            presto: ua.indexOf('Presto') > -1, // opera内核
            webKit: ua.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
            gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') == -1, // 火狐内核
            mobile: !!ua.match(/AppleWebKit.*Mobile.*/) || !!ua.match(/AppleWebKit/), // 是否为移动终端
            ios: !!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // IOS终端
            android: ua.indexOf('Android') > -1 || ua.indexOf('Mac') > -1, // 安卓终端
            iPhone: ua.indexOf('iPhone') > -1 || ua.indexOf('Mac') > -1, // 是否为iphone或QQHD浏览器
            iPad: ua.indexOf('iPad') > -1, // 是否为iPad
            webApp: ua.indexOf('Safari') == -1, // 是否web应用程序,没有头部与底部
            QQbrw: ua.indexOf('MQQBrowser') > -1, // QQ浏览器(手机上的)
            weiXin: ua.indexOf('MicroMessenger') > -1, // 微信
            QQ: ualower.match(/\sQQ/i) == " qq", // QQ App内置浏览器(需要配合使用)
            weiBo: ualower.match(/WeiBo/i) == "weibo", // 微博
            ucLowEnd: ua.indexOf('UCWEB7.') > -1, //
            ucSpecial: ua.indexOf('rv:1.2.3.4') > -1,
            webview: !(ua.match(/Chrome\/([\d.]+)/) || ua.match(/CriOS\/([\d.]+)/)) && 	ua.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/),
            ucweb: function() {
                try {
                    return parseFloat(ua.match(/ucweb\d+\.\d+/gi).toString().match(/\d+\.\d+/).toString()) >= 8.2
                } catch (e) {
                    if (ua.indexOf('UC') > -1) {
                        return true;
                    }
                    return false;
                }
            }(),
            Symbian: ua.indexOf('Symbian') > -1,
            ucSB: ua.indexOf('Firofox/1.') > -1
        };
    }()
};
console.log(browser.userAgent);

第十三章 DOM

DOM概念

DOM 文档对象模型:document object model

定义: DOM就是window对象下的document对象,表示在浏览器中已经加载好的网页文档

**作用:**通过DOM可以动态修改HTML文档中的所有内容

**DOM树:**DOM树是展现所有HTML内容的节点树,根为document节点

节点

**节点:**HTML文档中的所有内容都是节点(一切皆节点)

节点也是对象(元素节点 属性节点 文本节点 注释节点 文档节点 文档声明节点)

节点类型:

元素节点 ————> HTML标签

属性节点 ————> 标签的属性

文本节点 ————> 标签中的内容文字

注释节点 ————> HTML的注释

文档节点 ————> document对象

文档声明节点 ————> html声明标签

节点属性:

nodeName 返回节点的名称
nodeType 返回节点的类型
nodeValue 返回节点的值或内容(元素节点不可用)

对照表nodeType(number)nodeName(string)nodeValue
元素节点1“标签名”(大写)null
属性节点2“属性名”属性值
文本节点3“#text”文本内容
注释节点8“#comment”注释内容
文档节点9“#document”null
文档声明节点10“html”null

节点集合类型(类数组)

NodeList 节点集合

NameNodeMap 属性节点集合

HTMLCollection 元素节点集合

类数组对象转数组

Array.from() // 来自ES6 低版本ie不支持

[].slice.call(arrayLike); // 可以支持低版本ie

获取元素节点的API

documnet.getElementById(‘id’)

​ 功能:通过Id名获取唯一的元素节点

node.getElementsTagName(‘标签名’)

​ 功能:获取node节点下的所有指定标签名的元素节点

​ 返回值:HTMLCollection (元素节点集合、类数组)

node.getElementsByClassName(‘类名’)

​ 功能:获取node节点下的所有用于指定类名的元素节点

​ 返回值:HTMLCollection (元素节点集合、类数组)

​ 注意: IE8以下不兼容

node.getElementsByName(name)

​ 功能:获取node节点下的所有指定name属性值的元素节点

​ 返回值: HTMLCollection (元素节点集合、类数组)

​ 注意:一般用于表单元素(checkbox和radio)

node.querySelector(CSS selectors)

​ 参数:CSS选择器格式的字符串

​ 功能:获取到node节点下指定CSS选择器第一个元素节点

​ 返回值:匹配指定CSS选择器的一个元素节点

​ 兼容性:IE8以下不兼容

node.querySelectorAll(CSS selectors)

​ 参数:CSS选择器格式的字符串

​ 功能:通过匹配指定选择器获取到批量的元素节点

​ 返回值:HTMLCollection (元素节点集合、类数组)

​ 兼容性:IE8以下不兼容

自定义ByClassName方法

解决getElementsByClassName方法在IE8以下不兼容的问题

解决方案:

​ 自定义一个同等功能的函数
​ 自定义函数名(node,classStr);

步骤:

​ 1.通过getElementByTagName(’*’)获取到node节点下所有的子节点
​ 2.遍历所有子节点,将遍历到节点的class属性值与传入的参数classStr比较
​ 3.如果两者恒等,就将相应的节点推入数组
​ 4.将推入完的数组作为函数的返回值

获取父子节点的API

可以获取文本节点和元素节点 兼容IE6-8

node.childNodes

​ 功能:访问当前节点下的所有子节点

​ 返回值: NodeList (节点集合、类数组)

node.parentNode

​ 功能:访问当前节点的父节点

​ 返回值: 父节点(Object)

node.firstChild

​ 功能:访问当前节点下的第一个子节点

​ 返回值:第一个子节点(Object)

node.lastChild

​ 功能:访问当前节点下的第一个子节点

​ 返回值:最后一个子节点(Object)

node.nextSibling

​ 功能:访问当前节点的下一个兄弟节点

​ 返回值:下一个兄弟节点(Object)

node.previousSibling

​ 功能:访问当前节点的上一个兄弟节点

​ 返回值:上一个兄弟节点(Object)

获取父子节点的API

只获取元素节点 兼容IE8以上

node.children

​ 功能:访问当前节点下的所有元素节点

​ 返回值: HTMLCollection (元素节点集合、类数组)

node.firstElementChild

​ 功能:访问当前节点下的第一个元素节点

​ 返回值:第一个元素节点(Object)

node.lastElementChild

​ 功能:访问当前节点下的最后一个元素节点

​ 返回值:最后一个元素节点(Object)

node.nextElementSibling

​ 功能:访问当前节点的下一个兄弟元素节点

​ 返回值:下一个兄弟元素节点(Object)

node.previousElementSibling

​ 功能:返回当前节点的上一个兄弟元素节点

​ 返回值:上一个兄弟元素节点(Object)

元素操作API

所有的元素节点都有四种常用属性

元素节点常用属性

innerHTML

​ 功能: 获取元素中的内容(双标签)

​ 注意:可获取和赋值,代码可解析

textContent

​ 功能:获取元素中的纯文本内容(保留格式)

​ 注意:该属性是DOM标准属性

innerText

​ 功能:获取标签中的纯文本内容(不保留格式)

​ 注意:代码不解析,非DOM标准

outerHTML

​ 功能:获取整个元素内容(包含标签本身)

​ 注意:代码可解析

元素节点的创建

elementNode.createElement

功能:创建元素节点

parentNode.appendChild(childNode)

功能:在指定父节点最后插入一个子节点

parentNode.insertBefore(newChild,existingChild)

功能:在父节点下的指定节点之前插入一个元素节点

元素节点的删除

parentNode.removeChild(childNode)

功能:在指定父节点下删除一个子节点

返回值:被删除的子节点

elementNode.remove()

功能:删除指定的元素解节点

返回值: 无返回值

parentNode.replaceChild(newNode,oldNode);

功能:将指定父节点下的旧子节点替换成和新节点

属性操作API

DOM提供了两种操作属性节点的方法 Attribute系列方法attributes方法

attributes系列方法

attributes方法只获取到指定属性节点对象本身,若想使用此方法获取属性值,需搭配nodeValue

node.attributes

​ 功能:获取当前元素节点下的所有属性节点对象

​ 返回值: NamedNodeMap (属性节点集合、类数组)

node.attributes.getNameItem(‘属性名)

​ 功能:获取当前元素节点下的指定属性节点对象

​ 返回值:指定属性节点对象(Object)

node.attributes[‘属性名’]

​ 功能:获取当前元素节点下的指定属性节点对象

​ 返回值:指定属性节点对象(Object)

node.attributes[索引]

​ 功能:获取当前元素节点下的指定属性节点对象

​ 返回值:指定属性节点对象(Object)

Attribute系列方法

Attribute方法可以获取到属性节点的属性值

node.setAttribute(‘属性’,‘值’)

​ 功能:给当前元素节点新增属性和对应值

​ 返回值:无返回值

node.getAttribute(‘属性’)

​ 功能:获取当前元素节点下指定属性的值

​ 返回值:属性值(String)

node.removeAttribute(‘属性’)

​ 功能:删除当前元素的指定属性

​ 返回值:无返回值

node.hasAttribute(‘属性’)

​ 功能:判断当前元素是否有这个属性

​ 返回值:布尔值(true/false)

类名操作API

有两种操作类名class的方法: 自定义className方法 classList方法(H5提供的)

自定义className方法

实现原理:

  1. 调用一个自执行函数

  2. 在自执行函数内,声明一个对象ClassName,并创建两个方法addClass和remo

  3. 给两个方法赋值一个匿名函数,并给函数设置两个形参elm(元素)和name(操作的类名)

  4. addClass实现原理:

    1.进行判断,通过nodeType和typeof判断参数格式是否正确,且通过hasAttribute判断elm中是否有class这个属性节点

    2.如果格式正确且有class属性节点,通过setAttribut给class属性节点重新赋值成:原有的属性拼接上name的字符串

    3.如果条件不满足,通过setAttribut给classs属性节点赋值为name

  5. removeClass实现原理

    1.进行判断,通过nodeType和typeof判断参数格式是否正确,且通过hasAttribute判断elm中是否有class这个属性节点

    2.如果条件满足,通过getAttribute方法提取出class属性的属性值(string),并用spilt使用空格分割字符串并返回一个数组classList

    3.通过indexOf查找classList中是否有name这个值,通过index接受返回的索引值或 -1

    4.判断index是否大于0 ,如果大于0,证明class中有该name,使用splice将该值取下

    5.将该classList数组通过join使用空格拼接回字符串,通过setAttribute将该值设置给class属性节点

  6. 最后需要将className对象赋值给window对象,否则因为作用域无法在全局访问

实现代码:

(function(){
    var className={
        /**
         * 为传入的elm元素节点添加类名
         * @param {HTML DOM ELEMENT} elm 
         * @param {String} name 
         */
        addClass:function(elm,name){
            if(elm.nodeType==1&&typeof name=="string"&&elm.hasAttribute('class')){
                elm.setAttribute('class',elm.getAttribute('class')+' '+name);
            }else if(elm.nodeType==1&&typeof name=="string"){
                elm.setAttribute('class',name);
            }
        },

		 /**
         * 为传入的elm元素节点删除类名
         * @param {HTML DOM ELEMENT} elm 
         * @param {String} name 
         */
        removeClass:function(elm,name){
            if(elm.nodeType==1&&typeof name=="string"&&elm.hasAttribute('class')){
                var classList=elm.getAttribute('class');
                classList=classList.split(' ');
                var index=classList.indexOf(name);
                if(index>=0){
                    classList.splice(index,1);
                }
                classList=classList.join(' ');
                elm.setAttribute('class',classList);
            }
        }
    }
    window.className=className;
})();

classList方法(由H5提供)

HTML5提供了四种方法来操作类名

elm.classList.add(‘name’)

​ 功能:给elm的class属性添加name

elm.classList.remove(‘name’)

​ 功能:给elm的class属性删除name

elm.classList.replace(‘oldName’, ‘newName’)

​ 功能:将elm的class属性的oldName替换成newName

elm.classList.toggle(‘name’)

​ 功能:如果elm元素的class属性有name则删除name,如果没有name则添加name

获取CSS样式API

node.style.cssText

功能:访问当前元素的所有行内CSS样式

返回值:当前行内样式(String)

node.style.cssText.样式名

功能:访问到当前节点下行间的指定CSS样式

返回值:指定的行间Css样式值(String)

node.currentStyle[xxx] /.xxx

功能:访问到当前的实际显示样式

返回值:当前显示的指定Css样式值(String)

兼容:IE8及以下不支持

getComputedStyle(node)[xxx] / .xxx

功能:访问当前的实际显示样式

返回值:当前显示的指定的Css样式值(Strring)

兼容: IE9以上现代浏览器

跨浏览器的获取实际CSS样式兼容法

原理:利用三目运算符,如果浏览器有currentStyle,就为真,执行currentStyle,若为假,就执行getComputedStyle

function getStyle(node, cssStyle) {
    return node.currentStyle ? node.currentStyle(cssStyle) : getComputedStyle(node)[cssStyle];
}

HTML自定义属性

html5允许用户给元素进行属性的自定义

语法规范:

自定义的属性前缀必须为 data-

自定义属性的访问:

elementNode.dataset.属性名

例子:
<div data-age="18"></div>
div.dataset.属性名

HTML DOM

HTMLDOM 核心理念是将HTML标签 对象化。可以将每一个HTML标签看做是一个对象

标准DOM和HTML DOM的适用场景

标准DOM(核心DOM) 适用于 元素创建 修改 查询 节点操作 属性操作(无所不能)

HTML DOM 适用于 属性访问和修改

获取属性节点

语法:elementNode.属性名

功能: 快速获取属性节点

返回值:属性值(String)

HTML DOM的CSS属性

offsetWidth

功能:返回一个元素的布局宽度

offsetWidth

功能:返回一个元素的布局宽度

offsetTop

功能:返回距离其父元素的顶部内边距的距离

offsetLeft

功能:返回距离其父元素的左部内边距的距离

DOM操作实例

tabs选项卡切换

实现效果: 点击对应的元素选项卡,切换不同的内容区域

实现原理:

​ 页面设置:设置选项卡选中类名.actived 设置对应的内容显示样式.display(通过dispaly:none;)

  1. 通过querySelectAll获取到所有的选项卡按钮,并将该类数组使用Array.from转成数组

  2. 通过querySelect获取到所有的内容区域,并将该类数组使用Array.from转成数组

  3. 遍历所有选项卡按钮,为选项卡添加点击事件

  4. 通过this指向当前遍历到的选项卡按钮,使用classList.add为选项卡添加actived类名

  5. 选出被点击元素的兄弟元素,通过选项卡.filter(elm)返回elm不等于外部this(外部this指向遍历到的元素)的元素

  6. 通过forEach遍历选出的兄弟元素,并为其删除类名actived

  7. 通过内容数组[选项卡.indexOf(this)]使用classList.add为该内容元素添加display类名(原理:当选项卡被点击时,this指向该选项卡,选项卡数组.indexO获取到this的下标,内容数组[]使用该对应下标,获取到对应内容元素,为其添加类名)

  8. 选出被点击元素对应内容的兄弟元素,通过内容元素.filter(elm)返回elm不等于外部this(外部this指向遍历到的元素)的元素

  9. 通过forEach遍历选出对应内容的兄弟元素,并为其删除类名dispaly

    实现代码
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="./css/index.css">
        <script>
            window.onload = function() {
                var li = Array.from(document.querySelectorAll('.tabs>ul>li'));
                var div = Array.from(document.querySelectorAll('.tabs>div'));
    
                // 1.为被选择的li元素 添加点击事件
                for (var i = 0; i < li.length; i++) {
                    li[i].onclick = function() {
                        var that = this; // 保存this指向
                        // 给被点击的li元素添加类名
                        this.classList.add('actived');
    
                        // 选择出被点击元素的兄弟元素
                        var oLi = li.filter(function(el) {
                            // console.log(this); // 此处回调指向window
                            return el != that; // 使用外部的this环境进行判断
                        });
    
                        // 给被点击的li元素的兄弟元素删除类名
                        oLi.forEach(function(el) {
                            el.classList.remove('actived');
                        });
    
                        // 给被点击的li元素对应的div元素添加类名
                        div[li.indexOf(this)].classList.add('display');
    
                        // 选择div的兄弟元素
                        var oDiv = div.filter(function(elm) {
                            return elm != div[li.indexOf(that)];
                        });
    
                        oDiv.forEach(function(el) {
                            el.classList.remove('display');
                        })
    
                    }
                }
    
            }
        </script>
    </head>
    
    <body>
        <div class="tabs">
            <ul>
                <li>选项一</li>
                <li class="actived">选项二</li>
                <li>选项三</li>
            </ul>
            <div>
    
                内容一
            </div>
            <div class="display">
                内容二
            </div>
            <div>
                内容三
            </div>
        </div>
    </body>
    
    </html>
    

第十四章 事件

对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
每个事件在触发时 JS引擎会创建出一个对应的事件对象 event ,这个对象会被自动注入到 事件处理函数的第一个实际参数
注:ie8以及以下版本的浏览器中 event对象 不是DOM标准 而是BOM标准 获得event对象 需要写 全称

Event对象

事件处理

DOM事件处理有三种 : DOM0级事件处理 DOM2级事件处理 IE事件处理

DOM0级事件处理

DOM0级事件又称事件绑定,是指将一个事件处理函数赋值给一个事件源的事件类型,且一次只能绑定一个事件处理函数

注:解绑事件需将事件源的事件类型重新赋值为null

btn.onclick = function() {
    alert(123);
    btn.onclick = null; // 解绑事件 将事件处理属性赋值为null
}
DOM2级事件处理

DOM2级事件处理又称事件监听事件监听可以为一个事件添加多个事件处理函数,多个事件监听函数按照添加顺序依次执行

添加事件监听

语法: node.addEventListener(eventType,callback[,boolean=false]);

参数:

​ eventType(string) 事件类型 ‘click’ ‘input’ ‘mouseover’(不需要加on)

​ callback(function) 事件监听函数

​ bool 默认值false 冒泡执行(false)/捕获执行(true)

移除事件监听

语法: node.removeEventListener(eventType,fnName);

参数:

​ eventType(string) 事件类型**(不需要加on)**

​ fnName(function) 函数名/arguments.callee

arguments.callee:该属性是一个指针,指向拥有这个 arguments 对象的函数

应用:

场景:点击按钮后5秒内禁用该按钮

    btn.addEventListener('click', function() {
        // 禁用按钮
        this.setAttribute('disabled', 'true');

        var _this = this; // 保存this指向

        // 5秒后删除属性
        var sec = 5;
        var timer = setInterval(function() {

            if (sec == 0) {
            clearInterval(timer);
            _this.removeAttribute('disabled');
            _this.innerHTML = '按钮';
            return;
            }

            _this.innerHTML = '按钮' + sec + 's后可用';
            sec--;
        }, 1000);
    });
IE事件处理

IE事件处理适用于IE5-IE10

IE事件处理函数

**语法:**attachEvent(eventType, callback);

参数:

​ eventType(string) 事件类型**(需要加on)**

​ callback(function) 事件处理函数

IE事件移除函数

**语法:**detachEvent(eventType, fnName);

参数:

​ eventType(string) 事件类型**(需要加on)**

​ fnName(function) 函数名/arguments.callee

arguments.callee:该属性是一个指针,指向拥有这个 arguments 对象的函数

兼容事件处理

原理: 如果浏览器中有DOM2级事件处理函数,则使用二级事件处理函数,如果没有则使用IE事件处理函数

实现代码:

        function addEvent(elm, type, fn) {//事件添加函数
            if (typeof elm.addEventListener == 'function') {
                elm.addEventListener(type, fn);
            } else {
                elm.attachEvent('on' + type, fn);
            }
        }

        function removeEvent(elm, type, fn) {//事件删除函数
            if (typeof elm.removeEventListener == 'function') {
                elm.removeEventListener(type, fn);
            } else {
                elm.detachEvent('on' + type, fn);
            }
        }

        window.onload = function() {//使用方法
            var btn = document.getElementById('btn');

            addEvent(btn, 'click', function() {
                alert(1);
                removeEvent(btn, 'click', arguments.callee);
            });
        }

事件处理周期

事件处理周期(事件流)

三个阶段
  1. 事件捕获 从最不具体的事物到最具体的事物 事件沿DOM树向下传播

  2. 目标触发 运行事件绑定(监听)的函数

  3. 事件冒泡 从最具体的事物到最不具体事物 事件沿DOM树向上传播

    当一个元素接收到事件的时候 会把他接收到的事件传给自己的父级,一直到window 。(注意这里传递的仅仅是事件 并不传递所绑定的事件函数。所以如果父级没有绑定事件函数,就算传递了事件 也不会有什么表现 但事件确实传递了。

注意:

DOM0级事件 只能使用事件冒泡

低版本IE中 没有事件捕获阶段 只能使用事件冒泡

阻止事件冒泡/捕获

DOM标准

**语法:**event.stopPropagation()

IE浏览器

**语法:**event.cancelBubble = true;

兼容:

 ev = ev || event; // 兼容处理 阻止冒泡如果有ev就赋值给ev,如果没有ev就把event赋值给ev
event.stopPropagation ? ev.stopPropagation() : ev.cancelBubble=true;

事件委托

事件委托又称事件代理 将事件的处理函数添加给 父级或祖先级元素并通过事件冒泡的特性 判断事件的源 为目标添加事件

优点:

​ 1.可以为为未来元素添加事件

​ 2.优化DOM性能

使用方式

​ 常通过switch语句通过event.target.className来匹配对应的执行语句

鼠标事件和属性

事件类型

onclick 鼠标左键单击事件
ondbclick 鼠标左键双击事件
oncontectmenu 鼠标右键单击事件
onmousedown 鼠标按下事件
onmousemove 鼠标移动事件
onmouseup 鼠标弹起事件
鼠标事件属性

ev.button 鼠标按键类型(0、1、2 | IE下为 1、4 、2 )
ev.clientX、ev.clientY 根据浏览器可视区域的左上角计算坐标
ev.pageX、ev.pageY 根据页面的左上角计算坐标
ev.layerX、ev.layerY 根据页面的左上角计算坐标(FF方法,只支持FireFox)
ev.screenX、ev.screenY 根据显示器左上角计算坐标
ev.offsetX、ev.offsetY 根据元素左上角计算坐标

键盘事件和属性

事件类型

keydown 键盘按下事件
keyup 键盘弹起事件
oninput 键盘输入事件

输入事件可以通过this.value获取到输入的完整字符串

键盘事件属性

ev.keyCode、ev.which 获取按键的ASCII编码
ev.key、ev.data 获取按下的键盘字符
ev.altKey 是否按下alt键(true/false)
ev.shiftKey 是否按下shift键(true/false)
ev.ctrlKey 是否按下ctrl键(true/false)
ev.key、ev.data 获取按下的键盘字符
常见键盘ASCII码值

enter 13

ctrl 17

空格 32

滚轮事件

事件类型

mousewheel 滚轮滚动事件(chrome/ie)
DOMMouseScroll 滚轮滚动事件 (firefox)
滚轮事件属性

ev.wheelDelta 滚轮方向

正值为向上滚动 负值为向下滚动 (兼容IE Chrome)

ev.detail 滚动方向

正值为向下滚动 负值为向上滚动 (兼容IE Chrome)

滚轮事件兼容方法
function mouseScroll(ev) {
    ev = ev || event;
    var flag = true; // 表示滚动方向
    if (ev.wheelDelta) {
        flag = ev.wheelDelta > 0 ? true : false;
    } else {
        flag = ev.detail < 0 ? true : false;
    }
    return flag;
}

阻止事件默认行为

ev.preventDefault() 标准方法
ev.returnValue = false IE兼容
兼容方法
	ev = ev || event;
    if (ev.preventDefault) {
        ev.preventDefault();
    } else {
        ev.returnValue = false; 
	}

第十五章 正则表达式

简介

定义

RegExp是一种中立于语言和平台的 用于描述特定字符格式的表达式,它属于EMCAScript的内置对象,为引用类型数据

组成

由普通字符(例如字符a~z)以及特殊字符(称为元字符)组成

普通字符:除了元字符外所有可打印和不可打印字符。包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号

特殊字符:// . \ / * ? + ( ) [ ] { } ^ | $ ( 特殊字符如想使用原意需要使用 \ 进行转义才能使用)

作用

格式验证 文本匹配 文本替换 文本查找 等

创建方式

构造函数创建

语法: var reg = new RegExp(string[, attr]);

参数: string 用于描述字符规则的字符串

    attr  正则表达式的修饰符
字面量创建

语法: var reg=/string[, attr]/;

参数: string 用于描述字符规则的字符串

    attr  正则表达式的修饰符

语法规范

正则表达式中 有一些特殊字符拥有特殊含义 不能直接使用 需要使用 \ 进行转义才能使用

// . \ / * ? + ( ) [ ] { } ^ | $

语法检测函数

RegExp.prototype.test()

语法: reg.test(string)

功能: test方法用于检测字符串string是否符合reg正则表达式的规则

返回值: 布尔值

修饰符

global 属性 全局匹配字符串 修饰符 g

gnorecase 属性 忽略大小写 修饰符 i

字符集

在正则表达式中 字符集 使用 [ ] 中括号 表示

字符集表示的是一个范围内的单个字符

在字符集中 出现 ^ 表示 非

字符集功能
[abc]表示匹配abc中的任意字符
[abc] [ab]表示匹配两字符 第一个是abc中任意一个 第二个是ab中任意一个
[^abc]表示匹配非abc中的任意一个
[0-9]表示匹配一个数字
[^0-3]表示匹配非0-3的其他字符
[a-z]表示匹配一个小写字母
[A-Z]表示匹配一个大写字母
[A-Za-z0-9]表示匹配大写小写字母和数字
[A-z]表示匹配数字大小写字母和([] \ _ ^ `)
[A-Za-z0-9_ ]表示数字大小写字母和下划线

预定义字符集

预先设置好的字符集 字符集表示单个字符

预定义字符集功能
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束

数量匹配

数量匹配功能
*表示匹配字符重复 0次或多次
+表示匹配字符重复 1次或多次
表示匹配字符重复0次或1次
{x}表示匹配字符 x 次
{x,}表示匹配字符至少x次或更多次
{n,m}表示匹配字符重复n次到m次

匹配边界

^ 表示匹配边界开始

$ 表示匹配边界结束

\b 表示匹配单词边界

条件匹配

?=x 匹配其后紧跟x的字符串

?!x 匹配其后没有紧跟x的字符串

      var str = 'Jamesharden';

      var reg=/James(?=harden|13)/
      console.log(reg.test(str));//返回布尔值
      console.log(str.match(reg));//匹配到的其实是前面的字符串

选择和分组

| 表示选择 相当于JS中的逻辑或(||)

() 表示分组 一个小括号会被看做是一个整体 正则表达式会为每一个分组进行自动编号

字符串API

String.prorotype.match()

语法: str.match(regexp)

参数: regexp 正则表达式 用于匹配字符串的正则表达式

描述: 在str中匹配与正则规则相符的字符串 将符合的结果放入一个数组

返回值: array

String.prototype.search()

语法: str.search(regexp)

参数: 用于在字符串str中进行检索匹配的正则表达式

描述: search方法用于在str中查找与正则匹配的字符串内容 并返回第一个符合条件的字符索引

返回值: 索引 或 -1

String.prorotype.replace()

语法: str.replace(regexp,string);

描述: 用于在str中通过正则匹配字符串 将其替换成新给定的字符串

返回值: 返回一个替换后的新字符串

​ 不修改原有字符串

常用正则表达式

身份证验证:/^\d{6}((19)|(20))\d{2}((0[1-9])|(1[0-2]))((0[1-9])|(1\d)|(2\d)|3[01])\d{3}[\dxX]$/

手机号验证:/1[3-9]\d{9}/

第十六章 ES5

新增严格模式

严格模式:写在哪个作用域顶部,就在哪个作用域生效

语法: "use strict”;
**注意:**尽量不要把严格模式写在全局(否则全局包括引入的js文件也会进入严格模式)

严格模式使用规范:

       1. 使用严格模式时 顶部不允许有任何JS代码
       2. 数中this无法指向全局对象
       3. 函数内不允许重名的参数
       4. 模式下禁用 arguments.callee
       5. 严格模式下 任何以eval的命名都被禁止

严格模式目的:

- 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

​ - 消除代码运行的一些不安全之处,保证代码运行的安全;

​ - 提高编译器效率,增加运行速度;

​ -为未来新版本的Javascript做好铺垫

Function.prototype.bind()

语法: fn.bind(thisObj[arg1,…argN]);

参数: thisObj 对象 函数中this指向的对象

​ arg 函数中的实际参数

返回值: 一个新函数

描述: 为函数修改this指向 让其this指向thisObj 然后返回一个新函数

​ 为函数绑定实际参数

第十七章 ES6

Let和const

let 和 const 是 ES6(ES2015)新增的两个关键字

let声明

let关键字用于声明块级作用域变量 (块级作用域指当前大括号内有效)

**特性:**1. letconst 声明的变量 不会绑定在window

​ 2. let 和 const 没有声明提前 必须先声明后使用

const声明

const关键字于声明块级作用域变量(只能赋值一次)

**特性:**1.如果声明的变量是值类型,值无法修改

​ 2. 如果声明的变量是引用类型,则可以修改属性,但不可以修改引用

解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构

定义:解构赋值是左右相等的一种匹配模式进行赋值

结构赋值规则:

​ 1. 如果赋值符左右两边的结构相同 ,结构将自动拆解 对应赋值

​ 2. 如果赋值符左右两边的结构不同,且没有拿到对应值,则结构失败返回undefined

​ 3.若使用展开运算符,没有获取到对应的值,则该值会返回一个空数组

​ 4.对象的解构 需要变量名与对象的属性名相同 才能正确解构

​ 5.字符串的解构 需要变量名与对象的属性名相同 才能正确解构

模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

特性:

​ 1. 模板字符串保留字符串的书写格式 类似于 html标签

 

​ 2. 允许字符串换行

3. 拼接变量更加便利 使用固有符号 ${}

Symbol类型

ECMAScript 6 新增了一种数据类型 Symbol 它是ES中第六种 基本类型

创建方式:

使用Symbol() 函数进行创建

语法创建:   let umame=Symobl('username')
语法赋值:   obj[uname] = 'lisi';		
注意点:
		**Symbol 没有构造函数** 不能使用new来进行创建
作用:

​ 用于解决对象属性名冲突问题

	Symbol是一个独一无二的值
注意:

​ symbol不能使用点操作符,需使用[属性名]

箭头函数

箭头函数是ES6提供的一种函数语法糖,用于简化函数的语法

基本语法
 ()=>{}     //小括号代表参数 大括号代表函数语句
简化方法:

​ 1.当函数形参只有一个时,可以省略小括号

​ 2.当函数语句只有一条且为返回值时,可以省略大括号和return关键字

​ 3.当函数语句只有一条且为返回值时,可以省略大括号和return关键字

  1. 如果箭头函数需要返回一个对象时,必须在对象外加上大括号
应用场景:

​ 1.匿名函数

​ 2.回调函数

不适用场景:
  1. 事件处理函数(可以使用,但是this指向有问题)

​ 2. 构造函数(箭头函数不能作为构造函数使用)

​ 3. Generator函数(箭头函数不能作为Generator函数)

使用注意点(重要):

箭头函数中的this指向的是定义对象时的所处环境 运行时无法改变this指向

​ ( 1) 函数体内的this对象, 就是定义时所在的对象, 而不是使用时所在的对象。

​ ( 2) 不可以当作构造函数, 也就是说, 不可以使用new命令, 否则会抛出一个错误。

​ ( 3) 不可以使用arguments对象, 该对象在函数体内不存在。 如果要用, 可以用 rest 参数代替。

​ ( 4) 不可以使用yield命令, 因此箭头函数不能用作 Generator 函数。

Set结构

Set是es6新增的数据结构

它是一种类似于数组的有序数据结构

不同于数组的是 它的数据成员是唯一的(不存在重复的值)

创建方式:

​ 使用Set构造函数创建

let set = new Set([15, 32, 15, 33, 31, 32, 1, 15]);
Set的API:
Set.prototype.add()

​ 向Set结构中添加元素 将元素添加到Set的结尾处

​ 如果Set中已存在该元素 则默认忽略

​ 返回值: set对象(链式调用)

Set.prototype.size

​ 返回Set结构的长度 set没有length属性

Set.prototype.delete(value)

​ 删除Set中的指定元素

​ 返回值:布尔值 表示是否删除成功

Set.prototype.has(value)

​ 判断set中是否有指定的值

​ 返回值: 布尔值

Set.prototype.clear()

​ 删除所有元素 清空set

Map结构

Map 也是 ES6新增的数据结构(哈希(hash)结构)

定义:

Map是一种 值对应值的 哈希结构

​ Map的key 可以是任意数据类型

​ Map的本质是 值值对

创建方式:

​ 使用 Map的构造函数来创建Map

      let map = new Map();
Map的API:
Map.prototype.set(key,value)

​ 为map设置键值对

Map.prototype.get(key);

​ 通过key获得value

Map.prototype.has(key);

​ 判断key是否在map中存在

Map.prototype.delete(key);

​ 通过key删除一个键值对

Map.prototype.clear()

​ 清空map

Map优点

​ 对象提供的是 字符串和值的对应

​ Map提供的是 值和值的对应

​ Map是一种更完善的哈希结构

​ Map的key可以使用任意类型

for-of 遍历

for-of 是es6新增的一种遍历语法

遍历器(Iterator)

​ 它是一种接口,为各种不同的数据结构提供统一的访问机制。

​ 任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

​ Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;

​ 二是使得数据结构的成员能够按某种次序排列;

​ 三是 ES6 创造了一种新的遍历命令for…of循环, Iterator 接口主要供for…of消费。

原生 Iterator 接口的数据结构

​ Array

​ Map

​ Set

​ String

​ TypedArray

​ 函数的 arguments 对象

​ NodeList 对象

for-in和for-of 相同点

​ for-in 和 for-of 都可以遍历数组

​ for-in 和 for-of 都不能遍历 不可枚举属性

for-in和for-of 不同点

​ for-in遍历 key

​ for-of遍历 value

Generator 函数

ES6新增的一种遍历器对象

​ 从语法来看它是一种函数的表达式形式

​ 它的作用是解决异步编程

​ 让异步代码 同步化执行

​ 它一般不会单独使用

​ 配合 co.js(nodejs) 使用 co.js是一个自执行器

​ 在函数名和关键字function中间有一个 *

​ Generator函数中配合关键字 yield 使用

​ yield(生成,产出)

​ yield 关键字允许在 Generator中多次出现

RegExp.prototype.exec()

​ 语法: reg.exec(string);

​ 描述: exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。

​ 雷同:str.match(reg);

第十八章 DOM运动

第十九章 面向对象编程

OOP Object Oriented Programming

AJAX 局部刷新

XMLHTTPREQUEST对象

open( method, URL ,async)

建立与服务器连接 asyncs为布尔值,代表是否同步执行

send(content)

向服务器发送请求

onreadystatechange 事件

执行响应任务( readyState 改变时,就会触发 onreadystatechange事件)

readystate :XHR的状态信息

​ 0 XHR对象没有完成初始化

​ 1 XHR对象开始发送请求

​ 2 XHR对象请求发送完成

​ 3 XHR对象开始读取响应,但未结束

​ 4 XHR对象响应结束

states: HTTP的状态码

​ 200 服务器响应正常

​ 400 无法找到请求的资源

​ 403 没有访问权限

​ 404 访问的资源不存在

​ 500 服务器内部错误

responseText 获得响应的文本内容

responseXML: 获得响应的XML对象(已弃用)

注意:当就绪状态是4且状态码是200时才能处理数据

使用AJAX发送get请求

此题经常作为面试题

发送步骤

​ 1.获取Ajax对象: 获得XHR对象的实例

​ 2.使用open方法建立连接(get数据在此传递)

​ 3.使用send方法 发送请求

​ 4.设置回调事件 onreadyststechange

使用AJAX发送post请求

​ 1.获取Ajax对象: 获得XHR对象的实例

​ 2.使用open方法建立连接

​ 3.使用setRequestHeader方法设置请求头(请求类型)

​ 3.使用send方法发送请求 (post数据在此传递)

​ 4.设置回调事件 onreadyststechange

注意: PHP使用file_get_contents(‘php://input’)接受json数据

​ $data=file_get_contents(‘php://input’);//接受json数据

o b j = j s o n d e c o d e ( obj=json_decode( obj=jsondecode(data);//将json字符串转为php对象

同源策略和跨域解决方案

相同源头安全策略: 同源策略是浏览器提供的一种安全策略(协议)

用于保护数据的请求安全

核心思想:

​ 一个页面无法访问跨源数据(不能访问别人网站的数据)

​ 同源策略保证的是数据来自相同源头

Ajax是遵循同源策略

满足同源的3个条件
 		1. 相同的地址(ip/域名)
           		2. 相同的协议  (http://    https://)
                     		3. 相同的端口  (80   443)
CROS 跨域错误
跨源(跨域)数据访问三种解决方案

通常访问其他服务器数据时,有三种解决方案

  1. JSONP (前端实现跨域,需要后端接口配合)
  2. XHR2(CORS) 需要后端开放请求权限 设置请求头信息
  3. 反向代理 使用WEB服务器代理请求地址(使用最多)

JSONP

JSONP是一种社区的跨域解决方案 (和JSON没有任何关系)

JSONP是利用某些浏览器可以跨域的元素来实现的(img/iframe/script) 常用script

SRC属性

​ src属性可以跨源访问数据,不受同源策略的影响

发送请求的方式

在html页面中引入的所有的外部资源,都是使用的http的get请求

from location.href Ajax

设计模式

一、设计模式的分类
总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下:

面向对象设计七大原则

  1. 单一职责原则(Single Responsibility Principle)

每一个类应该专注于做一件事情。

  1. 里氏替换原则(Liskov Substitution Principle)

超类存在的地方,子类是可以替换的。

  1. 依赖倒置原则(Dependence Inversion Principle)

实现尽量依赖抽象,不依赖具体实现。

  1. 接口隔离原则(Interface Segregation Principle)

应当为客户端提供尽可能小的单独的接口,而不是提供大的总的接口。

  1. 迪米特法则(Law Of Demeter)

又叫最少知识原则,一个软件实体应当尽可能少的与其他实体发生相互作用。

  1. 开闭原则(Open Close Principle)

面向扩展开放,面向修改关闭。

  1. 组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP)

尽量使用合成/聚合达到复用,尽量少用继承。原则: 一个类中有另一个类的对象。

细则
单一职责原则(Single Responsibility Principle)

因为:

可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;提高类的可读性,提高系统的可维护性;变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。需要说明的一点是单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则。

所以:

从大局上看Android中的Paint和Canvas等类都遵守单一职责原则,Paint和Canvas各司其职。

里氏替换原则(Liskov Substitution Principle)

因为:

里氏替换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。里氏替换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。

所以:

使用里氏替换原则时需要注意,子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法。尽量把父类设计为抽象类或者接口,让子类继承父类或实现父接口,并实现在父类中声明的方法,运行时,子类实例替换父类实例,我们可以很方便地扩展系统的功能,同时无须修改原有子类的代码,增加新的功能可以通过增加一个新的子类来实现。

从大局看Java的多态就属于这个原则。

依赖倒置原则(Dependence Inversion Principle)

因为:

具体依赖抽象,上层依赖下层。假设B是较A低的模块,但B需要使用到A的功能,这个时候,B不应当直接使用A中的具体类;而应当由B定义一抽象接口,并由A来实现这个抽象接口,B只使用这个抽象接口;这样就达到了依赖倒置的目的,B也解除了对A的依赖,反过来是A依赖于B定义的抽象接口。通过上层模块难以避免依赖下层模块,假如B也直接依赖A的实现,那么就可能造成循环依赖。

所以:

采用依赖倒置原则可以减少类间的耦合性,提高系统的稳定性,减少并行开发引起的风险,提高代码的可读性和可维护性。

从大局看Java的多态就属于这个原则。

接口隔离原则(Interface Segregation Principle)

因为:

提供尽可能小的单独接口,而不要提供大的总接口。暴露行为让后面的实现类知道的越少越好。譬如类ProgramMonkey通过接口CodeInterface依赖类CodeC,类ProgramMaster通过接口CodeInterface依赖类CodeAndroid,如果接口CodeInterface对于类ProgramMonkey和类CodeC来说不是最小接口,则类CodeC和类CodeAndroid必须去实现他们不需要的方法。将臃肿的接口CodeInterface拆分为独立的几个接口,类ProgramMonkey和类ProgramMaster分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。

所以:

建立单一接口,不要建立庞大的接口,尽量细化接口,接口中的方法尽量少。也就是要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。依赖几个专用的接口要比依赖一个综合的接口更灵活。接口是设计时对外部设定的约定,通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性。

从大局来说Java的接口可以实现多继承就是接口隔离原则的基础保障。

迪米特法则(Law Of Demeter)

因为:

类与类之间的关系越密切,耦合度也就越来越大,只有尽量降低类与类之间的耦合才符合设计模式;对于被依赖的类来说,无论逻辑多复杂都要尽量封装在类的内部;每个对象都会与其他对象有耦合关系,我们称出现成员变量、方法参数、方法返回值中的类为直接的耦合依赖,而出现在局部变量中的类则不是直接耦合依赖,也就是说,不是直接耦合依赖的类最好不要作为局部变量的形式出现在类的内部。

所以:

一个对象对另一个对象知道的越少越好,即一个软件实体应当尽可能少的与其他实体发生相互作用,在一个类里能少用多少其他类就少用多少,尤其是局部变量的依赖类,能省略尽量省略。同时如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一方法的话,可以通过第三者转发这个调用。

从大局来说Android App开发中的多Fragment与依赖的Activity间交互通信遵守了这一法则。

开闭原则(Open Close Principle)

因为:

开放封闭原则主要体现在对扩展开放、对修改封闭,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。软件需求总是变化的,世界上没有一个软件的是不变的,因此对软件设计人员来说,必须在不需要对原有系统进行修改的情况下,实现灵活的系统扩展。

所以:

可以通过Template Method模式和Strategy模式进行重构,实现对修改封闭,对扩展开放的设计思路。
封装变化,是实现开放封闭原则的重要手段,对于经常发生变化的状态,一般将其封装为一个抽象,拒绝滥用抽象,只将经常变化的部分进行抽象。

组合/聚合复用原则(Composite/Aggregate Reuse Principle CARP)

因为:

其实整个设计模式就是在讲如何类与类之间的组合/聚合。在一个新的对象里面通过关联关系(包括组合关系和聚合关系)使用一些已有的对象,使之成为新对象的一部分,新对象通过委派调用已有对象的方法达到复用其已有功能的目的。也就是,要尽量使用类的合成复用,尽量不要使用继承。

如果为了复用,便使用继承的方式将两个不相干的类联系在一起,违反里氏代换原则,哪是生搬硬套,忽略了继承了缺点。继承复用破坏数据封装性,将基类的实现细节全部暴露给了派生类,基类的内部细节常常对派生类是透明的,白箱复用;虽然简单,但不安全,不能在程序的运行过程中随便改变;基类的实现发生了改变,派生类的实现也不得不改变;从基类继承而来的派生类是静态的,不可能在运行时间内发生改变,因此没有足够的灵活性。

所以:

组合/聚合复用原则可以使系统更加灵活,类与类之间的耦合度降低,一个类的变化对其他类造成的影响相对较少,因此一般首选使用组合/聚合来实现复用;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。

this指向

this 关键字 在JS中是一个动态的指针

它的指向由调用决定 不由定义决定

在浏览器环境中的this指向

​ this 出现在 普通函数中 调用该函数的对象

​ 构造函数中 新实例对象

​ 全局函数中 window

​ 事件函数中 事件绑定对象

​ 原型函数中 调用函数的对象

​ 自执行函数 window

​ 计时器函数 window

​ 严格模式下 不指向window

​ 箭头函数中 父级环境对象(固定指向 无法改变)

修改this指向的方法

​ Function.prototype.bind();

​ Function.prototype.call();

​ Function.prototype.apply();

箭头函数

​ 不能作为构造函数

​ 不推荐作为事件处理函数

​ 没有arguments

​ 不能作为Generator函数

jQuery

简介

JQuery的发布更新维护依赖于GitHub平台

历史版本

  • 1.x 可以兼容低版本浏览器 ie6停止更新维护状态 最终版本 1.12
  • 2.x 抛弃了兼容性代码,文件体积小,停止更新 ie9+ 最终版本 2.2
  • 3.x ie9+ es6支持

版本更新10多年 ,但核心函数不变 语法不变

核心思想

写的少,做的多

jQuery主要封装的内容是DOM操作

工厂函数

jQuery的工厂函数用于创建jQuery对象

工厂函数名就是 jQuery 也可以用 $

  console.log(jQuery);
  console.log($);
  console.log($ === jQuery);
jQuery就绪事件

**它采用了HTML5的就绪事件 DOMContentLoaded **

// 语法:
$(document).ready(function(){

});

//简写:
$(function(){
    
});

和Window.onload区别

jQuery的就绪事件可以添加多个,window.onload则不能添加多个

工厂函数的基本语法与作用
基本语法:
 $(selector[,context]).action();

	//selector 选择器(string)

	//context 上下文(dom/jQuery)

	//$(选择器).动作();

作用
  1. 构建jQuery对象 选择器选择到的所有元素 类数组对象(jQuery对象)

  2. 构建jQuery对象 可以将一个DOM对象或类数组对象 包装成jQuery对象

  3. 将数组构建成jQuery对象

jQuery选择器

jQuery支持所有css和c3选择器,还进行了扩展,使用第三方库 Sizzle.js 库

基本语法 $(selector).action()

基本筛选器

  • :first 获取第一个元素
  • :not(selector) 去除所有与给定选择器匹配的元素
  • :even 匹配所有索引值为偶数的元素
  • :odd 匹配所有索引值为奇数的元素
  • :eq(index) 匹配一个给定索引值的元素
  • :gt(index) 匹配所有大于给定索引值的元素
  • :lt(index) 匹配所有小于于给定索引值的元素
  • :lang(语言) 匹配指定语言的所有元素
  • :header 匹配所有的标题标签
  • :animated 匹配所有真正执行动画效果的元素
  • :focus 匹配获得焦点的所有元素
  • :root 匹配根元素(html)
  • :target 匹配id属性值等于当前文档URI的锚点名称的元素

内容选择器

  • :contains(text) 匹配包含给定文本的元素
  • :has(selector) 匹配含有选择器所匹配的元素的元素
  • :empty 匹配所有为空的元素
  • :parent 匹配含有子元素或者文本的元素

jQuery事件

事件委托

指将元素事件委托给父祖先元素,通过事件冒泡原理,实现给未来元素添加事件

实现方式 1 :jQuery 1.x 版本

$(selector).delegate(selector,eventType,callback)
// 参数:selector 选择器   eventype 事件类型   callback 事件处理函数

实现方式2 :on() 实现事件委托

// 语法1 单事件
$(select).on(eventType, 触发目标,callback);
// 语法2 多事件
$(select).on({
    {eventType:callback},
    {eventType:callback},
} 触发目标);

常用事件

hover([over,]out) 鼠标移入移出事件
//语法
$(selector).hover(function(ev){
    //mouseover (鼠标移入)
    //事件处理函数
},function(ev){
    //mouseleave(鼠标移出)
    //事件处理函数
})
off(eventype,fn)移除事件
//语法
$(selector).off()  //不写参数移除所有事件
$(selector).off(eventype)  //移除某一类事件
$(selector).off(eventype,fn)  //移除指定事件处理函数的事件

one(eventype,fn) 绑定一次性事件
//语法
$(selector).one(eventype,fn)
trigger(eventype) 触发其他元素事件
//语法
$(selector).trigger(eventype)

jQuery属性操作

attr(name) 获得第一个被选元素的属性值
//语法
$(selector).attr(name);
// 获得第一个被选元素的属性值
attr(name,value) 为所有被选择元素设置或修改属性值
//语法
$(selector).attr(name,value);
// 获得第一个被选元素的属性值
attr(options) 为所有被选元素设置多个属性值
//语法
$(selector).attr({
    // 属性键值对
    'name1' : 'value1',
    'name2' : 'value2'...
});
// 为所有被选元素设置多个属性值
removeAttr(name) 为所有被选择的元素删除属性
//语法
$(selector).removeAttr(name)
//为所有被选择的元素删除指定属性
注:attr() 函数 无法获得不可见属性 ,获得不可见属性 使用 prop() 语法同attr
案例:全选按钮
 $('input:checkbox:first').on('click', function() {
 	$('input:checkbox:not(:first)').prop('checked', $(this).prop('checked'));
    //this指向第一个按钮
    // $(this).prop('checked')获取到第一个按钮的checkbox的值
 });

jQuery类名操作

addClass(class|fn) 添加类名
// 语法1:
$(selector).addClass(类名)
// 为被选所有元素添加类名 多个类名用空格隔开

// 语法2:
$(selector).addClass(function(index,class){
    return class
    // 一般返回当前类加当前元素索引值
    // return class+index
})
removeClass() 移除类名
//语法
$(selector).removeClass(class)
//为所有被选元素删除类名
toggleClass 切换类名
//语法
$(selector).toggleClass(class)
//为所有被选元素切换类名 有该类名就删除 没有则添加

jQuery内容操作

html() 获得第一个被选元素的html内容
//语法
$(selector).html()
// 获得第一个被选元素的html内容
html(value|fn) 为所有被选择的元素设置或修改html内容(识别标签)
//语法1
$(selector).html(value)
// 为所有被选择的元素设置或修改html内容

//语法2
$(selector).html(function(index,value){
    return value + 添加内容;
})
//为所有被选择的元素在现有内容上添加内容

// 可解析标签
text() 获取到所有被选元素的文本内容
//语法
$(selector).text()
text(value|fn) 为所有被选元素设置文本内容(不识别标签)
//语法1
$(selector).text(value)
// 为所有被选择的元素设置或修改文本内容

//语法2
$(selector).text(function(index,value){
    return value + 添加内容;
})
//为所有被选择的元素在现有内容上添加内容

// 不可解析标签
val() 获取到第一个被选元素的value值(用于表单元素)
//语法
$(selector).val()
val(value|fn) 为所有被选元素设置value值(用于表单元素)
//语法1
$(selector).val(value)
// 为所有被选元素设置value值

//语法2
$(selector).val(function(index,value){
    return value + 添加内容;
})
//为所有被选元素设置value值

NodeJS

​ 应用程序 参数1 参数2…

NVM命令

$ nvm ls 		      #查看当前计算器安装过的nodejs列表
$ nvm install 版本号   #根据给定版本安装版本号
$ nvm use 版本号       #使用指定版本号的nodejs
$ nvm uninstall 版本号 #卸载已经安装过的版本

REPL测试环境

用于简易测试 Read Eval Print Loop 可以在终端直接写代码类似于控制台

$ node    #进入REPL测试环境
$ .exit   #推出REPL测试环境

终端命令

终端命令 后跟随的内容是 参数 每个参数使用空格隔开(本质上是应用程序)

$ pwd      # 查看当前绝对路径
$ cd       # 改变目录(进入)
$ ls       # 查看目录
$ ls -l    # 以列表形式查看目录
$ ls -a    # 查看全部目录内容(包含隐藏信息)
$ ls -la   # 以列表形式查看全部目录内容(包含隐藏信息)

路径和隐藏文件

相对路径

./ 从当前目录开始计算路径

绝对路径

windows操作系统中 绝对路径从盘符开始表示
c:/
d:/
e:/

类Unix操作系统(Unix Linux OSX) 中 绝对路径从根目录开始计算(没有盘符概念)

/ 表示根目录
~ 表示用户目录(home目录)

隐藏文件

类Unix操作系统中 隐藏文件/目录 是以点开头的 例如 .git
类Unix操作系统没有文件后缀概念(文件后缀由windows提出)

node 全局对象

global 对象
process 对象
process.argv属性

argv属性返回进程启动时的命令行参数的数组

第一个元素为 node程序

第二个元素为 当前执行文件的路径

剩余 元素为 额外的命令行参数

node 全局变量

__dirname 当前执行的目录名
	console.log(__dirname);   // 当前目录名 绝对路径
__filename 当前执行的文件名
	console.log(__filename);  // 当前文件名 绝对路径

node 回调函数

在nodejs中 所有的异步操作都是由回调函数完成的

nodejs的回调函数 是错误优先的

所有的回调函数 第一个参数都是 错误对象

// 判断奇偶数
function isOdd(num,callback) {
    if(typeof num !='number'){
        //如果参数错误 则调用回调函数并传入一个error对象
        callback(new Error('传入的不是数字'))
    } 
    if(num % 2){
        callback(null,'是基数');
    }else{
        callback(null,'是偶数')
    }
}

isOdd('5',function (err,reslut) { //回调函数的第一个参数必须是错误对象
    if(err) throw err;//错误处理放在最前
    console.log(reslut);
})

node 模块化规范

nodejs 采用的是模块化设计 采用 common.js 模块化规范

common.js规范特点

每个模块都拥有独立的作用域 代码在各自的模块中执行 不会照成全局污染
每个模块都是一个独立的文件
模块允许多次加载 但是只有在第一次加载时会执行一次
运行的结果会被缓存 如果再次加载 则从缓存中获得结果
模块加载顺序和代码书写顺序有关

模块使用

1.内置模块

2.自定义模块

3.第三方模块

模块导出和导入
module.export={导出内容}  // 模块导出 (模块导出的是一个对象)

require(模块路径)		  // 模块导入 (导入自定义模块使用相对路径)

**注:**模块也可以导出Class类

path模块

path模块是内置模块,提供了一些实用工具,用于处理文件和目录的路径

//模块导入方式
const path = require('path');
path.join()

​ **作用:**拼接路径

语法: path.join(路径片段1,路径片段2…)

​ **返回值:**String

​ **注意:**会智能补齐斜杠或识别斜杠,…代表返回上一级

path.extname(path)

​ **作用:**获得文件后缀

语法: path.extname(path)

​ **返回值:**String

path.dirname(path)

​ **作用:**获得文件路径名(不包括文件)

语法: path.dirname(path)

​ **返回值:**String

path.basename(path[,ext])

​ **作用:**用于获得文件名

​ **语法: ** path.basename(path[,ext])

​ **参数: ** ext代表去除指定后缀名

​ **返回值:**String

fs模块

filesystem文件系统模块是内置模块 用于进行文件系统的操作

//模块导入方式
const fs = require('fs');
fs.readFile(path [,opations] , callback)

​ **作用:**读取文件

语法: fs.readFile(path [,opations] , function(err,data){})

参数: path 文件路径

​ opations 字符集utf8

​ callback 回调函数(两个参数为err 和 data)

​ **注意:**为异步操作

fs.readFileSync(path [,opations] , callback)

​ **作用:**读取文件

语法: fs.readFile(path [,opations] , function(err,data){})

参数: path 文件路径

​ opations 字符集utf8

​ callback 回调函数(两个参数为err 和 data)

​ **注意:**为同步

querystring模块

querystring.parse(str[, sep[, eq[, options]]])

​ **作用:**将query字符串转成query对象

语法: querystring.parse(str[, sep[, eq[, options]]])

参数: sep 分隔符

​ eq 键值对连接符

querystring.stringify(obj[, sep[, eq[, options]]])

​ **作用:**将query对象转成query字符串

语法: querystring.parse(str[, sep[, eq[, options]]])

参数: sep 分隔符

​ eq 键值对连接符

Call和apply和bind

call和apply用于修改函数中的this指向并立即调用函数

call 用于修改函数的this指向并立即调用

​ 函数的参数已原有的顺序依次传入

apply 用于修改函数的this指向并立即调用函数

​ 函数的参数已数组或类数组的形式传入

闭包

闭包是JavaScript特有的一种函数嵌套结构

具体的行为表现为 在一个较大范围的作用域中可以访问较小范围作用域的变量

行成闭包有三个必要条件

  1. 函数嵌套(至少有两个函数)
  2. 内层函数中使用了外层函数的变量或参数
  3. 内层函数作为返回值返回到外部

闭包的作用

  1. 用于保护具有共享意义的变量
  2. 隔离作用域 避免(全局)作用域污染
  3. 为变量提供访问和操作的相关接口

闭包的缺点

  1. 概念复杂 不易理解

  2. 占用过多的资源(内存) 大量使用不利于代码优化

    目前推荐使用模块化开发代替闭包

高频事件优化

函数节流

​ 核心思想 让每一次的函数触发都一个固定的时间间隔

​ https://www.rootbk.cn/?p=93

   <script>
        window.onload = function() {

            // 函数节流
            // 核心思想 让每一次的函数触发都一个固定的时间间隔

            // https://www.rootbk.cn/?p=93

            // 想要有时间间隔就需要知道上一次执行的时间

            function thottle(callback, delay) {
                let prev = 0; // 用于记录上次的执行时间

                return function() {
                    let now = Date.now(); // 获得当前时间

                    if (now - prev >= delay) {
                        callback.apply(this, arguments); // 调用回调函数
                        prev = now; // 更新上一次的执行时间
                    }
                }
            }


            let box = document.querySelector('#box');

            let count = 0;


            box.addEventListener('mousemove', thottle(function(ev) {
                // count++;
                // console.log(count);
                console.log(this);
                console.log(ev);
            }, 1000));
        }
    </script>
</head>

<body>
    <div id="box"></div>
</body>

​ 想要有时间间隔就需要知道上一次执行的时间

函数防抖

​ https://www.rootbk.cn/?p=134

   <script>
        window.onload = function() {
            // 函数防抖

            // https://www.rootbk.cn/?p=134

            // 联想查询
            // 计算机无法判断用户输入的内容是否输入完成 没有办法判断用输入的单词或句子是否完整
            // 如果每次输入1个字符都进行查询 是没有意义的 因为最后一次用户输入结束才是用户想要的东西

            // 核心思想 在N秒中 只执行一次事件处理函数
            // 如果在N秒内 再次触发该事件则从新计时


            function debounce(callback, delay) {
                let timer = null; // 存储计时器id
                return function() {
                    let arg = arguments;

                    if (timer) { // 如果有开启计时器
                        clearTimeout(timer); // 关闭计时器
                    }
                    timer = setTimeout(function() {
                        callback.apply(this, arg);
                    }.bind(this), delay);
                }
            }

            let search = document.querySelector('#search');

            search.addEventListener('input', debounce(function() {
                let script = document.createElement('script');
                script.src = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=33984,33822,31660,33849,33676,33607&wd=' + this.value + '&req=2&csor=3&pwd=12&cb=callback';
                document.body.appendChild(script);
                document.body.removeChild(script);
            }, 1000));


            // search.addEventListener('input', function() {
            //     let script = document.createElement('script');
            //     script.src = 'https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=33984,33822,31660,33849,33676,33607&wd=' + this.value + '&req=2&csor=3&pwd=12&cb=callback';
            //     document.body.appendChild(script);
            //     document.body.removeChild(script);
            // });
        }

        function callback(data) {
            console.log(data);
        }
    </script>
</head>

<body>
    <input type="text" id="search">
</body>

​ 联想查询

​ 计算机无法判断用户输入的内容是否输入完成 没有办法判断用输入的单词或句子是否完整

​ 如果每次输入1个字符都进行查询 是没有意义的 因为最后一次用户输入结束才是用户想要的东西

​ 核心思想 在N秒中 只执行一次事件处理函数

​ 如果在N秒内 再次触发该事件则从新计时

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值