说明:本篇文章记录的是我在初学JS的过程中自己总结的经验或者是与Java不同然后要补充的内容或者是自己需要注意的点
文章目录
day01
总结:牢记JS的组成,对之后的学习有帮助,不然用到document的方法还不知道为什么要这样写;了解三种打印语句的特点,能通过打印来分析问题
JS的组成
- DOM:文档对象模型,document,是网页的抽象,提供了网页操作
- BOM:浏览器对象模型,window,是浏览器的抽象,提供了浏览器窗口的操作
- ECMAScript:js的语法,规范,规定了,以什么样的格式或语法编写js
三种打印语句详解
document.write();
(打印到页面)- 不阻塞程序执行
- 以字符的形式打印数据
- 可以打印多个数据
- 可以解析标签
alert();
(打印到弹出框)- 阻塞程序执行
- 以字符的形式打印数据
- 同时只能打印一个数据
console.log();
(打印到控制台)- 不阻塞程序执行
- 保持数据原有格式打印
- 可以打印多个数据
- 不会影响页面格式
- 也称静默打印,在页面上没有提示,不打开控制台看不到打印信息
typeof 的使用
typeof的执行结果是以字符的形式,显示当前的数据类型
注意点:
- typeof的类型都是字符,如
console.log(typeof typeof true);
的结果为string - NaN的类型是number
day02
关系(比较)运算符的类型转换
无隐式类型转换
1.数值的比较规则:数值大小比较
var a = 101;
var b = 20;
console.log( a > b ); // true
console.log( a >= b ); // true
console.log( a < b ); // flase
console.log( a <= b ); // flase
2.字符的比较规则:逐位比较,得到结果就停止
var a = "19999999";
var b = "20";
console.log( a > b ); //false
console.log( a >= b ); //false
console.log( a < b ); //true
console.log( a <= b ); //true
3.不存在隐式类型转换,严格比较,除了比较值,还要比较类型
console.log(a === b); //false
console.log(a !== b); //true
隐式类型转换
当两边只要有一个是数值型数据,比较规则都是数值的比较规则
var a = "101";
var b = 20;
console.log( a > b ); //true
console.log( a >= b ); //true
console.log( a < b ); //flase
console.log( a <= b ); //flase
var a = "10";
var b = 10;
console.log(a == b); //true
console.log(a != b); //false
数据类型转换
隐式类型转换
计算过程中不按照原本的数据类型计算,而是作为其他数据类型计算
场景:运算符
+号有两种含义:数学中的+号运算符;字符串的拼接。优先字符串拼接,所以在检测到+号左右两边存在字符串的时候,会自动将另一边不是字符串的数据,转成字符串,再进行操作
规则
- 其他转数值
- 其他转布尔
- 其他转字符
显示(强制)类型转换
1.其他转数值
规则
严格转换
必须全部为数字,才能转成数值,否则NaN
例子 : “hello” — NaN,“123a12” — NaN,“12312” — 12312
非严格转换
从左向右检测,遇到第一个非数字的字符,停止转换;第一个字符就非数字,直接NaN
例子 : “123a12” — 123,“hello” — NaN,“a1231” — NaN
方法
parseInt()
- 一般用来字符转数值
- 非严格转换,不能识别小数点
parseFloat()
- 一般用来字符转数值
- 非严格转换,能识别小数点
Math.round()
- 一般用来字符转数值
- 严格转换,四舍五入取最近的整数
Number()
- 一般用来其他转数值
- 严格转换,能识别小数点
- true转成1,false转成0
- 空数组转成0,只能转换数组长度为1且数据类型为可以转换成数字的数组
- null转换成0
- 除了以上的情况外其他的数据全部转成NaN
2.其他转布尔
规则:
- 字符:非空字符为true,空为false
- 数值:非0为true,0为false
- 对象数组函数:都是true
- undefined,null,NaN:都是false
方法:Boolean()
3.其他转字符
规则:
- 默认,类似于直接给数据添加引号
- 保留n为小数,存在四舍五入
- 对象默认转成:[object Object]
方法:
-
num.toString();
- 返回一个表示指定数字的字符串
- 对于基数大于10的字母,字母表示大于9的数字。例如,对于十六进制数字(基数为16),使用a至F。如果未指定基数,则假定首选基数为10。
-
num.toFixed(n);
- 把数字转换为字符串,结果的小数点后有指定位数n的数字
- 无法把整数小数化
- 解决方法:
function toFixed(num,d){ num *=Math.pow(10,d);// Math.pow( num ,a) 方法 返回 num 的 a 次方,所以这里巧妙的利用了这个方法以达成目的 num = Math.round(num); return num/(Math.pow(10,d)); }
-
String();
- 把对象的值转换为字符串
- String() 函数返回与字符串对象的toString()方法值一样
JS中的三大特殊数据
undefined
- undefined:未赋值,类型是undefined
- 如何判断是不是undefined
- typeof(要判断的值或变量)
- console.log( (typeof undefined) === “undefined” );// 结果是true布尔值:true为真,false为假
- typeof(要判断的值或变量)
null
- null:空,类型是object
- 如何判断是不是null
- typeof和关系运算符判断(typeof 要判断的值或变量 === “object”)
- console.log( (typeof null) === “object” );// 结果是true布尔值:true为真,false为假
- typeof和关系运算符判断(typeof 要判断的值或变量 === “object”)
undefined和null的特殊之处
- undefined和null在关系运算符两边隐式类型转换后,得到了一致的数据
- console.log(Boolean(undefined))
console.log(Boolean(null))
结果都为false,但是与false比较的结果为false! - console.log( undefined == null )结果为true
- console.log( undefined === null )结果为false(即值相等类型不相等)
- console.log(Boolean(undefined))
- undefined被Number转成NaN,null被Number转成0
NaN
- NaN:not a Number,不是一个数字
- 数据类型是:数值型
- 表示非法的运算,或错误的转换
- 如何判断是不是NaN
- isNaN(要检测的数据或变量)
- true:是NaN
- false:不是NaN
- isNaN(要检测的数据或变量)
- NaN与任何数据都不相等,包括它本身
浮点数的精度问题
- 因为计算中的数据在运算时会被转成二进制,计算结束后又会从二进制转回十进制
- 二进制中也存在无限数字,计算系统的位数有限,省略某些位数,导致一些小数的计算不精确
- 目前的解决方法:限制计算的小数位数,再将其转换成浮点型(parseFloat(x.toFixed(n)))
Boolean中的逻辑短路
-
或的逻辑短路:
- 一个true真,一个false值,取true值
- 都是true值,取第一个true值
- 都是false值,取最后一个false值
-
且的逻辑短路规则
- 一个true真,一个false值,取false值
- 都是true值,取最后一个true值
- 都是false值,取第一个false值
day03
分支语句
1.多分支switch(){}
注意:switch(值)不仅仅是数值,也能是字符串,也能是其他类型的值,只要和case中的值比较的结果为true就执行
例子JavaScript基础篇的3.函数第二题
switch(值){
case 值1:
...
break;
case 值2:
...
break;
...
default:
...
}
例子:根据成绩判断成绩等级
思路:用if-else很好写出来,因为是需要判断的是范围,但是硬要用switch写的话也能写
第一种:不破坏switch语义的情况,用除十取整的方法,这样写的话当分数大于100的时候有问题,100~109都会被计算在case10内
switch(Number(parseInt(number/10).toFixed(0))){
case 0:{
// document.getElementById("result").innerHTML="不及格";
// break;
}
case 1:{
// document.getElementById("result").innerHTML="不及格";
// break;
}
case 2:{
// document.getElementById("result").innerHTML="不及格";
// break;
}
case 3:{
// document.getElementById("result").innerHTML="不及格";
// break;
}
case 4:{
// document.getElementById("result").innerHTML="不及格";
// break;
}
case 5:{
// 不用break结束就会case穿透,可以用case穿透简化代码
//简化过程:
// 1.分类:将结果一样的case放在一起;
// 2.按照顺序排列在一起,保留最后一个case要执行的语句,删除除了最后一个case的执行语句;
document.getElementById("result").innerHTML="不及格";
break;
}
case 6:{
document.getElementById("result").innerHTML="及格";
break;
}
case 7:{
document.getElementById("result").innerHTML="及格";
break;
}
case 8:{
document.getElementById("result").innerHTML="良好";
break;
}
case 9:{
document.getElementById("result").innerHTML="优秀";
break;
}
case 10:{
document.getElementById("result").innerHTML="优秀";
break;
}
default:{
alert("请输入正确的成绩")
}
}
这里用到了case穿透
不用break结束就会case穿透,可以用case穿透简化代码
简化过程:
1.分类:将结果一样的case放在一起;
2.按照顺序排列在一起,保留最后一个case要执行的语句,删除除了最后一个case的执行语句;
第二种:破坏switch语义的情况,不易于语义话的switch写法,因为变量为真,而且case没有顺序可言(case为true就执行),不利于程序的阅读和维护
switch(true){
case number<60:{
document.getElementById("result").innerHTML="不及格";
break;
}
case number>=60 && number <=79:{
document.getElementById("result").innerHTML="及格";
break;
}
case number>=80 && number <=89:{
document.getElementById("result").innerHTML="良好";
break;
}
case number>=90 && number <=100:{
document.getElementById("result").innerHTML="优秀";
break;
}
case number>100:{
alert("请输入正确的成绩")
document.getElementById("result").innerHTML="请输入正确的成绩";
break;
}
}
单双分支和多分支的区别
- 分支的嵌套,嵌套之后,if-else也可以实现多分支效果
- if的()内放的是判断条件,条件是一个范围
- if适合处理范围的分支条件
- switch的()内放的是要判断的变量,是一个具体的值
- switch适合处理具体值的判断
- if的()内放的是判断条件,条件是一个范围
if的小括号内会发生隐式类型转换
if()中只需要布尔值,那么在if判断中,会把括号内所有的数据类型,都隐式转换成布尔型。
- 其他转布尔规则
- 字符:非空为true
- 数值:非0为true
- 函数,对象,数组,都是true
- undefined,null,NaN,都是false
day04
循环语句之间的区别
- while和do-while
- do-while在条件为false时,会执行一次,而while不会
- while和for
- while的三要素更灵活,更适合处理不确定次数的循环
- for的三要素更集中,更适合处理确定次数的循环
循环的嵌套
解决多行多列的结构
- 外层循环控制行
- 内层循环控制列
day05
函数
1.创建(定义,声明)函数
- 声明式:利用声明关键字:function
function 函数名(){}
- 赋值式:利用赋值运算符给变量赋值
var 变量名 = function(){}
2.函数的分类(根据写法)
- 有名函数:
function 函数名(){}
- 正常函数,可以正常使用
- 无名函数
function(){}
- 非正常函数,不能直接使用,只能作为值存在
- 用法:
- 赋值式创建函数:
var 变量名 = function(){}
- 事件处理函数:
事件源.on事件类型 = function(){}
- 作为匿名函数的函数体:
(function(){})()
- 赋值式创建函数:
- 匿名函数
(function(){})()
- 自动执行,立即执行的函数
- 专用来生成一个新的作用域
3.函数的入口 - 参数
- 参数的数量和类型都没有限制:任意个任意类型
- 数量对应关系:
- 数量一致,一一对应的关系
- 形参多,多出来的形参是undefined
- 实参多,多出来的实参,没有被形参接收
4.arguments
- 专属于函数内部的数组对象
- 用来保存当前函数的所有的实参(不受形参的数量影响)
- 数组形式,要想使用数组内的数据,必须先解析数组
- 数组的解析
- 索引[]+长度length
- 数组的解析
- 使用情况
- 当函数的参数的个数不确定时,使用arguments
- 当函数的参数的个数确定时,使用对应个形参
实例:
// 编写函数,实现任意个任意数字的和
//用arguments接收数据,再通过索引遍历处理
var sum=0;
function add(){
for(var i=0;i<arguments.length;i++){
sum+=arguments[i];
}
return sum;
}
console.log(add(1,1,1,1,1));
5.函数的出口 - 返回值return
- 官方定义 return语句将终止当前函数并返回当前函数的值
- 关键字:
return 要返回的数据或变量
- return的功能
- 返回当前函数的值
- 立即结束函数
- 一个函数只能有一个返回值,执行到返回值之后,函数会直接结束
- 返回值可以返回任何数据
- 如果函数内部没有return,默认返回undefined
- return将某一状态返回到调用其所在函数的地方
- retrun true; - 返回正确的处理结果
- return false; - 返回错误的处理结果,终止处理
- return; - 把控制权返回给页面
6.调用函数加括号和不加括号的区别
- JS函数被调用时加括号表示执行的是函数里面的代码,即花括号的部分,不包括整个函数体
- JS函数被调用时不加括号表示执行的是整个函数体,目的是引用,代表把这个函数赋值给某个变量
7.函数的使用
- 直接使用:函数()
- 事件绑定使用
day06
作用域
作用域:变量或函数,生效的区域
作用域中变量的读写规则:
- 读(使用):
- 在当前作用域中查找,如果找到了就使用并停止查找,没找到就依次向上级作用域中查找,直到全局作用域,如果都没找到就报错
- 写(赋值):
- 在当前作用域中查找,如果找到了就修改并停止查找,没找到就依次向上级作用域中查找,直到全局作用域,如果都没找到就声明一个全局,再修改(非严格模式)
在js中存在一个顶层对象,所有的全局变量或函数,都会自动添加到顶层对象身上,顶层对象:window
- 如果主动给window绑定了变量或全局,意味着声明了一个全局的变量或函数
声明提升
var的声明提升
- 声明会提前到作用域最开始的位置
- 原位赋值(值不会提升)
function的声明提升
- 整体提升到作用域最开始的位置
当var遇到function
- 赋值式创建函数:var fn = function(){}
- 提升的是var
- 重名
- var提升的更高,function其次,所以function覆盖了var的变量,function生效
递归
在函数内部调用自身
// 递归
function fn(){
fn();
}
fn();
递:函数不断执行自身的过程
归:函数执行结束会后,返回数据的过程
递归的特点:
- 消耗性能
- 有可能会造成内存泄漏
- 递归表达了一种编程思路
- 能少用尽量不用,必须使用谨慎使用
对象
创建对象
- 字面量:
var obj = {}
- 构造函数:
var obj = new Object()
注意:任何两个对象都不相等,如果相等则为同一对象
对象的分类
- 宿主对象:window,document,提供了执行环境的平台对象
- 本地对象:特殊的对象,是一种构造函数,需要被new执行后,才能得到真正的对象
- Object,String,Number,Boolean,Array,Function,Date,RegExp,…
- 本地对象的首字母都是大写
- 使用
- 直接使用:String.fromCharCode(),…
- 执行使用:String(),Number(),Boolean(),…
- new使用:new Object(),…
- 内置对象:js提供的可以被直接使用的对象
- Math:数学对象
- Math.round()
- Math:数学对象
对象的使用语法
- 点:当对象的属性是一个具体的值时
- obj.name
- obj.age
- 中括号:当对象的属性不是一个具体的值,是变量时
- obj[“name”]
- obj[“age”]
对象的长度不能用.length获取,用js原生的Object.keys可以获取到
const obj = {'name' : 'Tom' , 'sex' : 'male' , 'age' : '14'};
const arr = Object.keys(obj);
console.log(arr); // ['name','sex','age']
console.log(arr.length); //3
对象的遍历
for-in
day07
数组
数组:数据的组合,数据的一种集合形式
- 数组是数据的有序集合
- 对象是数据的无序集合
- 当需要操作多个同类数据时就需要使用数组
创建数组
- 字面量:var arr = [];
- 构造函数:var arr = new Array();
- 区分:当创建时,有且只有一个数值型数据,字面量认为就是数据,构造函数认为是长度
- 例子
// 构造函数创建一个长度为3的空数组
var arr = new Array(3);
// 构造函数创建一个长度为2的数组,arr[0]=3,arr[1]=4
var arr = new Array(3,4);
操作数组
直接使用:索引+长度(数组最本质的操作)
- 增:给数组不存在的位置设置数据
- 增加的数据,默认只能往数组的最后增
- 删:减少数组的长度
- 删除数组末尾的数据
- 改:重新赋值就是该
- 查:根据索引查询指定位置
数组的方法底层逻辑都是索引+长度(数组最本质的操作)
需求:在数组的任意位置插入数据
实现:插入只能在最后插入,所以将要插入的位置的后面的数据一个个往后面一个赋值达到覆盖,最后将要插入的数据赋值给要插入的位置即可
var arr = [0, 1, 2, 3, 4];
// arr[n]=arr[n-1];
// 插入倒数第二位
arr[5]=arr[4];
arr[4]=5;
console.log(arr);
// 插入第一位
arr[5]=arr[4];
arr[4]=arr[3];
arr[3]=arr[2];
arr[2]=arr[1];
arr[1]=arr[0];
arr[0]=5;//插入的数据赋值到要插入的位置
console.log(arr);
优化代码
// 循环实现
for (let i = 5; i > 0; i--) {
arr[i] = arr[i - 1];
}
arr[0]=5;
console.log(arr);
用函数实现
// arr为操作的数组,n为要插入的位置,data为要插入的数据
function insertArray(arr, n, data) {
for (let i = arr.length; i > n; i--) {
arr[i] = arr[i - 1];
}
// 将要插入的数据赋值到要插入的位置
arr[n] = data;
// 返回插入后数组的长度
return arr.length;
}
// 如果插入的位置超过arr.length+1,则从arr.length+1到插入的位置的数据都为empty
console.log(insertArray(arr, 0, 5));
console.log(arr);
以上为推导过程,至此,这个函数已经完成封装,可以放到工具类里面,方便以后调用
需求:删除数组长度范围内任意位置
实现:删除只能在最后删除,所以将要删除的位置的后面的数据一个个往前面一个赋值达到覆盖,最后把数组长度-1即可
删除数组长度范围内任意位置的函数方法推导也如上,这里就不进行推导了,直接写封装函数
// arr为操作的数组,n为要删除数据的位置
function deleteArray(arr, n) {
for (let i = n; i < arr.length; i++) {
arr[i] = arr[i + 1];
}
arr.length -= 1;
return arr.length;
}
// 如果删除超过数组长度则删除arr.length位置的数据
console.log(deleteArray(arr, 0));
console.log(arr);
数组的方法
JavaScript Array 参考手册
数组的分类
- 数组内都是字符数据,字符数组
- 数组内都是数值数据,数值数组
- 数组内都是对象数据,json数组
- 数组内都是数组数据,多维数组
数组内复杂数据的操作
- 逐层解析
数据的深浅拷贝
根据数据在内存中的存储形式分类
- 值传递的数据(基本数据)
- 字符,数值,布尔,undefined,null
- 值就是地址,地址就是值
- 复制时,复制的是值
- 引用传递的数据(复杂数据)
- 对象,数组,函数
- 地址是地址,值就是值
- 复制时,复制的是地址,修改其中一个数据,会影响另一个数据
深浅拷贝(复杂数据,引用传递的数据)
- 浅拷贝:引用传递的数据,复制时,复制的是地址,导致修改新数据,会影响老数据
- 深拷贝:复制值
- 借助对象的遍历
for-in
(不会遍历空数据)
- 借助对象的遍历
排序算法
冒泡排序
- 两两比较,大的放后面
选择排序
- 将第n位和后面所有数据做比较,得到最小的,和第n位交换
两者区别
- 冒泡是一直在操作数组中的数据,只要发现后面的大就进行交换,比较耗费性能
- 选择是找到小的数据赋值给一个变量,在内循环结束后才对数组中的数据进行操作,比冒泡耗费的性能少一些
day08
严格模式
"use strict"
建议开启方式:整个代码文件包裹在一个匿名函数中,匿名函数内先开启严格模式,再进行编程
(function () {
"use strict"
// 在这里面写代码
})();
字符
创建字符
- 字面量:var str = “”;
- 构造函数:var str = new String();
字符的操作
- 索引+长度,只能查,不能改
字符的使用
- 字符是原始数据
- 字符串的拼接:+ 号
- 引号必须成对出现
- 单双引号必须嵌套使用
字符的方法
JavaScript String 参考手册
day09
字符编码和字符集
字符转Unicode编码
str.charCodeAt(0)
Unicode编码转字符
String.fromCharCode(20013)
Unicode编码的格式:
- \u开头,跟四位的十六进制。浏览器能直接识别U编码
需要记忆的Unicode编码(字母比较的是Unicode编码大小)
- 97~122( a ~ z)
- 65~90( A ~ Z)
- 48~57( 0 ~ 9 )
- 4E00-9FA5(基本汉字)
对象的补充
概念:存储数据,一个对象,描述了一个事物
- 数据的无序集合
本质:键值对
意义:存储数据,编程
优势:提升了数据的查找和传输速度
操作:点,中括号
分类:宿主,本地,内置
在内存中的存储形式:复杂数据,地址(栈)==>值(堆)
- 简单的赋值拷贝,复制的是地址,不是值,存在深浅拷贝
删除对象的属性
- delete 对象.属性
js的顶层对象window
- 所有的全局都会自动绑定到window对象
- 只要给window对象绑定了属性,相当于声明了一个全局
Math(数学对象)
内置对象:可以直接使用
Math的属性
- Math.PI;//约等于3.14159
Math的方法(只能是数据,不能是数组,否则结果为NaN)
- Math.round(3.6); //四舍五入 4
- Math.max(a,b); //返回较大的值
- Math.min(a,b); //返回较小的值
- Math.abs(num); //返回绝对值
- Math.ceil(3.6); //向上取整 4
- Math.floor(3.6); //向下取整 3
- Math.pow(x,y); //x的y次方
- Math.sqrt(num); //开平方
- Math.sin(x); //x的正弦值,返回值在-1到1之间
- Math.cos(x); //x的余弦值,返回值在-1到1之间
- Math.random(); //返回一个大于等于0到小于1的随机数
限定min-max范围的随机数
// 两个数的输入顺序不影响结果
function random(max,min){
return Math.round(Math.random()*(max-min)+min);
}
Date(日期对象)
本地对象:构造函数,可以被new执行,也可以直接使用
获取日期
- 直接获取系统日期:new Date()
- 获取系统日期之后,单独获取每个部分:日期对象的get系列方法
- 获取时间戳
// 直接获取系统日期
var d = new Date();
console.log(d);
console.log(typeof d); // object
// 获取系统日期之后,单独获取每个部分
console.log(d.getFullYear())
console.log(d.getMonth()) // 0~11
console.log(d.getDate())
console.log(d.getDay()) // 0~6(0为周日)
console.log(d.getHours())
console.log(d.getMinutes())
console.log(d.getSeconds())
console.log(d.getMilliseconds())
// 获取时间戳:从1970.1.1 0:0:0 到此刻过去了多少毫秒数
//为什么从1970.1.1 0:0:0开始,下面是解释链接
//https://cloud.tencent.com/developer/article/1630408
console.log(d.getTime());
console.log(Date.now());
设置日期
- 创建时设置
var date = new Date("2021.08.26 17:08:8");
- 字符
- 一个参数
- 没有设置的部分归0
- 超出上限部分,Invalid Date
- 月份的范围:1~12
- 数值
- 多个参数
- 没有设置的部分归0
- 超出上限部分,向前进1
- 月份的范围:0~11
- 字符
- 创建后设置
// 没有设置的部分,以当前时间为准
// 超出上限部分,向前进1
// 月份的范围:0~11
var date = new Date();
date.setFullYear(2021);
date.setMonth(8);
date.setDate(26);
date.setHours(17)
date.setMinutes(10)
date.setSeconds(8)
date.setMilliseconds(8)
console.log(date)
- 设置时间戳
setTime(number)
- 从1970年1月1号 0:0:0过去了指定的毫秒数
计算两个日期之间的差值
- 先获取两个指定的日期,再获取时间戳,相减,之后根据相差毫秒数计算天,时,分,秒
day10
BOM
BOM的介绍
- BOM:浏览器对象模型,是浏览器的抽象,抽象成了window对象
- 提供了浏览器的窗口操作
- BOM缺乏标准,沿用了ECMAScript的标准
- BOM提供了ECMAScript的运行平台,ECMAScript在使用某些方法时,也需要遵守浏览器的规定
- window也是js的顶层对象。ES6版本以下,所有的全局都会自动绑定到window
- window身上有很多子对象,window自身也提供了很多方法和属性
- 所谓window的方法,其实就是内置的全局函数
- 所谓window的事件,其实就是浏览器的事件
window的方法
- 弹出框系列
- alert() //弹出信息框
- prompt() //弹出对话框
- confirm() //弹出决定框
- 窗口操作
- open() //打开新窗口
- close() //关闭当前窗口
- 计时器
-
setInterval( functioin(){}, time)
- 功能:计时器,随着时间的流逝,执行代码(每隔指定时间,执行指定代码)
- 参数
- 参数1:回调函数
- 参数2:毫秒数
- 返回值
- 当前计时器的唯一标志,用来被清除使用
-
clearInterval()
- 功能:清除计时器
- 参数:要清除的计时器的唯一标志
- 返回值:无
-
setTimeout( functioin(){}, time)
- 功能:延时器,延迟指定时间,执行指定代码(只执行一次)
- 参数
- 参数1:回调函数
- 参数2:毫秒数
- 返回值:当前延时器的唯一标志,用来被清除使用
-
clearTimeout()
- 功能:清除延时器器
- 参数:要清除的延时器的唯一标志
- 返回值:无
-
window的事件
- load:加载完成
- 页面结构:正常标签
- 页面资源:某些标签引入的外部资源
- 如:img的src,link的href,script的src,…
- resize:改变大小
- 获取页面可视区域的尺寸
- scroll:滚动
- 获取滚动的距离
window的子对象
- document:文档,页面
- history:历史记录
- 属性:
- 历史记录的个数
- history.length
- 历史记录的个数
- 方法:
- 后退
- history.back()
- 前进
- history.forward()
- 前进或后退指定步数
- history.go(n)
- 正:前进
- 负:后退
- 0:刷新
- history.go(n)
- 后退
- 属性:
- location:地址栏
- 属性:既可以获取又可以设置
- 完整地址:location.href
- 查询数据(向后端发送的数据):location.search
- 锚点链接(哈希值):location.hash
- 路径:location.pathname
- 域名地址(域名+端口):location.hostname
- 域名:location.host
- 端口:location.port
- 方法
- 刷新
- location.reload()
- 跳转
- 跳转到当前地址:location.assign("")
- 跳转到指定地址:location.assign(“url”)
- 刷新
- 属性:既可以获取又可以设置
- navitagor:浏览器信息
- screen:窗口
- frames:框架
DOM
DOM的介绍
- DOM:文档对象模型,document,提供了网页的操作
- DOM的结构:树状结构,家族结构
- DOM的每一个组成的成份,都叫节点!每种节点的js数据类型都是对象
- 元素节点,文本节点,属性节点,注释节点,根节点
- 操作DOM中的某个节点,必须要先选中,需要使用选择器
- 选中元素之后的操作:属性操作,样式操作,内容操作,元素自身操作
DOM的选择器
- 按照选择到的数量划分
- 单个:就算有多个符合条件,也只能选中第一个
- id,querySelector,parentNode,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling
- 多个:就算只有一个符合条件的元素,也是以数组的形式存在,注意解析数组之后,才能操作这个元素
- className,tagName,name,querySelectorAll,children,childNodes,attributes
- 单个:就算有多个符合条件,也只能选中第一个
- 按照选择的关系划分
- 直接选择
- id,className,tagName,name,querySelector,querySelectorAll,document
- 间接选择(必须有一个基准元素)
- children,parentNode,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling,childNodes,firstChild,lastChild,previousSibling,nextSibling,ownerDocument,attributes
- 直接选择
- 按照选中的节点类型划分
- 元素节点选择
- id,className,tagName,name,querySelector,querySelectorAll,children,parentNode,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling
- 其他节点选择
- childNodes,firstChild,lastChild,previousSibling,nextSibling,document,ownerDocument,attributes
- 元素节点选择
day11
节点操作(节点的过滤)
节点类型:nodeType
节点名:nodeName
节点值:nodeValue
元素的样式操作
行内样式
- 设置:元素.style.css属性 = “新的css值”
- 获取:元素.style.css属性
非行内样式
- 设置:不能设置
- 获取:getComputedStyle(元素).css属性
总结
- 获取:使用非行内样式获取
- 注意:getComputedStyle有兼容,不兼容低版本IE浏览器
- IE浏览器专用方式:元素.currentStyle.css属性
- 注意:getComputedStyle有兼容,不兼容低版本IE浏览器
- 设置:使用行内样式的设置
封装兼容处理
// 获取样式的兼容封装
// 这里用了判断的隐式类型转换,如果ele.currentStyle存在则用IE方式,如果不存在undefined
function getStyle(ele, attr) {
return ele.currentStyle ? ele.currentStyle[attr] : getComputedStyle(ele)[attr];
}
元素的属性操作
html属性:<元素名 属性名=属性值 属性名=属性值>内容</元素名>
- 获取:元素.getAttribute(“属性名”)
- 设置:元素.setAttribute(“属性名”, “属性值”)
- 删除:元素.removeAttribute(“属性名”)
- 内置的html属性,在js中都有对应,所以内置的html属性也可以使用js属性的操作方式
js属性:在js中可以直接使用对象的操作进行操作
- 增删改查:参考对象语法
- .innerHTML(插入HTML中的内容,可以解析标签)
- .innerText(插入HTML中的内容,不能解析标签)
- .value(获取表单控件的内容)
day12
元素操作
增
- 创建元素节点
- document.createElement(“标签”)
- 插入到指定父级的最后一个子
- .appendChild(标签名)
删
- 直接删除(.remove())
- 根据父删除指定子
- document.body.removeChild()
改(不推荐使用)
- .outerHTML
查:选择器
尺寸类快速获取属性
只能获取到css中的width值
- getComputedStyle().width
width + padding
- .clientWidth
width + padding + border
- .offsetWidth
完整的内容区域(包括可滚动的区域)
- .scrollHeight
获取元素相对于包含块偏移的位置(margin + position)
- .offsetLeft
即可获取,又可设置滚动条滚动的距离
- .scrollTop
事件
绑定事件的方式:on绑定
- 元素.on事件类型 = 函数
事件源:绑定事件的元素:this
事件目标:触发事件的元素:事件对象.target(IE:事件对象.srcElement)
事件目标的兼容
var obj = event.srcElement ? event.srcElement : event.target;
// 或者
var evtTarget = event.target || event.srcElement;
on:是一种绑定方式
事件类型:事件的触发方式
事件处理函数:当触发事件时,要执行的功能
键盘事件只能加给有焦点的元素,如果页面上没有这种元素,或者本来就不是为了给这个元素添加键盘事件,只能加给document
事件对象:
- 记录了当前事件发生过程中产生的所有信息,比如:鼠标点击的位置,按下了键盘上的哪个键
事件对象
事件对象的特点
- 事件对象只能在事件发生过程中才会产生
- 事件结束后,事件对象就会被释放
- 事件处理函数就是当前事件要的功能
- 所以事件对象只能在事件处理函数中拿到
获取事件对象(兼容)
- 正常浏览器:事件处理函数的第一个参数
- IE浏览器:在事件处理函数中通过window.event获取
鼠标事件对象身上的常用属性
- target / srcElement(IE) // 事件目标
- type // 事件类型
- offsetX/Y //相对于事件目标的坐标位置
- clientX/Y // 相对于浏览器的可视区域
- screenX/Y // 相对于显示器的坐标
- button // 获取按下的是哪个鼠标键(兼容)
- buttons // 获取按下的是哪个鼠标键(兼容)
键盘事件对象身上的常用属性(键盘事件只能加给有焦点的元素,如果都没有则给document加)
- keydown //键盘按键按下
- keyCode/which(IE) // 获取键码(兼容)
day13
事件流
事件的执行顺序
- 多层元素嵌套时,元素之间的相同事件触发顺序,叫事件流
- 事件流的三个阶段
- 事件捕获:从外向内
- 需要配合事件监听式绑定事件才能实现事件捕获
- 目标阶段:真实要触发的元素的事件
- 事件冒泡:从内向外,浏览器的默认事件流
- 某些情况下,事件冒泡会对程序造成影响,此时需要阻止事件冒泡
- 事件捕获:从外向内
阻止事件冒泡
- 找事件对象
// 阻止事件冒泡的兼容封装
function stopBubble(e){
if(e.stopPropagation){
// 正常
e.stopPropagation()
}else{
// IE
e.cancelBubble = true;
}
}
绑定事件和删除事件的方式
- 赋值式(DOM0级事件绑定)无法重复绑定相同事件
- 绑定
- 事件源.on事件类型 = 事件处理函数
- 删除
- 事件源.on事件类型 = null
- 绑定
- 监听式(DOM2级事件绑定)可以重复绑定相同事件
- 绑定
- 正常浏览器:事件源.addEventListener(“事件类型”, 事件处理函数, 事件流的状态)
- IE浏览器:事件源.attachEvent(“on事件类型”, 事件处理函数)
- 删除
- 正常浏览器:事件源.removeEventListener(“事件类型”, 事件处理函数, 事件流的状态)
- 删除时,删除的事件处理函数必须要绑定的事件处理函数是同一个
- 提前给事件处理函数起名
- 删除时,删除的事件处理函数必须要绑定的事件处理函数是同一个
- IE浏览器:事件源.detachEvent(“on事件类型”, 事件处理函数)
- 删除时,删除的事件处理函数必须要绑定的事件处理函数是同一个
- 提前给事件处理函数起名
- 删除时,删除的事件处理函数必须要绑定的事件处理函数是同一个
- 正常浏览器:事件源.removeEventListener(“事件类型”, 事件处理函数, 事件流的状态)
- 绑定
默认事件
没有主动添加,默认自带的事件
如何阻止
- 正常浏览器阻止默认事件
- e.preventDefault();
- IE浏览器阻止默认事件
- e.returnValue = false;
- return false
- 只能最后使用,如果在前面使用则后面的代码都不会执行
事件委托
将多个子元素的相同事件,添加给页面上现存的共同的父元素,利用事件冒泡的原理,通过事件目标找到真正触发事件的元素的过程,是事件委托
优势
- 节省性能
- 可以给页面上暂时不存在的元素绑定事件(可以在用js获取之后操作页面上本来没有的元素)
day14
正则
正则
- 正确的规则,约束字符串的规则,自身类型是对象,正则对象,也可以作为值操作,正则表达式
- 在网页上收集到的用户的所有信息都是字符,正则验证或操作这些字符
- 如:从字符串中"hjsgdvh1123yf435uir2tgut847r76f"拿出所有的数字,放在一个数组中,用正则
var arr = str.match(/\d+/g);
,如果不用正则,就需要遍历这个字符串,然后一个个比较是否为数字,如果是才放入数组中 - 意义
- 节省开发者操作
- 没有提升性能
创建正则
- 字面量:var reg = /a/;
- 构造函数:var reg = new RegExp(“a”);
- 构造函数可以根据变量创建正则(与字面量的区别)
使用正则
- 验证
- reg.test(str);
- 查询
- str.search(reg);
- str.match(reg);
- reg.exec(str);
- 替换
- str.replace(reg, newStr);
正则的写
- 正则的符号
- 转义符
- \d 数字
- \w 数字字母_
- \s 空格
- \D 非数字
- \W 非数字字母_
- \S 非空格
- \ 转所有
- 修饰符
- g 全局
- i 忽略大小写
- 量词
?
前一个匹配出现1个或0个+
前一个匹配出现1个或以上*
前一个匹配出现0个或以上{n}
前一个匹配指定的n次{n,}
前一个匹配至少n次,无上限{n,m}
前一个匹配至少n次,最多m次
- 转义符
day15
正则
特殊字符
|
或[]
中元符,表示范围,内的每个规则之间都是或关系,可以用-把范围连接起来[^]
非,中元符中使用上箭头表示非,除了.
通配符,表示所有内容()
表示一个整体,表示一个子串
使用正则验证(reg.test(str))
- 默认只验证字符串的局部
- 如果需要整体验证,需要在正则中添加开头和结尾的标志
- 开头:
^
- 结尾:
$
- 开头:
- 使用test时,如非特殊需要,正则都需要添加开头和结尾的标志
- test()验证的^$和使用全局g的区别
- test()验证的^$表示整体开头到结尾验证,不会触发lastIndex,而且是要整体存在才是true,类似且
- /g是全局修饰符,只要全局中存在就为true,类似或
使用reg.exec(str)查询
var str = "adg123uigv456ibo457fdj";
var reg1 = /\d/;
var reg2 = /\d/g;
// exec的正则不全局匹配,每次执行得到的结果都是固定的
console.log(reg1.exec(str));
console.log(reg1.exec(str));
// exec的正则全局匹配,每次执行都是在上次查询结束的位置,继续查询
console.log(reg2.exec(str));
// 查询结束的位置(下次查询开始的位置)
console.log(reg2.lastIndex);
// 主动设置下次查询开始的位置
reg2.lastIndex = 0;
// exec返回的数组中的第0个数据,是完整正则查询到的数据
// exec返回的数组中的第1个数据,是正则的第一个子串查询到的数据
// exec返回的数组中的第2个数据,是正则的第二个子串查询到的数据
// ...
var reg3 = /(\d[a-z])([a-z])/g;
console.log(reg3.exec(str));
console.log(reg3.exec(str));
console.log(reg3.exec(str));
lastIndex隐藏的坑
lastIndex只有正则表达式使用了表示全局检索的 “g” 标志,且使用exec( )或test()时,该属性才会起作用。同时,它还满足以下规则:
如果在正则匹配中成功匹配到字符串,lastIndex会被设置为第一次匹配到的字符串的后一个字符位置,以作为字符串全局匹配下次检索的起点,如果后面字段还能匹配成功,那么lastIndex会被反复重新赋值,直到匹配失败,它会被重置为0;
参考链接
正则只是验证的是基本格式要求,并不能验证内容
如:验证abc === a正则可以认为true,因为验证的只是第一位是否为a,并不是整个内容全部匹配,比如下面的html标签的写法中\1表示和第一个字串相同,在写<span>...</s>
时结果为true显然是不正确的,因为正则只是验证的是基本格式要求,并不能验证内容,从这个角度来说正则是没有问题的
常见的正则写法
- 邮箱:
/^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/
- URL:
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?$/
- html标签:
/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/
JSON
是一种通用数据,类似于有格式的记事本
json的语法
-
js中的json语法
- json必须是字符数据,不允许使用双引号包裹
- 必须遵守js中对象或数组的基本语法
- 如果是对象语法,对象的key必须使用双引号包裹
- 不允许出现没有意义的逗号
- 不允许出现undefined,NaN,函数
-
json文件中的json语法
- 必须遵守js中对象或数组的基本语法
- 如果是对象语法,对象的key必须使用双引号包裹
- 不允许出现没有意义的逗号
- 不允许出现undefined,NaN,函数
为了测试json的正确性 - 在js中提供了json和对象的转换方法
- json转对象:必须先符合json的语法
- JSON.parse(json);
- 对象转json:必须先符合对象的语法
- JSON.stringify(obj);
day16
ES6的新增
ES6:ECMAScript的第六次重大更新,向下兼容,在原版本的基础之上新增
新增的声明关键字
- let,const,class,import,export
- let和const声明变量
- let的特点
- 全局变量不会自动绑定到window
- 不允许重复声明
- 会触发块级作用域:花括号即作用域
- 不存在变量提升
- 暂时性死区
- const的特点
- let的特点,const全部具备
- const声明的变量不允许修改地址(基本类型:值就是地址;复杂类型:地址是地址,值是值)
- let的特点
- class声明类
- import和export属于ES6的模块化规范
- let和const声明变量
- 使用原则
- const优先,let其次,最后var
新增的箭头函数
- 有名函数:正常函数
- 匿名函数:自动执行
- 无名函数:不能直接存在(报错),只能作为值使用
- 赋值式创建函数的值
- 匿名函数的函数体
- 事件处理函数
- 参数:回调函数
- 返回值:闭包函数
- 箭头函数:等同于无名函数(直接存在不报错)
- 完整语法:()=>{}
- 极简语法:=>
- 当箭头函数有且只有一个参数时,可以省略小括号
- 当箭头函数有且直接返回值时,可以省略花括号和return(花括号和return必须同时省略)
- 箭头函数自身没有this,自动使用上层函数的this
- 箭头函数不能被new执行
- 箭头函数伤害了代码可读性
- 不建议大范围使用(小范围的用于参数或返回值,比较方便)
ES6对字符串的扩展
-
新增的对新版U编码的支持
- 旧版U编码:
- 默认:四位十六进制
- 超出上限部分:两个四位十六进制
- 新版U编码
- 五位十六进制
- 字符串转U编码:str.codePointAt()
- U编码转成字符:String.fromCodePoint()
- 该方法返回一个字符串,而不是一个 String 对象。因为 fromCodePoint() 是 String 的一个静态方法,所以只能通过 String.fromCodePoint() 这样的方式来使用,不能在你创建的 String 对象实例上直接调用。
- 旧版U编码:
-
新增的字符的方法
-
字符串中的包含str.includes(“要查询的字符”)
- 存在为true
- 不存在为false
-
字符串的开头包含str.startsWith(“要查询的字符”)
- 存在为true
- 不存在为false
-
字符串的结尾包含str.endsWith(“要查询的字符”)
- 存在为true
- 不存在为false
-
字符串重复str.repeat(重复的次数)
-
新增字符串的表达和拼接方式
- 表达
- ``
- 用${变量}表示变量
- ``
- 拼接
- 直接在``里面写,会保存源代码中的缩进和换行
- 表达
-
ES6新增的解构赋值
- 数组:从左向右的顺序依次对应,不存在的位置为undefined
- 对象:按照键(key)一一对应,不存在的键,为undefined
- 字符:从左向右的顺序依次对应,不存在的位置为undefined
- 为了防止从数组中取出一个值为undefined的对象,可以在表达式左边的数组中为任意对象预设默认值,如果取出来的值不为undefined则为取出来的值,否则为预设的默认值
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
ES6新增的展开运算符
- 展开运算符:
...
- 数组:一定要在能接收多个数据的位置,展开
- 对象:一定要在能接收多个键值对的位置,展开
- 可以实现数据的深拷贝
ES6新增的数据类型
- Symbol类型,类似于字符,是一种直接的值
- 用于标记状态值
- 不允许修改,任意两个值不相等
ES6新增的数据集合
- 数组:数据的有序
- 对象:数据的无序
- set:是数组的映射
- set其实也是一种map
- new的时候忽略相同的数据
- 应用:数组去重(前提是两个添加的元素严格相等)
- map:是对象的映射
- for-of遍历(与for-in用法相同,但是for-in不能遍历map)
day17
this
this是一个关键字,是一个指针,没有具体的内容
this一般存在于函数中,表示当前函数的执行对象(谁执行了this所在的函数,this就是谁)
this的绑定情况
- 默认绑定:没有明确隶属对象的函数直接执行,内部的this,被绑定到window(非严格模式)
- 隐式绑定:属于某个对象的函数,被对象执行,此时内部的this指向当前对象
- 隐式丢失:将已经被隐式绑定的this所在的函数,有赋值给其他变量或参数,直接执行,此时this会隐式丢失到window身上(非严格模式)
- 显示(强制)绑定:使用函数的方法强行将函数中的this指向指定的值
- 修复隐式丢失:提前使用bind进行强制绑定,指定this的指向
- new绑定:使用new关键字执行函数,函数内部的this指向new出来的实例
函数的方法
- 函数的方法:将函数作为对象,属于函数的函数,是函数的方法
- 语法
function fn(){}
// fn是函数
fn.xxx()
- 分类
- call
- 参数
- 参数1:要改变的this的指向值
- 参数2~N:作为实参传入原函数
- 返回值:原函数的返回值
- 参数
- apply
- 参数
- 参数1:要改变的this的指向值
- 参数2:必须是数组的格式,自动将数组解析之后,作为实参传入原函数
- 返回值:原函数的返回值
- 参数
- bind
- 参数
- 参数1:要改变的this的指向值
- 参数2~N:作为实参传入原函数
- 返回值:改变this指向之后的新函数(要执行这个返回值就相当于执行新函数)
- 参数
- call
- 区别
- 功能:改变this指向
- 参数:
- call和bind的参数一致
- apply的第二个参数是数组
- 返回值:
- call和apply的返回值一致
- bind的返回值是改变this之后的新函数
- 是否改变原数据:否
DOM动画
动画:某个物体按照时间,持续改变属性
- 运动源:要运动的元素
- 速度
- 频率
- 人眼1秒能识别24帧。1000/24,DOM运动能支持大约30ms切换一帧,33fps
- DOM动画,最大33fps
- canvas内,最大能支持120fps
- 步长
- 频率
- 目标:停止条件
匀速运动
缓冲运动
- 不同元素的缓冲
- 不同元素不同属性的缓冲
- 多元素同时缓冲
- 多元素多属性同时缓冲
- 链式运动(在动画结束后,执行其他功能)
重力运动
圆周运动
day18
面向对象
是以对象为主进行编程
面向…
- 以…为主
- 面向二进制编程
- 面向指令的编程
- 面向自然语言的编程
- 面向过程的编程
- 跟随思路的变化,逐行实现功能
- 面向函数的编程
- 将不同的功能封装成不同的函数,通过函数之间的互相调用,实现编程效果
- 面向对象的编程
- 对相关的功能或数据进行封装之后,形成了对象,只操作一个对象内的方法和属性进行编程
- 面向过程的编程
对象
- 优势:封装之后
- 提升了数据的传输速度
- 提升了数据的查找速度
面向对象编程的演化过程
- 将一个具体的事物的特征抽象出来,封装之后,是对象
- 将多个对象的相同特征再次抽象成类,类中涵盖了多个对象的相同特点
- 类再次进行抽象,将类中表示功能的部分,抽象成规范,由将来类创建出来的实例统一继承
- 抽象的类用来创建具体的对象,具体的对象是一种具体事物的描述,也叫实例
- 类和实例的关系
- 类是实例的抽象
- 实例是类的具象
- 类和实例的关系
- 规范规定了类该如何创建,类中规定了实例有哪些属性,实例就是具体的对象
面向对象解决问题的过程
- 面向对象(OO)
- 是一种解决问题的方式。
- 面向对象分析(OOA)
- 拆解问题,将问题不断的拆解,拆解到能直接解决
- 大规模的分工
- 面向对象设计(OOD)
- 高内聚,低耦合(依赖)
- 精密的协作
- 面向对象编程(OOP)
- 使用某种编程语言,解决经过设计的拆解出来的问题
面向过程编程和面向对象编程的区别
- 面向过程
- 1 -> 2 -> 3 -> 4
- 面向对象
- 1, 3 -> 2, 4
面向对象编程的语法
- 构造自定义函数
- 使用new关键字执行自定义的特定的函数
- new的原理
- 1.创建一个新对象
- 2.修改了函数的this,指向第一步创建的新对象
- 3.修改了新对象的原型链的指向,指向了函数的prototype
- 4.检测函数是否主动返回对象,如果没有,返回这个新对象
- new的原理
- 使用new关键字执行自定义的特定的函数
- 自定义的构造函数的命名使用大驼峰式方式,以示区分正常函数
- 类:属性写在构造函数内
- 规范:方法写在构造函数的原型身上
- 构造函数和原型上的方法中的this都指向实例
原型链
-
函数的prototype - 规范
- 显示原型,对象类型的数据
- 作用:用来被将来new当前所属函数创建出来的实例的
__proto__
指向 - 用来作为类的规范
- 自身拥有个内置的constructor属性,该属性表示当前prototype所属的函数
-
实例的
__proto__
:- 隐式原型,是一个指向
- 指向了创建自身的函数的prototype
- 指向了自身所属类的规范
- 配合对象的属性和方法的访问原则 ,可以让自身拿到规范中的方法或属性
-
对象的属性和方法的访问原则:
- 当对象访问属性或方式时,先在对象自身查找,找到了就使用,没找到,顺着
__proto__
依次向上级查找,任意一层找到了,就使用,直到顶层还没找到,抛出undefined - js中的原型链的顶层是:Object.prototype
- 因为函数的prototype上的方法将来会直接被实例执行,所以函数的prototype上的方法中的this也可以认为指向实例
- 当对象访问属性或方式时,先在对象自身查找,找到了就使用,没找到,顺着
day19
面对对象的实例–轮播图
思路:
先分析再设计后编程
给对象绑定事件,通过添加索引控制每一次位置的变化
无缝轮播图:视觉欺骗
思路:
右点击:将第一张图片复制一份放到最后一张,当索引切换到最后一张时候看到的是第一张,此时再点击把索引设置为第二张,直接设置整个位置到第二张的位置,此时因为没有动画的效果,切换是极快的,所以视觉上是从最后一张到了第一张之后再到第二张,从视觉上是无缝的
class
js中没有类的概念,是使用函数模拟了类
新版本更新后,增加了class关键字,用来声明类
class关键字的使用
class 对象名{
constructor(n){
this.name = n
}
show(){
console.log(this.name)
}
}
const test = new 对象名("admin")
test.show();
day20
面对对象实例–放大镜
所谓的放大镜效果实际上是两张内容相同的大小图片的跟随鼠标的移动的效果
面对对象实例–瀑布流
之前瀑布流的实现是通过css实现的,现在要通过js实现
思路:动态获取首行放置元素的个数(用当前浏览器宽度除以元素宽度再取整),其他行放置元素是放在首行中最小高度元素的下面,要获取首行最小高度元素的索引和高度值,放置后更新首行最小高度元素的值,又重复这个过程直到元素放置完
day21
Node
node的介绍
- 服务器编程语言,运行在服务器上的语言
- node的语法使用的是ECMAScript的规范
- node中并没有BOM和DOM,所以不能使用这两部分内容
- node的组成:模块 和 ECMAScript
- node中全面支持ES6,唯独不支持ES6的模块化,因为node中有自己的模块化规范
- ES6的模块化:export,import
- node的模块化规范:commonJs
- require
- exports
node内置模块的使用
http的使用
- 引入服务器模块
- 创建服务器功能
- 挂载到指定端口
// 引入服务器模块
const http = require("http");
// 创建服务器的功能
const serverObj = http.createServer((req, res)=>{
// 请求头信息对象:外部到服务器,req
// 响应头信息对象:服务器到外部,res
// console.log("所有的请求req和响应res");
// 打印到后端
console.log(req.url + "访问了服务器");
// 向前端写数据(向前端发送数据)
// 只能写字符
// json数据就是字符数据
const obj = {name:"admin",age:19}
res.write( JSON.stringify(obj) );
// 向前端发送结束状态
res.end();
});
// 挂载到指定端口
serverObj.listen(3000,()=>{
console.log("挂载成功...")
});
路由处理:对请求头做判断即可
接下来的node的学习在另外一篇文章
结束于2021/09/13