JavaScript复习总结

认识JavaScript

html:主要目的搭建页面的结构

css:装饰页面

JavaScript:在用户在页面上的操作有反馈,也叫做用户与页面的交互

  • 能够修改css的样式
  • 能够操作html
  • 能够获取后台数据,把数据展示在页面中
  • 可以把信息发送给后台

js和html、css一样都是一个编程语言。运行在浏览器上的编程语言

html、css、js三者分离:结构、行为、样式分离

网页页面加载的顺序

  1. 地址叫做域名,把域名转化解析成ip地址
  2. 根据ip地址访问,对应的服务器。(项目)
  3. 从服务器下载你要访问的页面
  4. 浏览器加载你的页面
  5. 先从上到下执行,先会根据html构建网页的结构
  6. 根据css,渲染样式
代码执行顺序:

代码先预解析,代码从上往下,从左到右,遇到等号,先执行等号右边的

关于前端的引号并没有区分

约定:html属性默认都是双引号js默认是单引号

单引号里面套双引号,双引号里面套单引号

js的注释

单行注释 // 快捷键ctrl+/

多行注释 /* */ 快捷键 shift + alt + a

javascript组成部分

ECMAScript:

js的核心语法(变量、函数、条件语句、循环、运算符、数据类型、字符串方法、时间对象、数学对象、数组、json)

什么是ECMA

是一个计算机协会组织,规范制定一些计算机相关的标准(组织、包含、语言类的作者、浏览器厂商)

什么是ECMAScript

ECMA这个组织出了很多标准,其中第262条标准叫做ECMAScript

为什么要规范JS的标准

需要浏览器按照标准去解析

什么是ES4、5、6

是JS的版本

ECMAScript 1.0 1997年出来

ECMAScript 2.0 1998年出来

ECMAScript 3.0 1999年出来 刚开始一年一个版本 最稳定的,被所有浏览器支持

ECMAScript 4.0 2007年 在4.0作者觉得应该让JS功能更丰富,更严谨,需要大幅度的改动JS

ECMAScript 3.1 这个版本是 4.0的阉割版

ECMAScript 5

ECMAScript 6 2007年提出 2015年ES6草案才通过

ES6不是一次性改完,分很多年慢慢改的第一版是2015年发布的,叫ESMA2015这些叫ES6

现在大版本叫ES6,以及ESNext

ECMAScript是有版本的

ECMA4 现在学的,所有浏览器版本都兼容的

ECMA5 从这里开始不兼容IE低版本浏览器

ECMA6

DOM:document object model 文档对象模型

获取元素、修改样式、修改属性、修改文本

主要操作页面里面的所有东西(html css)

BOM: browser object model 浏览器对象模型

三大弹框 : alert(‘内容’) 警告框 .confirm(‘内容’) 确认框 .prompt(‘内容’) 输入框

定时器


js的添加方式

行内引入方式、当作属性去添加
<body>
    <button onclick="
    document.getElementById('div1').style.width='300px';
    document.getElementById('div1').style.height='200px';
    document.getElementById('div1').style.background='blue'">
     变化
    </button>
    <div id="div1"></div>
</body>
内嵌引入方式(内部引入)

写在script标签中、可以写在任意地方;

当需要我们在头部引用脚本就放在头部,否则则放在底部,因为放在头部可能会影响浏览器渲染

  <script>
        // function 函数名{()
        //     要执行的代码
        //}
    // 函数就是装代码的容器
      function fn(){
            document.getElementById('div1').style.width = '300px';
            document.getElementById('div1').style.height = '200px';
            document.getElementById('div1').style.background = 'blue'
        }
  </script>

  <body>
    <button onclick="fn()">变化</button>
    <div id="div1"></div>
  </body>
外部引入方式、在script标签中使用src引入外部文件
<script src=" "></script>

变量:

什么是变量 ?

  • 一句代码的别名、容器
变量的分类:

全局变量:在函数外面声明的, 只要定义了在任何地方都可以使用,相当于在浏览器占用一个空间,并且浏览器关闭才会释放,会一直占用内 . 全局的变量相当于在浏览器内容中储存了一个内容,并且这个不会释放掉除非浏览器关闭

  • var的时候相当于在js的window对象上存了一个属性
  • window.上面的东西在使用的时候不需要写window
  • BOM里面都是window, 都不用写window

局部变量:在函数内部声明的,在函数内可以使用 ,相当于在函数内占用空间,函数使用完就释放. 局部变量只能在函数的作用域内使用

如果局部变量和全局变量名字相同,如果在函数内部使用,先找函数内部变量,再找全局变量

var  变量名 = 变量值    var a=1   var oDiv=document.getElementById(“ ”)   获取一个元素,把元素赋值给oDiv
变量生命周期

全局变量的作用域是全局性的,即在整个JavaScript程序中,全局变量处处都在。

而在函数内部声明的变量,只在函数内部起作用。这些变量是局部变量,作用域是局部性的;函数的参数也是局部性的,只在函数内部起作用。

为什么他们释放的时机不同的

因为js有一个自动的垃圾回收机制(把没有用的东西释放掉) 需要判别哪些是垃圾。

因为全局变量在任意地方都能使用,所以不会当成垃圾,但是局部变量在函数内部使用,当函数使用完,就可以当做垃圾清除掉。

变量和函数还存在预解析的现象

变量的提升,这种提升的现象叫做预解析

​ 作者在设计代码的时候,想让代码执行的更快一些。所以在最开始的时候,预先把变量的定义提升到当前作用域的最上面。

注意:仅仅是定义,没有赋值。预解析也是有范围的, 好的写代码的方式。把变量的定义都放在最上面

在js刚刚加载之前,会把变量和函数的定义提前,仅仅是定义,没有赋值,并且提升的时候是有作用域的

  1. 函数开始的时候
  2. script标签开始的位置
  3. js文件开始的位置
如何声明 :

变量的命名规范

如何声明: var变量名 = 变量值

官方规定:

  1. ​ 变量必须以字母、下划线、或者$开头,不能为数字
  2. ​ 变量中不能出现空格或者其他标点符号
  3. ​ 不能出现中文
  4. ​ 不能用关键字、保留字(js出现单词不能用)

命名约定俗成

​ 驼峰命名法(小驼峰命名法:匈牙利命名法)

  • 首个单词小写,后面的单词首字母大写

  • 变量的类型+名字进行取名

    ○ oDiv    div对象
    ○ sValue  value的字符串
    ○ bFlag 一个真假的值
    ○ fnShow  展示函数
    

​ 名字必须有意义

​ 项目中命名可以拼音,可以英文,但是如果用拼音全部用拼音,如果用英文全部用英文,不允许混合用,不允许缩写用。

声明变量的时候不加var

不加var就是全局变量,哪怕在函数内声明,也是全局变量

注意:声明的时候必须var,为什么不会报错,是js语言设计的缺陷

连等号赋值

var a =b=c=d=1;这种方法不能用,因为b、c、d变成了全局变量

连续赋值 var a=1,b=1,c=1,d=1

for (var i = 0, j = 0; i < 2, j < 5; i++, j++) {
    console.log(i, j);
  }
代码从左到右执行,判断条件看最右边
ES6里面的声明变量方法
Let / Const/Var

为了解决var的各种各样的问题,出现了Let和Const

Let相对于var 有啥区别

  • Let不会变量提升
 alert(a);//Cannot access 'a' before initialization 初始化前无法访问
 let a=1;  
  • 相同的变量,在同一作用域内不能重复声明
let a=1;
let a=2; // Identifier 'a' has already been declared 标识符xx已经声明
alert(a);
  • 不把全局变量放在window,这样提高性能
var a=1;//相当于把a放进了window。
        //这样就会导致window里面的内容非常庞大。使用window里面的东西,性能就不好。
let a=1;
console.log(window); 
  • 用let会产生块级作用域
//在let之前只有一种作用域 函数作用域,现在用let声明多了一种作用域,块级作用域
//用{}包裹的都有作用域。  for(){}  if(){}  while(){}
if(true){
   let a=1;
   }
alert(a); 

Const相对于var有啥区别

  • const不会变量提升

  • 相同的变量,在同一作用域内不能重复声明

  • 不把全局变量放在window,这样提高性能

  • 用const会产生块级作用域

    const相对于let区别

  • const声明了就不能更改,声明的是常量

  • 只要声明了就必须赋值

解构赋值:

等号两边结构一样,常用数组和json对象的解构

let[a,b]=[1,2]

let{a,b}={a:1,b:2}

let [a,{aa},c]=[1,{aa:2},3]

let {a,b}={a:1,b:[1,2,3]}

块级作用域

for 循环举例(经典案例)

for 循环举例(经典案例)

代码 1、我们先来看看如下代码:(用 var 定义变量 i)

<!DOCTYPE html>
<html lang="">
    <head>
        <meta />
        <meta />
        <meta />
        <title>Document</title>
    </head>
    <body>
        <input type="button" value="aa" />
        <input type="button" value="bb" />
        <input type="button" value="cc" />
        <input type="button" value="dd" />

        <script>
            var myBtn = document.getElementsByTagName('input');

            for (var i = 0; i < myBtn.length; i++) {
                myBtn[i].onclick = function () {
                    alert(i);
                };
            }
        </script>
    </body>
</html>

上方代码中的运行效果如下:

为何点击任何一个按钮,弹出的内容都是 4 ?这是因为,我们用 var 定义的变量 i,是在全局作用域声明的。整个代码中,自始至终只有一个变量。

for 循环是同步代码,而 onclick 点击事件是异步代码。当我们还没点击按钮之前,同步代码已经执行完了,变量 i 已经循环到 4 了。

也就是说,上面的 for 循环,相当于如下代码:

var i = 0;
myBtn[0].onclick = function () {
    alert(i);
};
i++;

myBtn[1].onclick = function () {
    alert(i);
};
i++;

myBtn[2].onclick = function () {
    alert(i);
};
i++;

myBtn[3].onclick = function () {
    alert(i);
};
i++; // 到这里,i 的值已经是4了。因此,当我们点击按钮时,i的值一直都是4

代码 2、上面的代码中,如果我们改为用 let 定义变量 i:

<!DOCTYPE html>
<html lang="">
    <head>
        <meta />
        <meta />
        <meta />
        <title>Document</title>
    </head>
    <body>
        <input type="button" value="aa" />
        <input type="button" value="bb" />
        <input type="button" value="cc" />
        <input type="button" value="dd" />

        <script>
            var myBtn = document.getElementsByTagName('input');

            for (let i = 0; i < myBtn.length; i++) {
                myBtn[i].onclick = function () {
                    alert(i);
                };
            }
        </script>
    </body>
</html>

上方代码中的运行效果如下:

上面这个运行结果,才是我们预期的效果。我们用 let 定义变量 i,在循环的过程中,每执行一次循环体,就会诞生一个新的 i。循环体执行 4 次,就会有四个 i。

暂时性死区 DTC

ES6 规定:使用 let/const 声明的变量,会使区块形成封闭的作用域。若在声明之前使用变量,就会报错。

也就是说,在使用 let/const 声明变量时,变量需要先声明,再使用(声明语句必须放在使用之前)。这在语法上,称为 “暂时性死区”

DTC 其实是一种保护机制,可以让我们养成良好的编程习惯。

代码举例:

const name = 'qianguyihao';

function foo() {
    console.log(name);
    const name = 'hello';
}

foo(); // 执行函数后,控制台报错:Uncaught ReferenceError: Cannot access 'name' before initialization

闭包

两个函数定义的时候,出现函数嵌套,这个时候父级函数的局部变量就不会被释放掉,因为不知道子函数什么时候会用,这个时候会造成局部变量无法释放,这种现象叫做闭包。

function fn1( ) {
   let a = 10;
   function fn2( ) {
       console.log(a);
   }
   fn2( );
}
fn1( );

函数 fn2 的作用域 访问了 fn1 中的局部变量,那么,此时在 fn1 中就产生了闭包,fn1 称之为闭包函数。

闭包缺点:如果有大量的闭包,内存就不会释放掉

解决方法:

  1. 减少闭包的使用
  2. 当子函数使用完后,干掉子函数

数据类型:

用typeof分类
  • 数字:number

  • 字符串:string

  • 布尔值:boolean

  • 函数:function

  • 对象:object 空对象:null typeof的的类型是object

  • 未定义:undefined

    • 声明一个变量为赋值 var a; a就是undefined
    • 函数没有传参 function fn(a,b){} a.b就是undefined
    • 函数没有返回值) function fn(){} var a =fn() a就是undefined
  • NaN not a number 不是一个数字 typeof 下属于number

    • ​ NaN非纯数字的字符串或者undefined参与运算,都会得到NaN
    • ​ NaN 不等于NaN
    • ​ 怎么判断是不是NaN isNaN(要判断的东西)
基础数据类型

number string boolean null undefined NaN

引用数据类型

对象 函数

常见的对象(数组、json、时间对象、数学对象、正则对象)

基础数据类型和引用数据类型区别
存储方式不同

基础数据类型因为他简单,占用空间少。所以他是直接指向储存的数字

​ var a=1; a直接代表1 名字直接对应了一个个体

复杂数据类型,因为他的里面会放很多的简单数据类型,占用的空间大。名字对应的是一个地址

​ var arr=[1,2,3,4,5];

注意事项:

1、引用数据类型复制的时候比较麻烦。 建议暂时用…

2、引用数据类型的比较,哪怕两个东西完全一样,也不相同

数据类型之间的转换和真假的关系
字符串转成数字

隐式类型转换: - / * % == != 运算做了隐式转换

强制类型转换:隐式类型转换变化太多,容易出现错误

  • parseInt(字符串)调用的结果就是转化的整数

    • ‘18’ 18

    • ‘18.1’ 18

    • ‘18a’ 18

    • ‘a18’ NaN

  • parseFloat(字符串) 调用的结果是转化的小数

    • ‘18’ 12

    • ‘18.1’ 12.1

    • ‘18a’ 12

    • ‘a18’ NaN

  • Number(字符串) 调用的结果就是转化的数字,字符串里面必须全部都是数字

    • ‘18’ 18

    • ‘18.1’ 18.1

    • ‘18a’ NaN

    • ‘a18’ NaN

转换错误会出现NaN(not a number )

数字转化成字符串

数字 + " "

js里面的真假关系

在js里面只有6个假,除此之外都是真

  • 0
  • false
  • 空字符串‘’(‘空格’不是)
  • NaN
  • null
  • undefined

js的输入输出方式

alert( ) 、 console.log( )、prompt 最主要目的是为了测试

三种弹框
页面弹窗alert()
  • 只是消息的提示,能中断代码。
  • alert()展示的数据都会被转化成字符串
  • 只能打印一个东西
输入弹窗prompt(‘ ’)
  • 可以让用户输入的提示框
  • 也会中断代码
  • 会返回结果,返回的结果是字符串

img

判断弹窗confirm(‘ ’)

​ 可以用户选择确定还是取消,会返回一个true false的结果

var b = "刘帅是不是帅二娃";
      confirm(b);

img

控制台输出 console.log()
  • 不会中断代码
  • 不会转换类型
  • 可以打印多个,用逗号隔开
var a = NaN;
console.log(isNaN(a));

img

输出写在页面中的document.write()
  document.write("李郝帅");

img


运算符

1、算术运算符
  • +加法
  • -减法
  • *乘法
  • /除法
  • %取余数、取模
2、比较运算符
  • > 大于

  • < 小于

  • == 是否相等 (不判断数据类型,如果字符串是数字,会转化成数字进行比较)

  • === 权等(会判断数据类型,既要判断数值,也有判断类型)

  • >= 大于等于

  • <= 小于等于

  • != 不等于

3、逻辑运算符
  • 或 || (两边只要一边成立)
  • 并且 && (两边都要成立)
4、赋值运算符
  • = 例子:a = 1

  • += a+=1 相当于 a= a+1

  • -= a-=1 相当于a =a-1

  • = a=2 相当于 a= a2

  • / = a/=2 相当于a=a/2

  • %= a%=2 相当于a=a%2

  • a++ 相当于a=a+1或者a+=1

  • a-- 相当于a=a-1

关于 + + i 和 i + + 的面试题
var i = 1;
alert(++i);
//i++;相当于 i+=1相当于i=i+1
++i;
alert(i++);

区别:

  • i + + 是先赋值在运算(如果打印,打印的是运算前的)

  • ++ i 是先运算再赋值(如果打印,打印的是运算后的)

5、三元运算符、三目运算符

条件?条件成立代码:条件不成立代码


条件判断语句

if else条件语句
if(条件){//如果
  条件成立执行的代码
}
else{
  条件不成立执行的代码
}
if(条件1){//如果
  条件1成立执行的代码
}
else if(条件2){
  条件2成立执行的代码
}
else{
  条件都不成立执行的代码
}

注意:if和else最多一个,else if可以多个或者没有

案例:一个按键让div显示隐藏
<style>
  #div1 {
    width: 100px;
    height: 100px;
    background: #000;
    display: none;
  }
</style>

<button id="btn1">按钮</button>
<div id="div1"></div>
var oBtn = document.getElementById("btn1");
var oDiv = document.getElementById("div1");
oBtn.onclick = function () {
  if (oDiv.style.display == "block") {
    oDiv.style.display = "none";
  } else {
    oDiv.style.display = "block";
  }
      };
switch条件语句
switch(表达式) {
  case n:
    代码块
    break; //意思是终止下面的操作,跳出
  case n:
    代码块
    break;
  case n:
    代码块
    break;
  default:   //上面所有都不满足
    默认代码块
} 

解释:switch 可以理解为"开关、转换" case 可以理解为"案例、选项"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Djo7kYRU-1662618687466)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20220828144746373.png)]


循环语句

for循环语句
for(初始值的声明;判断条件;自增或者自减){
	条件成立执行代码
}

1.初始化声明

2.进行判断满不满足

3.满足,执行for里面的代码,不满足for循环结束

4.执行完代码,自增或者自减(因为要最终离开循环)

5.进行判断满不满足,依次执行3.4.5,直到条件不满足

 for (var i = 0; i < 10; i = i + 1) {
        console.log(i);
      }

img

注意:循环几次,里面的代码执行几次

( break是直接终止 continue是单独中止一次 )

break:跳出整个循环

continue:跳出本次的循环

img

如果要跳出多层循环,添加一个空的,直接离开for循环

a:
for(var i=0;i<10;i++){
   for(var j=0;j<3;j++){
     if(i==2&&j==1){
       break a;
     }
   console.log(i,j);
 }
}
案例:一堆div点击变红
<style>
  div {
    width: 100px;
    height: 100px;
    background: black;
  }
</style>
</head>
<body>
  <div id="div1"></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  
  
var aDiv = document.getElementsByTagName("div");
// console.log(aDiv);
for (var i = 0; i < aDiv.length; i++) {
  // console.log(i);
aDiv[i].onclick = function () {
    // this 表示触发这个函数的东西  表示谁触发了这个函数
    this.style.background = "red";
  };
}

注意:

i++ 就是 i= i+1

这里是获取getElementsByTagName(" ") 一个数组

img

for循环里面的 i<a.Div.length 是遍历数组。

img

while循环
 while(条件){
        代码
        自增或自减(不写就变成死循环)
    }

 var a = 0;
    while (a < 3) {
      console.log(a);
      a++;
    }

如果循环的是固定具体的次数,那么用for循环,如果不知道循环多少次,不是固定的次数,用while循环

do-while(只在面试题里面出来,基本不用)
  do {
      代码;
      自增或者自减;
    } while (条件);


 var a = 0;
    do {
      console.log(a);
      a++;
    } while (a < 3);

while和do—while的区别在于,while如果第一次条件不成立,不会进入循环,do—while是先进入循环再判断,就算初始条件不满足,也换先执行一次。


数组

数组中的元素可以是任意的数据类型,也可以是对象,也可以是函数,也可以是数组。

创建数组对象
var wuzi=['大米','面','蔬菜','肉']
使用构造函数创建数组
var arr = new Array(参数);

区别:

new Array(只放一个数字) 不能创建出一个数组里面有一个数字,创建出一个长度为几的空数组

注意:数组是放数据的,里面可以放任意类型的数据,工作的时候一个数组类型基本相同

声明数组的方法
var arr=[1,2,3];
var arr2=new Array(1,2,3)
console.log(arr,arr2); 

区别:
var arr=[3];             //生成一个 3数组
var arr2=new Array(3)    //生成三个 空数组
console.log(arr,arr2);

数组的索引

索引 (下标) :用来访问数组元素的序号,代表的是数组中的元素在数组中的位置(下标从 0 开始算起)。

获取数组中的元素
数组[索引];
var arr = [21, 22, 23];
console.log(arr[0]); // 打印结果:21
console.log(arr[5]); // 打印结果:undefined
向数组中添加元素
数组[索引] =;
// 向数组中添加元素
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[5] = 50;

获取数组的长度

可以使用length属性来获取数组的长度(即“元素的个数”)。

数组的长度是元素个数,不要跟索引号混淆。

数组的长度 = 数组名.length;
var arr = [21, 22, 23];
console.log(arr.length); // 打印结果:3
遍历数组

遍历: 就是把数组中的每个元素从头到尾都访问一次。

最简单的做法是通过 for 循环,遍历数组中的每一项。

var arr = [10, 20, 30, 40, 50];
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]); // 打印出数组中的每一项
}
数组的一系列操作
var aaa = ["刘帅", "帅二娃", "帅先生", "250"];
//   前面 增加
aaa.unshift("我儿子");

//后面增加
aaa.push("我的好大儿");

//删除前面的
aaa.shift();
//删除最后面的
aaa.pop();
//删除指定位置    splice.()  起始位置,删除几个,添加内容
aaa.splice(1, 1);
// 添加内容
aaa[1] = "添加的刘帅";
console.log(aaa);

// 两个数组合并到一个数组 原数组不会发生变化
var arr = [1, 2, 3];
var arr2 = [4, 5, 6];
var arr3 = arr.concat(arr2);
console.log(arr3, arr, arr2);

// 把数组变成字符串
var str = arr3.join(); //括号里面写连接的方式   原数组不会发生变化
console.log(str);
alert(typeof str);

// 数组翻转     原数组会发生变化
var newArr = arr3.reverse();
console.log(newArr, arr3);

//如何清空一个数组
arr.length = 0;
arr2 = [];
arr3.splice(0, arr3.length);
console.log(arr, arr2, arr3);

//排序
var arr4 = [3, 5, 1, 8, 9, 2, 6];
arr4.sort(); //默认按照字典顺序排列
console.log(arr4);

var arr5 = ["a", "aa", "ba", "ac", "da", "db"];
arr5.sort();
console.log(arr5);

//按照大小顺序排
var arr6 = [3, 5, 1, 8, 9, 2, 6, 12, 15, 23];
arr6.sort(function (a, b) {
  //告诉系统,以什么样的规则去排序
  //a,b 就是数组中的每一项
  return a - b; //传过去一个比较的规则  规则就是让两个数字,比较大小
  //   a-b 升序:从小到大排   b-a 降序:从大到小排
});
    console.log(arr6);
冒泡排序
var arr = [20, 10, 50, 30, 40];
for (var i = 0; i < arr.length - 1; i++) {
    for (var j = 0; j < arr.length - i - 1; j++) {
        if (arr[j] > arr[j + 1]) {
            var temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;
        }
    }
}

数组的方法清单
数组的类型相关
方法描述
Array.isArray()判断是否为数组
toString()将数组转换为字符串
Array.from(arrayLike)伪数组转化为真数组
数组元素的添加和删除
方法描述备注
push()向数组的最后面插入一个或多个元素,返回结果为新数组的长度会改变原数组
pop()删除数组中的最后一个元素,返回结果为被删除的元素会改变原数组
unshift()在数组最前面插入一个或多个元素,返回结果为新数组的长度会改变原数组
shift()删除数组中的第一个元素,返回结果为被删除的元素会改变原数组
slice()从数组中提取指定的一个或多个元素,返回结果为新的数组不会改变原数组
splice()从数组中删除指定的一个或多个元素,返回结果为被删除元素组成的新数组会改变原数组
fill()填充数组:用固定的值填充数组,返回结果为新的数组会改变原数组
数组的合并和拆分
方法描述备注
concat()合并数组:连接两个或多个数组,返回结果为新的数组不会改变原数组
join()将数组转换为字符串,返回结果为转换后的字符串不会改变原数组
split()将字符串按照指定的分隔符,组装为数组不会改变原字符串

注意,split()是字符串的方法,不是数组的方法。

数组排序
方法描述备注
reverse()反转数组,返回结果为反转后的数组会改变原数组
sort()对数组的元素,默认按照Unicode 编码,从小到大进行排序会改变原数组
遍历数组
方法描述备注
for 循环这个大家都懂
map()对原数组中的每一项进行加工,将组成新的数组不会改变原数组
filter()过滤数组:返回结果是 true 的项,将组成新的数组,返回结果为新的数组不会改变原数组
查找数组里包含某个东西

indexOf es5 includes es6

数组变成字符串

join() 直接把数组直接转成字符串 是带逗号的 原数组没有发生变化

join(‘’) 数组的所有内容拼接在一起

join(‘T’) 拼接的时候中间加拼接内容

循环方法

for

let arr = [1, 2, 3, 4, 5];
for(let i=0;i<arr.length;i++){ 
}

forEach循环

//forEach 循环数组里面的每一个东西
//里面放一个函数  函数里面,系统会传过来两个参数
第一个参数是循环过程中,数组的每一项,第二个参数是,循环过程中,每一项的下标
不会返回一个新的数组, 就是单纯的循环
let arr = [1, 2, 3, 4, 5];
var arr1=['hello','hei','apple','banana']
let res = [];
for (let i = 0; i < arr1.length; i++) {
      res.push(arr1[i].toUpperCase());
}
console.log('res', res);

map 循环数组

//循环数组里面的每一个东西
//map里面放一个函数  函数里面,系统会传过来两个参数
//第一个参数是循环过程中,数组的每一项,第二个参数是,循环过程中,每一项的下标
//map的返回值是一个新的数组。新的数组中的每一项都需要在函数中return
let mapArr = arr1.map((v, i) => {
    return v.toUpperCase();
})
console.log(mapArr);

filter循环数组

//循环数组里面的每一个东西
//里面放一个函数  函数里面,系统会传过来两个参数
//第一个参数是循环过程中,数组的每一项,第二个参数是,循环过程中,每一项的下标
//filter的返回值是一个新的数组,新数组的每一项都需要在函数中return,必须符合条件 
//需要return 一个条件
 let filterArr = arr1.filter((v, i) => {
     console.log(v, i)
     return v.includes('a')
})
console.log(filterArr);

函数

什么是函数?

就是将一些功能或语句进行封装,在需要的时候,通过调用的形式,执行这些语句。

  • 函数也是一个对象

  • 使用typeof检查一个函数对象时,会返回function

  • 可以包裹一堆代码的容器

好处:

  1. 把某一些功能可以整个到一个函数中。 random() findInArr()
  2. 重复利用
  3. 利于开发配合
函数的定义/声明

函数怎么定义

命名函数:使用函数声明来创建一个函数(也就是 function 关键字)什么时候调用,什么时候执行函数里面的代码

function 函数名([形参1,形参2...形参N]){  
 // 备注:语法中的中括号,表示“可选”
	语句  代码...
}
函数名()   函数的调用

let 函数名=function(){ 把一个匿名函数赋值给一个变量
    //code
 }
函数名()   函数的调用


区别:下面这个方式必须先定义在使用,因为变量会提升

匿名函数:因为没有名字需要依靠别的东西

​ oBtn.onlick =function(){}

​ window.οnlοad=function(){}

事件 document.οnclick=function(){}

定时器 setTimeout(function(){},1000)

对象的方法 let json={ fn:function(){ } } json.fn();

事件触发的时候执行

fn( ) 和 fn 的区别【重要】
  • fn():调用函数。调用之后,还获取了函数的返回值。

  • fn:函数对象。相当于直接获取了整个函数对象。

特殊的匿名函数:自执行匿名函数

两个括号一个分号,第一个括号里面加function(){}

(function 形参() {
     代码
 })
(传参);

自执行匿名函数的好处

可以解决变量冲突的问题。第三方的插件都会用自治性匿名函数包裹。第三放插件的变量就变成局部变量。。。 现在可以用{}代替自治性匿名函数,但是不能完全代替 不能传参

! - + ~ 这几个标志表示为自执行函数

​ !function(){

​ //code

​ }()

es6里面对函数新加了一些东西

默认参数

function 函数名(参数=默认值){

}

//如果这个参数不传,就是默认值。

三个点运算符 | reset运算符 | 剩余参数运算符 …

1、把一个数据集合拆开

  • 复制一个数组、json/创建一个数组、json
  • 合并多个数组或者json
  • 把非(伪)数组转化成数组

什么是伪数组:只有下标和长度,没有数组的方法

2、可以把一些东西合并起来当成数组或者json

  • 解构赋值中剩余的合并
  • 不用argument了 直接用剩余参数
函数的调用
 //函数怎么使用
   函数名()  函数的调用   
 //什么时候后调用,什么时候执行函数里面的代码
  
普通函数的调用
function fn1() {
  console.log("我是函数体里面的内容");
}
    fn1(); // 调用函数
绑定事件函数的调用
var btn = document.getElementById('btn');
//2.绑定事件
btn.onclick = function() {
    console.log('点击按钮后,要做的事情');
};

函数的参数:形参和实参

img

形参:

  • 概念:形式上的参数。定义函数时传递的参数,当时并不知道是什么值。
  • 定义函数时,可以在函数的()中来指定一个或多个形参。
  • 多个形参之间使用,隔开,声明形参就相当于在函数内部声明了对应的变量,但是并不赋值。

实参

  • 概念:实际上的参数。调用函数时传递的参数,实参将会传递给函数中对应的形参。
  • 在调用函数时,可以在函数的 ()中指定实参。

注意:实际参数和形式参数的个数,一般要相同。

js中函数传参时如果传递多个参数,需要用",",隔开,而且需要不同的变量去接收参数,传递的参数与接收参数的变量是一一对应的

实参的数量(实参和形参的个数不匹配时)

调用函数时,解析器也不会检查实参的数量。

  • 如果实参的数量多余形参的数量,多余实参不会被赋值。

  • 如果实参的数量少于形参的数量,多余的形参会被定义为 undefined。表达式的运行结果为 NaN。

    function sum(a, b) {
    console.log(a + b);
        }
    
    sum(1, 2);      // 3
    sum(1, 2, 3);   // 3
    sum(1);         //NaN
    
    
arguments :实参的参数集合,里面装了所有实参
操作arguments[ ]

当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。

在 JavaScript 中,arguments 实际上是当前函数的一个内置对象。所有函数都内置了一个 arguments 对象(只有函数才有 arguments 对象),arguments 对象中存储了传递的所有实参.

arguments的展示形式是一个伪数组。伪数组具有以下特点:

  • 可以进行遍历;具有数组的 length 属性。
  • 按索引方式存储数据。
  • 不具有数组的 push()、pop() 等方法。
函数的返回值
console.log(sum(3, 4)); // 将函数的返回值打印出来

//函数:求和
function sum(a, b) {
	return a + b;
}

return 的作用是结束方法(终止函数)。

注意:

  • return 的值将会作为函数的执行结果返回,可以定义一个变量,来接收该结果。
  • 在函数中return后的语句都不会执行(函数在执行完 return 语句之后停止并立即退出函数)
  • 如果return语句后不跟任何值,就相当于返回一个undefined
  • 如果函数中不写return,则也会返回undefined
  • 返回值可以是任意的数据类型,可以是对象,也可以是函数。
  • return 只能返回一个值。如果用逗号隔开多个值,则以最后一个为准。

箭头函数

箭头函数目的是为了简化写法,和优化this指向

普通函数
const fn=function(){}

箭头函数
const fn=()=>{}

箭头函数的简写
const fn=a=>{}  //只有一个参数的时候()可以写
const fn=(a,b)=>a+b  //只有一句return的时候 {}和return都可以不写


箭头函数的this指向:与该函数所在的父级函数内的this指向相同

箭头函数和普通函数的区别

      • 箭头函数没有arguments 用…代替
      • 箭头函数不能作为构造函数,也就是不能new
      • 箭头函数不能作为generator函数 暂时不用管

字符串

关于字符串

只要es6 es5 html5就不兼容ie低版本

var 变量=‘ ’

var 变量=“ ”

var 变量= (反撇 tab上面那个键,支持换行)

  • 放变量方便 ${ }
  • 好看
操作字符串方法
查找字符串

indexOf(‘要查询的字符串’)

  • 返回的是字符串所在的位置下标

  • 从左往右查找,找到后返回,不会往下找了

  • 没找到返回-1

str.lastIndexOf(‘要查询的字符串’)

  • 从右往左查找,找到后返回,不会往下找了
var str = "hello world(你好)";
var index = str.indexOf("e");
var index = str.indexOf("ll");
var index = str.indexOf("z"); //查不到了就是-1
var index = str.indexOf("o"); //两个相同的的,只查询第一个
console.log(index);
截取字符串

str.substring(开始位置,结束位置)

  • 不包括后面
  • 结束位置可以不写,如果不写默认截取到最后
var str = "hello world(你好)";
var a = str.substring(0, 2);
console.log(a);   //he       左闭右开
把字符串变成数组

str.split(); //把整个字符串放进一个数组

str.split(‘’); //把所有字符串都切割放进一个数组

str.split(‘某种方式切割’)

返回一个数组

var str = "hello world(你好)"; 
var b = str.split();
      console.log(b);
var c = str.split("");
      console.log(c);

img

img

大小写转化

toLowerCase()转小写

toUpperCase ( ) 转大写

 var str = "hEllo world(你好)";
 var d = str.toLowerCase();
 var e = str.toUpperCase();
console.log(e);
通过下标返回对应的字符串

str.charAt(下标) 返回对应的字符串

var str = "hEllo world(你好)"; 
var f = str.charAt(0);
console.log(f);  //h

字符串 ‘hello world’ 如果遇到了字符串拼接 ‘hello ‘+变量+’ world’

里面的东西太多的时候直接换行不能用

在es6里面出来了一个新的写法 hello ${变量} world 里面随便换行

简单的字符串可以用’ ’ 需要复杂的换行、或者里面拼接变量用``

案例:让首字母大写

'hello world'  -> 'HelloWorld'

var str = "hello world"; //每个首字母大写

function toUp(str) {
  var arr = str.split(" "); //通过空格,切割成一个数组
  for (var i = 0; i < arr.length; i++) {
    //循环每一项
    //重新改数组
    //arr[i]的这一项的首字母大写+这一项除首字母的东西
    arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
  }
  return arr.join(""); //把转换后的数组,拼接成字符串返回
}
aaa = toUp(str);
      console.log(aaa);
截取文件名后缀  ‘a.txt’--> txt   'a.a.a.png'   --> png


function fn(str) {
  return str.substring(str.lastIndexOf(".") + 1);   先从左往右查询坐标,获取坐标后进行分割
}

console.log(fn("a.txt"));
console.log(fn("a.a.a.a.png"));
字符串的方法
查找字符串所在的位置
  • indexOf(‘要查找的字符串’) 返回下标,没有找到返回-1

  • lastIndexOf(‘要查找的字符串’) 返回下标,没有找到返回-1

通过下标找对应的字符串
  • charAt(‘下标’) 返回的是字符串,没有内容返回空字符串。

  • str[ 下 标 ] 不兼容IE低版本

大小写转化
  • toLowerCase()

  • toUpperCase()

截取字符串
slice(?开始下标,?结束下标)

解释:从字符串中截取指定的内容。不会修改原字符串,而是将截取到的内容返回。

注意:上面的参数,包左不包右。参数举例如下:

  • (2, 5) 截取时,包左不包右。
  • (2) 表示从指定的索引位置开始,截取到最后
  • (-3) 表示从倒数第三个开始,截取到最后。
  • (1, -1) 表示从第一个截取到倒数第一个。
substring(开始下标,?结束下标) ?是可有可无的意思

解释:从字符串中截取指定的内容。和slice()类似。

substring()slice()是类似的。但不同之处在于:

  • substring()不能接受负值作为参数。如果传递了一个负值,则默认使用 0。
  • substring()还会自动调整参数的位置,如果第二个参数小于第一个,则自动交换。比如说, substring(1, 0)相当于截取的是第一个字符。

如果开头是负数:

substring 当做0开头

slice 找不到

如果结尾数字比开始数字小:

substring 相当于把开始结束反过来

slice 找不到

如果结束是负数:

substring 当做0处理

slice 从后往前取

开始结束都是负数:都为空

把字符串变成数组

str.split(‘某种方式切割’); 把整个字符串放进一个数组

​ 返回一个数组

是否包含某个字符串

includes() 返回的是true和false

是不是以什么开头

startsWith() 返回的是true和false es6

是不是以什么结尾

endWith() 返回的是true和false es6

最大长度,如果不够长用什么补

padStart ( ) es6

padEnd( ) 在结尾填充字符串

trim( ) 去除首尾空格 es5

trimStart() 去除首空格 es6

trimEnd() 去除结尾空格 es6

search(正则) 搜索 返回的下标
match(正则) 查找一个或多个字符串,返回的数组
replace(’要替换的字符串‘,’新的字符串‘)

replace(正则,“新的字符串”)

replace(正则,function(v){ return 新的字符串})

ES6字符串的新增方法

模板字符串 `` aaa${变量}bbb

includes(‘字符串’) 字符串内是否包含某个字符串

startWith(‘字符串’) 字符串的开头是否包含某个字符串

endWith(‘字符串’) 字符串的结尾是否包含某个字符串

padStart(最小位数,‘要补的字符串’) 开头补

padEnd(最小位数,‘要补的字符串’) 最后补

trimStart() 开头去空格

trimEnd() 结尾去空格

repeat(次数) 重复


正则表达式

  • 用来操作字符串的

有一些字符串的操作用常规的字符串方法操作非常复杂,用正则方便

  • 一定规律的字符串

全称叫做正则表达式 regular expression 也叫规则表达式

  • 可以用来描述一套规则

他是一种独立语言,很多语言都会引入

怎么创建一个正则

正则也是一个对象

var reg = /规则 /选项修饰符 字面量的创建

var reg = new RegExp(‘ ’) 通过new来创建

选项修饰符
  • i ignore 忽略大小写
  • g global 全局
  • m mutil-line 多行

可以同时使用,没有先后顺序

转义字符 用+字母代表特定的规则

\ 转义

\s space 空格

\d 数字

\D 非数字

\w 单词

\W 非单词

. 代表任何任意

如果想代表本身 .

所有有特殊含义的,想要用本身的含义都需要\转义 \本身

量词

{ 最小值,?最大值} 最大值可以不写

{n} 正好n个 eg :/1{2}/ 11

{n,m} 最少n个,最多m个 ,m包含

​ eg: /1{1,3}/ 1 11 111

{n,} 最少n个,多了不限

几个特殊写法的量词

{1,} 最少1个,多了不限 +代替

{0,} 可以没有,有了不上限 *代替

{0,1} 可以没有,有只有1个 ?代替

特殊符号

| 或 [ab] a|b a或b

^ 行首

$ 行尾

[ ]

1 .或
[abc] 代表 a|b|c
[a|b] 代表 a|b或者是|

2.区间
[a-z] 代表 所有的字母
[0-9] 代表 所有的数字,相当于\d

3.排除
[^]排除所有的可能
[^0-9] 除了数字所有都可以
()提高优先级 分组

特殊题:

[1-38] 1|2|3|8

[1-3-8] 1|2|3|-|8

[\u4e00-\u9fa5] 汉字

/^1[3-9]\d{9}&/ qq号校验 第一位为1,后面的数字3-9,九位

正则两种声明方式的区别

1.通过new来写的 转义符需要转两次 (字符串里面两个\才有转义的作用)

2.new里面可以放变量 用处不大

时间对象

内置对象 Date 用来处理日期和时间。拿到这个对象就可以拿到当前系统时间

创建Date对象有两种写法:
  • 写法一:如果Date()不写参数,就返回当前时间对象
  • 写法二:如果Date()里面写参数,就返回括号里输入的时间对象
写法一:不传递参数时,则获取系统的当前时间对象
var date1 = new Date();
console.log(date1);
console.log(typeof date1);

img

法二:传递参数
var date11 = new Date('2022/02/17 21:00:00');
console.log(date11); // Mon Feb 17 2022 21:00:00 GMT+0800 (中国标准时间)
var date21 = new Date(2020, 2, 18); // 注意,第二个参数返回的是三月,不是二月
console.log(date21); // Wed Mar 18 2020 00:00:00 GMT+0800 (中国标准时间)
Date对象的方法

Date对象 有如下方法,可以获取日期和时间的指定部分

方法名含义备注
getFullYear()获取年份
getMonth()获取月: 0-110代表一月
getDate()获取日:1-31获取的是几号
getDay()获取星期:0-60代表周日,1代表周一
getHours()获取小时:0-23
getMinutes()获取分钟:0-59
getSeconds()获取秒:0-59
getMilliseconds()获取毫秒1s = 1000ms
先要获取系统的时间对象-当前时间下的时间对象
var oDate=new Date(): 

获取年份
var y = oDate.getFullYear();

获取月份 从0开始  0-11
var x = oDate.getMonth();

获取的日
var a = oDate.getDate();
      
获取小时
var h = oDate.getHours();

获取分钟
var m = oDate.getMinutes();
 
获取秒
var s = oDate.getSeconds();

获取的星期  0-6 0是星期天 1-6是周一到周六
var b = oDate.getDay();
      

获取时间戳
时间戳的定义和作用

时间戳:指的是从格林威治标准时间的1970年1月1日,0时0分0秒到当前日期所花费的毫秒数(1秒 = 1000毫秒)。

计算机底层在保存时间时,使用的都是时间戳。时间戳的存在,就是为了统一时间的单位。

getTime():获取时间戳

getTime() 获取日期对象的时间戳(单位:毫秒)。这个方法在实战开发中,用得比较多。但还有比它更常用的写法,我们往下看。

获取 Date 对象的时间戳
获取 Date 对象的时间戳(较常用的写法)
var time2 = new Date().getTime();
console.log(time2); // 打印结果举例:1589448165370
获取当前时间的时间戳

获取当前时间的时间戳,除了上面的几种方式之外,还有另一种方式。代码如下:

获取当前时间的时间戳(很常用的写法)
var t =Date.now()  
console.log(Date.now()); // 打印结果举例:1589448165370

获取时间戳    从197011日到现在的毫秒数
var t = oDate.getTime();

除了这种方法获取时间戳还有一种方法
var t =Date.now()  

直接出来年月日的时间
var time1 = oDate.toLocaleDateString(); 
console.log(time1);

直接出来年月日的时间 小时分钟秒
var time2 = oDate.toLocaleString(); 
console.log(time2);

小时分钟秒      
var time3 = oDate.toLocaleTimeString(); 
console.log(time3);
设置时间
var oDate = new Date();
oDate.setFullYear(1999);
oDate.setMonth(11);
oDate.setDate(1);

简写的设置

可以设置年,月,日
oDate.setFullYear(1999, 11, 1); 

小时也可以设置小时,分钟,秒
oDate.setHours(11, 12, 13); 

20228114234var oDate = new Date(2022, 8, 1, 14, 23, 54); 
var oDate = new Date("2022-02-02");
var oDate = new Date("2022/02/23 14:29:54")

案例:距离国庆还有多少天

var nowDate = new Date(); //现在的时间对象
var futureDate = new Date("2022/10/1 0:0:0"); //未来的时间对象
var total = futureDate.getTime() - nowDate.getTime(); //现在距离国庆的毫秒数=国庆距离1970,1,1的毫秒数-现在距离1970,1,1的毫秒数
console.log(total);
//天
var day = Math.floor(total / 1000 / 60 / 60 / 24); //一天有86400秒
//小时
var hour = Math.floor((total / 1000 / 60 / 60) % 24);
//分钟
var minutes = Math.floor((total / 1000 / 60) % 60);
//秒
var sec = Math.floor((total / 1000) % 60);
console.log(day, hour, minutes, sec);

DOM 文档对象模型

文档是如何构建的
DOM树 文档是以DOM树的方式构建的

节点、根节点、父节点、子节点、兄弟节点

分支

对html来说最大的根节点是document,文本(文档)
节点的类型
  • 根节点 document
  • 元素节点 div p span
  • 文本节点 内容
  • 属性节点

用的最多的是根节点和元素节点

关于节点有一些特殊的东西

nodeName 节点的名字

元素节点 nodeName就是节点名称大写标签名、

属性节点 nodeName和属性名相同

文本节点 nodeName 始终是#text

nodeValue 节点的值

元素节点 null

属性节点 属性值

文本节点 文本本身

nodeType 节点的类型

元素节点 1

属性节点 2

文本节点 3

img

节点的获取
通过id获取

document.getElenmentById(‘id名字’)

通过标签名获取

document.getElenmentByTagName(‘标签名’)

通过class名获取

document.getElenmentByClassName(‘class名’) 是es5出来的,不兼容ie低版本

通过选择器获取

document.querySelector(‘选择器(#div p a)’) 获取的是一个

document.querySelectorAll(‘选择器’) 获取的是一组 不兼容ie低版本**

如何获取子节点

childNodes 获取出来的是所有类型的节点,平常不用

children 获取所有的元素节点(第一层的所有元素节点)

如何获取父节点

parentNode

获取兄弟节点

上一个兄弟节点

previousElementSibling 不兼容IE低版本

下一个兄弟节点

nextElementSibling 不兼容IE低版本

获取第一个子节点

firstElementChild 不兼容IE低版本

获取最后一个子节点

lastElementChild 不兼容IE低版本

创造一个节点

document.createElement(‘标签名’)

必须是document创建

必须插入或者放在body的某个地方才有用

var bbb = document.querySelector("#div2");
var aaa = document.createElement("i"); 
var oSpan = document.querySelector("#div2 span");
bbb.insertBefore(aaa, oSpan);


var oDiv=document.querySelector('#div1');
var oDiv2=document.querySelector('#div2');
oDiv.innerHTML='<i>我是斜体</i>'
/* 
创建一个元素插入
*/
var oP=document.createElement('p');
var oB=document.createElement('b');
添加一个节点

innerHTML = ‘节点’ ,这种添加相当于是覆盖

父节点.appendChild(子节点) 向父亲的最后追加一个节点

父节点.appendChild(新的子节点); 父节点的最后插入一个新的子节点。
var bbb = document.querySelector("#div2");
var aaa = document.createElement("i");
bbb.appendChild(aaa);
console.log(bbb);

父节点.insertBefore(‘把谁插入到谁的前面’)

 <div id="div1">
      <p>111</p>
      <p>222</p>
      <p class="p1">333</p>
      <p>444</p>
      <p>555</p>
    </div>
    <div id="div2">
      <span>哈哈</span>
    </div>

父节点.insertBefore(新的子节点,作为参考的子节点)
 var oSpan = document.querySelector("#div2 span");
 var bbb = document.querySelector("#div2");
 var aaa = document.createElement("i");

 bbb.insertBefore(aaa, oSpan);
      console.log(bbb);
删除一个节点

父节点.removeChild(子节点)

不能删除一组节点

 <div id="div1">
      <p>111</p>
      <p>222</p>
      <p class="p1">333</p>
      <p>444</p>
      <p>555</p>
    </div>
    <div id="div2">
      <span>哈哈</span>
    </div>

var oSpan = document.querySelector("#div2 span");
var bbb = document.querySelector("#div2");
var aaa = document.createElement("i")
bbb.removeChild(oSpan);
替换一个节点

父节点.replaceChild(替换的元素【新】,被替换的元素【旧】)

  <div id="div1">
      <p>111</p>
      <p>222</p>
      <p class="p1">333</p>
      <p>444</p>
      <p>555</p>
    </div>
    <div id="div2">
      <span>哈哈</span>
    </div> 
var oSpan = document.querySelector("#div2 span");
var bbb = document.querySelector("#div2");
var ccc = document.createElement("b");
bbb.replaceChild(ccc, oSpan);
克隆一个节点

.cloneNode() 只克隆当前元素

.cloneNode(true) //所有的都克隆过来

var oDiv = document.querySelector("#div1");
var oBox = document.querySelector("#box");
var newDiv = oDiv.cloneNode();
oBox.appendChild(newDiv);
oDiv.cloneNode(true);

克隆过后需要记住把他们加进去

对节点的内容的操作
  • innerHTML 解析、获取html内容
  • innerText 操作的是文本内容,不能获取解析html内容
  • outerHTML 操作文本+标签+自身标签
对节点属性的操作

. [ ]

平时用的最多,但是不能获取到自定义属性,除非是js后面添加的

对于非法的自定义属性,浏览器在解析html的时候会过滤

js自己添加的属性能够通过 . [ ]获取

<div title="aaa"></div>

var oDiv = document.querySelector("div");
oDiv.title = 111;
oDiv["title"] = 222;

getAttribute(‘属性名’)

setAttribute(‘属性名’,‘属性值’)

removeAttribute(‘属性名’)

不管你是不是自定义,都能操作

var oDiv = document.querySelector("div");
 oDiv.setAttribute("aaa", "111");
 oDiv.removeAttribute("title", "123");
 console.log(oDiv);

在htm5之前,行业有个约定俗成的规矩,自定义属性加一个前缀 data-xxx

html5出来以后,把data-xx变成了规范

获取: 元素.dataset.属性名

设置 : 元素.dataset.属性名='属性值’

var oDiv = document.querySelector("div");
oDiv.dataset.aaa = 2;
console.log(oDiv.dataset);

总结:

平时,系统自带的用. [ ] 毕竟写起来方便

如果是自定义的用data-xxx

Attribute一般不用,在设计框架的时候用

对class的操作

.className = ‘xxx’

对class重新赋值

h5出来了新功能

.classList.add(“class名”);

.classList.remove(“class名”)

对样式的操作

获取:元素.style.样式名

设置:元素.style.样式名=‘样式值’

行间样式的设置

getComputedStyle(元素).样式 :获取样式 计算过后的样式 兼容高级浏览器

注意:获取出来的是加单位的字符串

注意:颜色 不管用的什么表示法获取出来的都是rgb

拓展

str.indexOf找不到为什么返回-1,不返回null undefined

函数封装的时候约定返回值最好是同一种数据类型

定义一个变量,如果刚开始赋值的时候最后赋同类型的

var oDiv = null

DOM里面特殊的对象

document 根元素

html : document.docunmentElement 相当于html

body : document.body 相当于body

事件

  • 什么是事件?

    用户的操作交互

    onclick: 当用户点击的时候

    onmouseover:当鼠标移入的时候

    onmouseout:当鼠标移出的时候

    alert(‘弹框内容’) 弹框

  • 事件加给谁?

    要操作谁就加给谁。

  • 事件什么元素都可以添加事件吗?

    理论上所有标签都可以加事件,但是平常给body以及body里面的标签加事件

事件的分类
鼠标事件

onclick 一次点击,相当于,一次鼠标按下 + 一次鼠标抬起

ondblclick 双击

onmouseover 鼠标移入

onmouseout 鼠标移出

onmousemove 鼠标移动的时候

onmouseenter 鼠标进入

onmouseleave 鼠标离开

  • 没有事件冒泡的行为
  • 不兼容低级浏览器

高频触发事件,这种事件不要写复杂的逻辑,后期这种事件也要做性能优化

onmousedown 鼠标按下去

onmouseup 鼠标抬起

oncontextmenu 点击鼠标右键

键盘事件

onKeydown 键盘按下

onKeyup 键盘抬起

键码

a 65 空格 32 数字1 49 回车 13 左 37 上 38 右 39 下 40

js里不能同时出现两个键码

在事件对象中得组合键: ctrlKey altKey shiftKey

ui事件、窗口事件

onload

onscroll

onresize window.onresize 当窗口大小发生变化的时候

输入事件

oninput 只兼容高级浏览器

焦点事件

onfocus 当获取焦点的时候

onblur 当失去焦点的时候

元素.focus

元素.blur

change事件

用于select 、input:file

当select没有value的时候。默认获取文本值,有value获取value

文件上传,获取元素里面的file属性

不能用在input、texttarea里面,用在里面会出现,失去焦点才触发的情况

ui事件、窗口事件

onload

onscroll

onresize window.onresize 当窗口大小发生变化的时候

事件(JavaScript)的添加方式

1、行间的事件添加方式 在标签上以属性的方式
   <script>
function fn(){}
  </script>
      <div onclick="fn()"></div>
2、操作属性的方式获取 可以获取所有要用的元素、标签 > 进行添加

同一个元素不能加多个相同的事件

解除: oBtn.οnclick=null

window.onload = function(){
  //窗口加载完,执行函数
  
var oBbt = document.getElenmentById('btn');
var oDiv = document.getElenmentById('div1');
oBtn.onclick=function(){
oDiv.style.display='none'
    }
}

案例:让div盒子显现出来

<!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>
    <style>
        div{
            width: 100px;
            height: 100px;
            background: red;
            display: none;
        }
    </style>
</head>
<body>
    <!-- <button οnclick="让div样式里面的display变成block">显示</button> -->
    <!-- <button οnclick="div1.style.display='block'">显示</button>
    <div id="div1"></div> -->
    <!-- 
        div1.style.display='block'  
        不是标准的写法。不被协议组织认可的写法
     -->
    <button onclick="document.getElementById('div1').style.display='block'">显示</button>
    <div id="div1"></div>
</body>
</html>
3、元素.addEventListener( 不加on的事件,事件触发执行函数函数名不加(),是否事件下沉)

目的:给同一个元素加多个相同的事件

第三个参数true是事件下沉,false是事件冒泡,默认是false

解除事件 :元素.removeEventListener(‘不加on的事件名’,事件触发时候执行的函数,是否事件捕获)

4、事件委托

把事件的添加委托给父级元素,或者在往上的元素.

ul.onclick = function(e) {
   if (e.target.tagName == "BUTTON") {
		e.target.parentNode.remove();
	}
事件委托的原理

利用事件冒泡,把事件冒泡给父元素。通过事件对象里面的target找到触发的原对象

为什么要委托

1、提高性能 给多个相同元素加相同事件的时候,平常用for,为了提高性能可以用事件委托

2、为不存在的,未来的元素加事件

事件对象

事件触发时候,包含事件详细信息的对象。

函数触发的时候里面有个东西 event

event 不兼容低版本火狐。现在全部兼容

clientX/clientY 可视区的坐标

pageX/pageY 页面的距离坐标 兼容高级浏览器

cancelBubble 阻止事件冒泡

target 触发事件的目标元素

event.preventDefault() 阻止浏览器默认行为
  • 右键菜单
  • form表单的提交
  • 阻止浏览器选中
  • 阻止出现禁止标志

事件流

当事件发生的时候,会有一个执行的顺序,这个执行的顺序,就叫做事件流(事件的流向)

事件冒泡

从当前触发的元素开始执行,一层一层向父级递进,在这个过程中,有相同的事件,触发,没有相同的事件继续向上递进,直到document (ie公司提出)

事件下沉(事件捕获)

当事件触发,最先从document开始,一层一层向下执行,直到执行触发事件的元素,有相同的事件触发,没相同元素继续(网景公司提出)

默认都是事件冒泡

阻止冒泡: cancelBubble =true

event.cancelBubble =true

案件:鼠标拖拽

img

  <style>
    div {
      width: 100px;
      height: 100px;
      background: #2f90ff;
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
  <body>
    <div></div>
  </body>

//  script
    var oDiv = document.querySelector("div");
    var disX;
    var disY;

    function down() {
      disX = event.pageX - oDiv.offsetLeft;
      disY = event.pageY - oDiv.offsetTop;

      document.addEventListener("mousemove", moveFn);
      document.addEventListener("mouseup", upFn);

      //阻止浏览器的事件发生
      event.preventDefault();
    }

    function moveFn() {
      var left = event.pageX - disX;
      var top = event.pageY - disY;
      //限制范围
      if (left <= 0) {
          left = 0;
      } else if (
          left >=
        document.documentElement.clientWidth - oDiv.offsetWidth
      ) {
          left = document.documentElement.clientWidth - oDiv.offsetWidths;
      }

      if (top <= 0) {
        top = 0;
      } else if (
        top >=
        document.documentElement.clientHeight - oDiv.offsetHeight
      ) {
        top = document.documentElement.clientHeight - oDiv.offsetHeight;
      }
      oDiv.style.left = left + "px";
      oDiv.style.top = top + "px";
    }
    function upFn() {
      document.removeEventListener("mousemove", moveFn);
    }
    oDiv.addEventListener("mousedown", down);

如何获取元素

通过id名来获取元素 document.getElementById(‘id名’)

通过标签获取元素 document.getElementsByTagName(" ") 一个数组

注意:通过标签获取的是集合元素(一组元素),要取到其中某一个,需要用到下标

它还有拥有length 长度

不仅可以在document下获取,也可以在其他父级下获取(见下拉列表案例)

哪怕获取出来的是一个也是一组

案件:下拉列表选择

<style>
  * {
  margin: 0;
  padding: 0;
}
div {
  margin: 30px 40px;
}
li {
  list-style: none;
  height: 26px;
  line-height: 26px;
  border-bottom: 1px solid #ddd;
  text-align: center;
}
li:hover {
  background: #56c0ff;
  color: white;
}
h4 {
  width: 80px;
  height: 30px;
  border: 1px solid black;
  text-align: center;
  line-height: 30px;
  text-indent: 4px;
}
ul {
  border: 1px solid #eee;
  width: 80px;
  display: none;
}
</style>
<div>
    
  <h4>html</h4>
<ul>
  <li>html</li>
  <li>css</li>
  <li>js</li>
  <li>node</li>
</ul>

</div>
var oH4 = document.getElementsByTagName("h4")[0];
var oUl = document.getElementsByTagName("ul")[0];
var aLi = oUl.getElementsByTagName("li");
oH4.onclick = function () {
  oUl.style.display = "block";
};

for (var i = 0; i < aLi.length; i++) {
  aLi[i].onclick = function () {
    oUl.style.display = "none";
    oH4.innerHTML = aLi[i].innerHTML;
  };
}

js的样式操作

获取样式 元素.style.xxx

修改样式 元素.style.xxx=‘xxx’

注意:如果操作的是带连字符-怎么办, background-color backgroundColor

还可以通过修改class属性,达到修改样式的目的

也可以通过修改link标签的href,达到修改样式的目的

虽然修改样式多种方法,但是不要混着用,容易出现权重的问题

js文本操作

获取文本 元素.innerHTML
修改文本(文本赋值) 元素.innerHTML=‘xxx’

js属性操作

获取属性的值:元素.属性
修改属性的值:元素.属性=‘xxxx’ className=‘xxx’
● 注意:如果要操作class 需要写className

数学方法

随机数:Math.random(); 0-1 不包含1

//0-1之间的随机数
 var a=Math.random();
console.log(a);
//想得到一个0-10之间的随机数怎么办  整数
parseInt(Math.random()*10+0);
//想要0-8之间的数
parseInt(Math.random()*8+0);
//10到20之间的数
parseInt(Math.random()*10+10)
//5-12之间的数   
parseInt(Math.random()*7+5)
// n-m之间的数 
parseInt(Math.random()*(m-n)+n)
function random(n,m){

    return parseInt(Math.random()*(m-n)+n)
    
}

四舍五入 Math.round(5.5) // 6

向上取整 Math.ceil(2.1) //3

向下取整 Math.floor(2.9) //2

绝对值 Math.abs(-1) //1

次方 Math.pow(2,3) 2的3次方 //8

平方根 Math.sqrt(9) //3

最大值 Math.max(1,2,3,4,5,6,7) //7

最小值 Math.min(1,2,3,4,5,6) //1

Π Math.PI //3.141592…

json对象

有属性方法的无序的键值对的集合

json对象的作用是:封装信息

为什么需要对象

保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组

如果用JS中的对象来表达,结构会更清晰

var person = {
     name: "刘帅",     //name 键     //刘帅 值
     age: "22",
     sex: "男",
     height: "175cm",
      };

对象里面的属性均是键值对

  • 键:相当于属性名。
  • 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)。
  • 对象的属性值可以是任何的数据类型,也可以是个函数:(也称之为方法)
json对象

数组 有序的数据集合 有顺序 有下标 有长度 for forEach

json 无序的键值对集合 没顺序 有键 没有长度 for-in

let json={键名:键值,键名:键值}

怎么使用

获取值

​ json.键名

​ json[‘键名’]

区别 [ ]里面可以放变量

设置

​ json.键名 =xxx

​ json[‘键名’]=xxx

修改

​ json.键名 =xxx

​ json[‘键名’]=xxx

键名不能重复

删除

​ delete json.键名

​ delete json[‘键名’]

遍历所有内容的

​ for-in 目的就是为了遍历对象

​ for(var 随便写的变量代表键 in 要遍历的对象){

​ //key json[key]

​ }

Bom(浏览器对象模型)

三个弹窗、定时器
open
  • 打开一个页面open(‘地址’)
  • 如果直接写,会被浏览器阻止,为了用户体验,不允许直接跳转
  • 用户必须操作后才可以跳转,必须在事件里面触发
close
  • 关闭一个页面 close(‘地址’)
地址栏
  • location是一个对象
  • location.href 地址 可以跳转页面的时候用
  • location.search 数据 ?后面的内容
  • location.hash 锚点 #后面的内容
  • location.reload() 刷新
历史记录
  • history
  • history.forword()前进
  • history.back() 后退
  • history.go(数字) 1前进一页 -1退回前一页 0当前页面刷新
浏览器信息

navigator.userAgent 可以获取浏览器信息

h5-localstorage 浏览器的本地存储

存:localStorage.setItem(key,value) 存进去的东西都会变成字符串

取:localStorage.getItem(key)

删除:localStorage.removeItem(key)

全部删除:localStorage.clear()

如何把对象变成字符串

JSON.stringify(对象) 转化成字符串

向浏览器存的如果是对象,先转化成字符串再存

把字符串如何变成对象

JSON.parse(字符串-里面是对象的样子) 转化成对象 从浏览器获取出来的如果是字符串的对象 先转化成真正的对象再用

事件触发时候,包含事件详细信息的对象。

函数触发的时候里面有个东西 event

event 不兼容低版本火狐。现在全部兼容

clientX/clientY 可视区的坐标

pageX/pageY 页面的距离坐标 兼容高级浏览器

cancelBubble 阻止事件冒泡

target 触发事件的目标元素

event.preventDefault() 阻止浏览器默认行为
  • 右键菜单
  • form表单的提交
  • 阻止浏览器选中
  • 阻止出现禁止标志

定时器

分两种定时器
每隔固定的时间执行

**setinterval **(要执行的函数,间隔时间) 间隔时间 毫秒数

固定的时间后,执行一次

setTimeout(要执行的函数,等待时间) 等待时间 毫秒数

清除定时器

clearinterval、clearTimeout [ 需要先定义一个timer ]

function fn1() {
  console.log("帅先生");
}
var timer1 = setTimeout(fn1, 3000);

function fn2() {
  console.log("帅二娃");
}

var timer2 = setInterval(fn2, 1000);
clearInterval(timer2);
clearTimeout(timer1);

案例:点击获取验证码的倒计时

 <body>
    <button id="btn">点击发送验证码</button>
  </body>
var aBtn = document.getElementById("btn");
var timer;
var n = 5;

function fn() {
    n--;
if (n == 0) {
 aBtn.innerHTML = "点击发送验证码";
 n = 5;
 clearInterval(timer);
 aBtn.disabled = false;
      } else {
 aBtn.innerHTML = n + "秒后重新获取";
      }
    }

aBtn.onclick = function () {
   fn();
aBtn.disabled = true;
 timer = setInterval(fn, 1000);
    };

案例:秒表

<div id="div1">
    <input type="text" value="00:00" />
    <button>开始计时</button>
    <button>暂停计时</button>
</div>

var oInp = document.getElementsByTagName("input")[0];
var aBtn = document.getElementsByTagName("button");
var n = 0;
var timer;

function toDUb(n) {
   if (n < 10) {
        return "0" + n;
      } else {
        return n;
      }
    }

function fn() {
     n++;
     var m = Math.floor(n / 60);
     var s = n % 60;
     oInp.value = toDUb(m) + ":" + toDUb(s);
  }
//开始
  aBtn[0].onclick = function () {
  timer = setInterval(fn, 1000);
  aBtn[0].disabled = true;
  };
//暂停
  aBtn[1].onclick = function () {
  clearInterval(timer);
  aBtn[0].disabled = false;
  };
//重置
  aBtn[2].onclick = function () {
  oInp.value = "00:00";
  clearInterval(timer);
  aBtn[0].disabled = false;
  n = 0;
 };

案例:本月还剩几天

  <p>本月还剩++</p>

var oP = document.querySelector("p");

//console.log(nowMoth);
var oDate = new Date();
var nowMoth = oDate.getMonth() + 1;
var nowYear = oDate.getFullYear();
//  console.log(nowYear);
var y = nowYear;
console.log(y);

var m = nowMoth;
function toMonth() {
  if (
    m == 1 ||
    m == 3 ||
    m == 5 ||
    m == 7 ||
    m == 8 ||
    m == 10 ||
    m == 12
    ) {
    return "本月有31天";
   } else if (m == 4 || m == 6 || m == 9 || m == 11) {
    return "本月有30天";
   } else {
     if (y % 400 == 0 || (y % 4 == 0 && y % 100 != 0)) {
     return "本月有29天";
    } else {
      return "本月有28天";
          }
        }
      }
      toMonth();
      console.log(toMonth(m));

获取可视区的大小

document.documentElement.clientWidth

document.documentElement.clientHeight

只兼容高级浏览器

物体的信息
物体占地大小 内容+padding+border
  • 元素.offsetWidth
  • 元素.offsetHeight
物体内容的大小,内容没有超出 内容+padding 超出了包含超出的大小
  • 元素.scrollWidth
  • 元素.scrollHeight
物体距离周边的位置 物体距离定位父级的距离,如果没有定位父级,距离body的距离
  • 元素.offsetLeft
  • 元素.offsetTop

获取出来的是数字不加单位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMjCSc7l-1662618687474)(https://iknow-pic.cdn.bcebos.com/0eb30f2442a7d933684f93f4aa4bd11372f00155?x-bce-process=image%2Fresize%2Cm_lfit%2Cw_600%2Ch_800%2Climit_1%2Fquality%2Cq_85%2Fformat%2Cf_auto)]

滚动的相关信息
滚动的距离

document.documentElement.scrollTop

document.documentElement.scrollLeft

滚动事件

window.onscroll

面向对象

面向过程和面向对象
面向过程

面向过程:先分析好的具体步骤,然后按照步骤,一步步解决问题。

优点:性能比面向对象高,适合跟硬件联系很紧密的东西,例如单片机就采用的面向过程编程。

缺点:没有面向对象易维护、易复用、易扩展。

面向对象

面向对象(OOP,Object Oriented Programming):以对象功能来划分问题,而不是步骤。

优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护。学会封装让别人去调用,把所有相同属性和方法的东西,都抽象成对象的过程

缺点:性能比面向过程低。

特点

1、都可以new出来

  • var arr =new Array()
  • var json =new Object()
  • var reg =new RegExp()
  • var data =new Data()

2、一堆属性和方法的集合

  • arr.length 属性
  • arr.push() 方法
  • data.getFullYear() 方法
为什么要面向对象

1、利于团队配合

2、提高效率、节约时间

面向对象的编程思想

面向对象的编程思想:对代码和数据进行封装,并以对象调用的方式,对外提供统一的调用接口。

创建对象:
1、单例模式、单体模式
var obj = {
    name: '李郝帅',
    age: 22
};


var singleDog = {
  name: "帅二娃",
  sex: "boy",
  age: "22",
  isBoy: true,
    // 还可以存放一个嵌套的对象
  
  //我们还可以在对象中增加一个方法。以后可以通过singleDog.catch()的方式调用这个方法 
  catch: function () {
    console.log("我是帅二娃!");
  },
};

var singleDog = new Object();
  singleDog.name = "帅二娃";
  singleDog.age = 22;
  singleDog.catch = function () {
  console.log("我是帅二娃!");
};
  console.log(singleDog);

缺点:一次只能造出来一只

2、工厂模式 new Object()
function createSingleDog(name, age) {
  //准备空白对象  准备原材料
  var SingleDog = new Object();
  //添加属性和方法   加工
    //向对象中添加属性
  SingleDog.name = name;
  SingleDog.age = age;
  SingleDog.catch = function () {
    console.log("我是帅二娃!");
  };
  //返回对象   将新的对象返回
  return SingleDog;
}

var c1 = createSingleDog("文崝", 25);
var c2 = createSingleDog("李郝帅", 35);
      console.log(c1, c2);

优点 :批量生产

3、构造函数模式
function createSingleDog(name, age) {
  this.name = name;
  this.age = age;
  this.catch = function () {
    console.log("我是帅二娃!");
  };
}
  /* 当在函数调用前加new:
          1.会在函数开始的时候创建一个空白对象。
          2.把this指向空白对象。(空白对象赋给this)
          3.在函数的最后会把加工后的对象返回出去。
 */

var c1 = new createSingleDog("文崝", 25);
var c2 = new createSingleDog("李郝帅", 35);
      console.log(c1, c2);

构造函数:是一种特殊的函数,主要用来创建和初始化对象,也就是为对象的成员变量赋初始值。它与 new 一起使用才有意义

构造函数就是函数,但是他的作用就是造对象,所以取名叫做构造函数。

在工作中,为了让程序猿一眼看来,他是造对象的构造函数,给他一个特征首字母大写

构造函数的创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。

优点;

性能更高,不用管初始化对象,不用管返回

new 一个构造函数的执行流程

new 在执行时,会做下面这四件事:

  1. 会在函数开始的时候创建一个空白对象。
  2. 把this指向空白对象。
  3. 执行构造函数里面的代码,给这个新对象添加属性和方法。
  4. 返回这个新对象(所以构造函数里面不需要 return)。
4、构造加原型混合模式

把变化的,需要的定制的放在构造函数里面,把不需要变化的,放在原型里面

优点:性能进一步提升,因为相同的东西只执行一遍,相同的东西都在原型(基因)里面继承下来

  function createSingleDog(name, age) {
  this.name = name;
  this.age = age;
}
createSingleDog.prototype = {
  catch: function () {
    console.log("我是帅二娃!");
  },
  sex: "nan",
};

var c1 = new createSingleDog("文崝", 25);
var c2 = new createSingleDog("李郝帅", 35);
console.log(c1, c2);
c1.catch;
c1.sex();
常用布局
定宽布局

大部分用float

外面的容器是定宽, 里面的内容用百分比 里面的内容也可以放缩

最大值最小值定宽 min-width max-width width:100%

响应式布局

利用媒体查询

在不同终端都能适配的一种布局。

手机,pad,电脑屏幕

移动端刚刚出来。如果要写一个官网,则移动端写一个,pc端写一个,pad端写一个

能不能写一套代码,所有浏览器都适用。

自适应布局

弹性布局+rem布局

媒体查询

根据屏幕的宽度来进行判断

不同的尺寸写不同的样式。虽然是一套代码,但是是多套样式

有很多局限性

1、结构有局限性

2、不能特别复杂

媒体查询用于什么地方

1、简单的官网

2、都是产品的商品网站

3、文档类的网站

用媒体查询做一些小块的修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值