前端基础知识和一些面试题(一)

一、基础知识储备
CS架构:客户端(需要客户先安装)/服务器;
BS架构:浏览器(可直接使用浏览器运行)/服务器;
软件开发周期:软件定义期(可行性研究阶段,需求分析阶段)——软件开发期(概要设计阶段,编码实现阶段,测试阶段)——软件维护期(软件维护阶段)
二、常用快捷键
Alt+Tab:切换当前的窗口;
Windows+d:显示或者隐藏桌面;
Windows+e:打开“此电脑”或者“文件资源管理器”;
Windows+r:打开“运行”窗口,可以快速打开软件,例如:cmd(命令行)/mspaint(画图)/calc(计算器)/mstsc(连接远程云服务器)
三、数据库
1.关系型数据库逻辑结构
    数据库服务器Server -> 数据库Database -> 数据表Table -> 行Row -> 列Column;
2.mysql为中小型数据库,可用于各种操作系统;
3.部署结构
    (1)服务器端
        mysqld.exe(相当于start键,是启动文件,占用的端口是3306)
            服务器端主要负责储存维护数据
    (2)客户端
        mysql.exe
            客户端负责连接数据库服务器
4.mysql.exe   -h127.0.0.1  -P3306  -uroot  -p
    -h(host连接服务器域名/IP地址,连接自己电脑的localhost/127.0.0.1)
    -P(post端口)
    -u(user用户名,mysql管理员用户名为root)
     简写为mysql  -uroot
用小键盘上的上下箭头可以调出以前写的代码,Esc取消上述操作
5.常用的管理命令
    show  databases;——查询所有数据库
    use  数据库名称;——进入指定数据库
    show  tables;——查看当前所处的数据库有哪些表
    desc  数据表名称;——描述指定数据表中表头都有哪些项
    quit;——退出连接
    select * from 数据表名称;——查询数据表中数据
6.下面介绍的是脚本模式时脚本文件写法,结果可以去交互模式下查看,我的电脑有问题输入utf8 依旧会乱码,所以需要在进入mysql之前输入chcp 65001+enter来手动改变一下编码,防止以后乱码;
set names utf8;#客户端服务器使用utf8编码;
drop database if exists xizi;#如果存在数据库xizi则丢弃它;
creat database xizi charset=utf8;#创建数据库xizi并使用utf8编码;
use xizi;#打开xizi数据库;
#创建笔记本分类的表family;
create table family (
  fid   int primary key,           #编号并附加主键约束
  fname varchar(20)              #分类名称
);
#输入数据
insert into family values
("10","小米"),
("20","戴尔"),
("30","联想");
#创建保存笔记本数据的表laptop
create table laptop (
  lid int primary key auto_increment,            #编号并附加主键约束以及设置为自增列
  title varchar(50) unique not null,              #标题
  price decimal(7,2) default 9999,             #价格
  stime date default "2022-10-24" ,                     #上架时间
  isonsale boolean,               #是否在售
  familyid int,                   #所属类别编号
  #将familyid作为外键列,取值必须到family的fid去找
  foreign key(familyid) references family(fid)
);
#输入数据
insert into laptop values("1","小米先锋",null,"2022-10-1",true,"10");
insert into laptop values("2","戴尔三","45563.22","2020-9-15",false,"20");
insert into laptop values("3","联想拯救","10050.24",null,true,"30");
#只给编号,标题,上架时间提供值;其他列不提供值,会自动应用默认值
insert into laptop(lid,title,price,isonsale,familyid) values(4,"devile","10002.33",true,30);
insert into laptop values("7","戴尔3.0",default,default,false,"20");
insert into laptop values(null,"戴尔3.1",default,default,false,"20");
insert into laptop values(null,"戴尔3.9",default,default,false,"20");
insert into laptop values(null,"戴尔3.2",default,default,false,"20");
insert into laptop values(null,"戴尔3.3",default,default,false,"20");
insert into laptop values(null,"戴尔3.4",default,default,false,"20");
insert into laptop values(null,"戴尔3.5",default,default,false,"20");
insert into laptop values(null,"戴尔3.6",default,default,false,"20");
delete from laptop where lid="2";#删除数据
update 数据表 set 列名称=...,列名称=...,列名称=... where 条件(比如id="2")
7.常见简称
定义数据结构(DDL)【create/drop/alter(修改)】、操作数据(DML)【insert/delete(删除)/update(修改】、查询数据(DQL)【select】、控制用户权限(DCL)【grant(授权)/revoke(收权)】
8.列类型
    (1)数值型
        tinyint/smallint/int/bigint/float/double/decimal/boolean
            整数型
                tinyint微整形,占一个字节,范围【-128,127】
                smallint小整形,占两个字节,范围【-32768,32767】
                int整形,占4个字节,范围【-2147483648,2147483647】
                bigint大整形,占8个字节,范围很大
            浮点型
                float单精度浮点型,占四个字节
                double双精度浮点型,占8个字节
                demcial(M,D)定点小数,小数点不会发生变化,M代表总的有效位数,D代表小数点后的有效位数
            布尔型
                只有两个值,分别是true和false代表真和假;用于储存只有两个值的数据,例如:性别,是否在线,是否是会员
    (2)日期时间型
        date/time/datetime
            date日期型“2022-10-22”
            time时间型
                “15.50.30”
            datetime日期时间型
                “2022-10-12 15.50.30”
    (3)字符串型
        varchar/char/text
            varchar(M)变长字符串(空间浪费少)
            char定长字符串(视情况而定)
9.列约束
    (1)primary key主键约束
        一个表格里只能有一个主键,声明主键约束的列,不允许重复的值,主键约束的列的上禁止插入null(一次性插入多条数据,
                     允许在主键约束里使用一次null,这可能导致出错,所以不推荐使用一次性插入)
    (2)not null非空约束
        声明了非空约束的列禁止插入null
    (3)unique唯一约束
        声明了唯一约束的列上不允许 插入重复的值,但允许插入null,甚至是多个null
    (4)default默认值约束(default+默认值)
        在插入数据的时候,如果不提供的值可以使用列的默认值。步骤分为两步: 
                  【1.设置默认值,通过default设置,如果不设置的话,默认值是null.   
                     2.使用默认值,不提供值时会自动使用默认值】
    (5)check检查约束
        用户根据自己需求添加的约束,MySQL不支持这种约束,认为这种约束会严重影响数据的插入速度。
                    例如:create table student(score tinyint check(socre>=0 and score<=100));
    (6)foreign key(外键列(familyid)) references family(另一个表的主键列fid)外键约束
        目的是为了确保两表之间建立关联,便于后期的查询,声明了外键约束的列,插入的值必须在另一个表的主键列中出现过
               (注意事项:外键约束的列上允许插入null,外键列和对应的另一个表的主键列类型要保持一致(如int对int)
    (7)auto_increment自增列
        自动增长,声明了自增列,在插入的值的时候,只需要赋值为null就会获取当前的最大值然后加1插入
                  (注意事项:自增列必须添加在整数形式的主键列上,允许手动赋值)
10.其他说明
    null是关键字,使用时不能加引号
    多个约束可以同时使用,之间敲个空格即可
11.简单查询
    查询特定的列
    查询所有的列
    给列起别名
        as
    显示不同的记录
        distinct
    查询时执行计算
    查询结果排序
        order  by
        asc(升序) / desc(降序)
    条件查询
        where
        比较运算符
            >  <  >=  <=  =  !=
        and(&&)   /   or(||)
        is  null/is  not  null
        in()/not  in()
    模糊条件查询
        %   _ 
        like
    分页查询
        两个已知条件
            当前的页码
            每页的数据量
        开始查询的值=(当前的页码-1)*每页的数据量
        limit  开始查询的值, 每页的数据量
        注意:开始查询的值和每页的数据量必须是数值,不能加引号
12.复杂查询
    聚合查询/分组查询
        count()/sum()/avg()/max()/min()
        group  by
        year()
    子查询
    多表查询
        内连接
            inner  join   on
        左外连接
            left   outer  join   on
        右外连接
            right  outer  join   on
        全连接
            mysql不支持
            解决方案
                union
                union  all
四、JS
1.数据类型(ES5)
    原始类型
        数值型,字符串型,布尔型,空null,未定义undefined【ES6新增:Symbol类型、bingint类型】
    引用类型
2.数据类型转换
    数值型+字符串——字符串
    数值+布尔型——数值型
    字符串+布尔型——字符串
    强制转换——Number(),parseInt(),parseFloat(),toString()
3.%取余,/正常运算5/2=2.5
4.switch-case只能进行全等(===)的条件判断
    switch(表达式){
            case 值1:语句块1   break
    case 值2:语句块2  break
    .......
    case 值n:语句块n  break
    default:语句块N+1}
5.While(循环条件){循环体}——停止循环用break
   do{循环体}while(循环条件)——停止循环用break
6.for(初始值;循环条件;增量){循环体}
    continue跳过并继续
    break结束
7.return和break对比
    return用于函数中,作用是结束函数的调用,不再执行函数体
    break用于循环或者switch-case语句,用于结束对应语句
8.递归
    function say(){console.log("从前有座山") say()}
9.如何面向对象:封装,继承,多态
10.斐波那契数列
    function f(n){
                 if(n==1 || n==2){
                     return 1
                             }else{
                     return  f(n-1)+f(n-2)
                             }
                        }
                      console.log(f(4))
11.函数提升优于变量提升
    //c()
           var c=3
          function c(){
               console.log(9)
             }
         c()//c is not a function
12.回调函数
    把函数作为参数传递
        function tao(madai){
                             console.log(1)
                                madai()
                              }
                         function nan(){
                            console.log(2)
                             }
                               tao(nan)
13.匿名函数自调用
    ;(function(){})()
14.系统函数
    isNaN()检测一个字符串中是否含有非数字
        有,返还true
        没有,返还false
    eval()执行字符串中表达式
15.js中的对对象
    自定义对象
    内置对象:js提供的对象
    宿主对象:根据执行环境划分
        浏览器dom
            在浏览器中存在兼容性问题
        node.js------mysql对象
            在node.js中因为因为只有node一种环境,所有不用考虑兼容问题
16.访问对象中的属性
    对象.属性名
    对象[属性名]
17.对象遍历
    for(var k in user){console.log(k,user[k])}
18.栈内存和堆内存(地址传递)
    原始类型的数据为栈内存
        数值型,字符串型,布尔型,空,未定义型
    引用类型的数据为堆内存
        比如对象,函数,数组
19.数组遍历(ES5)
    for(var i=0;i<arr.length;i++){console.log(arr[i])}
【ES6】array.forEach(element => {  });
20.数组API
    toString()数组转字符串
    reverse()翻转数组元素
    sort()对数组进行排序,默认是按首字母的编码顺序
    join()将数组转换为字符串,可以指定连接符
    arr0.concat(arr1,arr2)拼接多个数组
    slice(start,end)截取数组元素,左闭右开,返还截取的元素
    start开始的下标,end结束的下标,左闭右开——end为空时截取到最后
    splice(start,count,v1,v2...)删除数组元素
        start开始的下标
        count删除数量count为空时删除到最后
        v1,v2将继承开始的下标向后延续
    push()在数组末尾添加元素,返还数组长度
    unshift()在数组开头添加元素,返还数据长度
    shift()删除数组开头一个元素,返还删除元素
    indexOf()检测数组中是否含有某个元素,返回下标,找不到返还-1
21.字符串对象API
    length获取字符串长度
    charAt查找下标对应的字符等价于字符串[下标]
    indexOf()
    lastindexOf()
    slice()
    split()将字符串转为数组,每个字符串是一个元素,需要指定分割符
    面试题
        翻转字符串abcdef->fedcba
        var n="abcdef"
         console.log(n.split("").reverse().join(""))
    英文字母转大写toUppertCase()
    英文字母转小写
        toLowerCase()
22.Math对象API
    Math.PI——获取圆周率
    Math.abs()——获取绝对值
    Math.pow(x,y)——获取x的y次方
    Math.random()——获取随机数,范围【0,1)
    Math.ceil()——向上取整
    Math.floor()——向下取整
    Math.round()——四舍五入
    Math.max()
    Math.min()
23.Date对象(堆内存)
    计算机元年1970年1月1日0:0:0:0
    new Date()获取当前时间
    new Date(时间戳)
    
    d.getFullYear()
    d.getMonth()+1【月份0-11对应1-12月】
    d.getDate()
    d.getHours()
    d.getMinutes()
    d.getSeconds()
    d.getMillisecond()毫秒
    d.getDay()星期0-6对应日-六
    d.getTime()获取时间戳
    Date.now()获取当前操作系统时间戳
    设置日期时间
                setFullYears()/setMonth()/setDate()/setHours()/setTime()/setHours()/setMintes()/setSeconds()...
    转换为本地字符串
                d.toLocalString()
24.Number对象
    Number()
    toFixed(n)保留小数后n位
25.赋值执行顺序是从右向左进行的
五、ES6正式开始
1.ES6(ECMAScript6)JS的第六套标准规范
(1)块级作用域:let声明的变量不允许重复声明,let声明的变量存在提升(存在暂存死区),但不允许访问,大括号之                  间的语句就是块级作用域
        const声明的变量专门用来声明常量,不能重复声明,声明了就必须赋值,存在块级作用域中
(2)可以给参数设置默认值了:
    function add(a=0,b=0,c=0){}
(3)箭头函数:对匿名函数的简化,和匿名函数不完全一样
    ()=>{}
    如果箭头函数只有一行代码并且是return可以省略花括号和return,例如:(a=>console.log(1))()
(4)模板字符串    `${}`
2.对象
    全局对象
        global(在浏览器下为window)
    console对象
        在浏览器下输出
            console.log()打印日志
            console.warn()打印警告
            console.info()打印消息
            console.error()打印错误
        console.time()开始计时
        console.timeEnd()结束计时
    process对象
        进程:计算机运行的每个软件都可以成为进程,进程有相应的CPU,内存的消耗
        process.arch查看CPU架构
        process.platform 查看操作系统
        process.pid 进程编号
        process.kill(“进程编号”)结束指定编号进程
    Buffer对象
        buffer缓冲区,是内存中临时存储数据的空间
    module对象
        每个文件就是一个模块,每个模块是一个独立的功能体
        require("./eye.js")引入模块
        module.exports={myA:a,myB:b}暴露对象
3.路径
console.log(__filename)//当前对象的绝对路径+模块名称
console.log(__dirname)//当前对象的绝对路径
4.模块
    自定义模块
    核心模块
    第三方模块
        会在目录下寻找package.json文件中main 对应的文件,找不到的话,会自动寻找index.js
    例如:require("tao")会自动去node_modules目录下去寻找,找不到不断往上一级去寻找0
5.npm 
    npm init -y初始化,生成项目描述文件package.json,记录项目相关信息
    npm install 包的名称
        例如:npm  i  express;npm i -g nodemon;npm  install  mysql
    npm i 会下载package.json和'package-lock.json中记载的文件
6.网址URL
    协议+域名或者IP地址+端口号+文件的路径名+?查询的字符串
7.定时器(异步)
    一次性定时器:setTimeout(function(){console.log("boom")},3000)
        清除clearTimeout()
    周期性定时器:setInterval(回调函数,间隔时间)
        清除clearInterval()
    立即执行定时器
        setImmediate(function(){})
            clearImmediate()
        process.nextTick(回调函数)
        注意:process.nextTick()会插队setImmediate(),会先执行
8.文件系统模块
    fs.readFile()读取指定文件中的内容
    fs.writeFile()用来向指定文件中写入内容
9.同步stateSync与异步async
10.服务器编写与路由编写例子
例子
    server.js
        //引入express模块
const express=require("express")
//建立WEB服务器
const app=express()
//引入路由器
const userRouter=require("./router/user.js")
//建立端口8080
const port=8080
app.listen(port,()=>{
    console.log("服务器连接成功,端口号:"+port)
})
//中间件...
//将post传递的参数转换为对象
app.use(express.urlencoded({
    extended:false
}))
//设置路由器路径
app.use("/v1/consume",userRouter)
//静态托管
app.use(express.static("./public"))
//设置错误处理中间件
app.use( (err,req,res,next)=>{
    if(err){
        console.log(err)
        res.send({code:500,msg:"服务器端错误"})
    }
})
    pool.js
        //引入mysql模块
const mysql=require("mysql")
//创建连接池
const pool=mysql.createPool({
    host:'127.0.0.1',
    port:'3306',
    user:'root',
    password:"",
    database:"consumedb",
    connectLimit:15
})
//暴露连接池
module.exports=pool

    user.js
        //引入express模块
const express = require("express")
//引入连接池模块
const pool = require("../pool.js")
//创建路由器
const r = express.Router()
//暴露路由器
module.exports = r
//路由的编写
//消费记录查询
//初始化页面,消费记录查询页面,需要按录入的消费日期降序排列
//http://127.0.0.1:8080/v1/consume/select?limit=5
r.get("/select", (req, res, next) => {
    let obj = req.query.limit
    let n = parseInt(obj)
    //未传n参数也会报错,因为n没有设置默认值,如果用户不传值,就是NAN
    n = n ? n : 10 //有值用值,无值使用默认值10
    let sql =
        "select consumeName,consumePrice,consumeCount,consumeDate,consumeType from consumeInfo order by consumeDate desc limit ?"
    pool.query(sql, [n], (err, result) => {
        if (err) {
            next(err)
            return
        }
        res.send(result)
    })
})
//添加消费信息
//当点击“录入消费信息”链接时,跳转到添加消费记录页面consumeAdd.html,进行非空验证
//http://127.0.0.1:8080/v1/consume/add
r.post("/add",(req,res,next)=>{
    let obj=req.body
    let consumeName=obj.consumeName
    let consumePrice=obj.consumePrice
    let consumeCount=obj.consumeCount
    let consumeDate=obj.consumeDate
    let consumeType=obj.consumeType
    if(!consumeName){
                 res.send({code:201,msg:"商品标题不能为空!"})
    }
    if(!consumePrice){
                 res.send({code:201,msg:"商品价格不能为空!"})
    }
    if(!consumeCount){
                 res.send({code:201,msg:"商品数量不能为空!"})
    }
    if(!consumeDate){
                 res.send({code:201,msg:"消费日期不能为空!"})
    }
    if(!consumeType){
                 res.send({code:201,msg:"消费类型不能为空!"})
    }
    let sql="insert into consumeInfo set ?"
     pool.query(sql,[obj],(err,result)=>{
         if(err){
             next(err)
             return
         }
        res.send({code:200,msg:"消费记录录入成功!"})
     })
})
五.  git
        git config --global    uer.name   "用户名"
        git config --global   user.email   "用户邮箱"
        git init 初始化仓库
        git status查看git仓库状态
        git add 文件名称或者全部添加git add  .
        提交git  commit  -m  "提交说明"
        git log查看所有提交日志
        git reset --hard  提交的ID
        clear清屏
        copy复制,paste粘贴
        git  reflog查看所有提交的日志已经回退记录等
        git branch 查看所有分支
        git checkout 分支名称         切换分支
        git merge  分支名称(所写分支与当前分支合并)
        git clone 克隆
        git push 推送
        git pull 拉取
        git remove -v查看远程仓库别名
        git remove add 别名  链接
        git branch -d 分支名称
            删除已经合并的分支
        git branch -D 分支名称
            强制删除分支,不管是否合并
六、HTML5
    加粗<b></b>       <strong></strong>
    倾斜<i></i>           <em></em>
    下划线<u></u>     <ins></ins>
    删除线<del></del>     <s></s>
    平方   x<sup>2</sup>  x的平方
    下角标  x<sub>1</sub>
    版权声明圈C         
        &copy;
    注册商标圈R
        &reg;
    商标符号TM小写的
        &trade;
    关闭符号X
        &times;
    带圈的关闭符号
        &otimes;
    空格
        &nbsp;
    小于
        &lt:
    大于
        &gt;
    预格式化标签
        <pre></pre>
    去掉table表格的边框间距
        style="border-collapse:collapse;"
        colspan="n"
            跨列,从当前单元格开始合并n个单元格
        rowspan="n"
            跨行,从当前单元格开始合并n个单元格
    input
        type
            text
            password
            submit
            radio单选
            checkbox多选
                checked默认选中状态
            reset重置
            date
            range
            month
            week
            url
            search
            email
            number
                min="10"  max="30"   step="2"
    <textarea></textarea>
        多行文本域
            可加属性如:cols="20"   rows="10"    style="resize:none;"设置文本域大小用户不可调
    <select></select>下来选择框,默认是单选,加multiple属性变成多选
        <select><option  value="1">选项一</option>(加selected设置默认选中状态)</select>
七、AJAX(AJAX是效果:不刷新页面更新网页)
    let xhr=XMLHttpRequest()
    xhr.onreadyStatechange()
        readyState有五种取值
            0:尚未初始化
            1:正在加载中
            2:加载完毕
            3:正在处理
            4:处理完毕
    xhr.open(methed,url)
        methed:"POST"/"GET"/"PUT"/"DELETE"
    xhr.setRequestHeader("Content-type":"application/x-www-form-urlencoded;charset=UTF-8")
        如果是post或者是put请求要记得加
    xhr.οnlοad=function(){   let result=xhr.responseText     console.log(result)
        status
            1xx提示性响应消息,服务器接受请求,需要客户端继续执行后续操作
            2xx成功的响应消息
            3xx请求需求转向另一个地址(重定向)
            4xx客户端引起的错误
            5xx服务器端运行错误
    xhr.send()}
八、JSON语法规则
    1.一段JSON格式的数据本质上是字符串
    2.一段JSON字符串只能有一个根-这个根——这个根要么是对象"{}"要么是数组“[]”
    3.一个JSON对象中,可以包含多个键值对,格式:“键名”:“键值”
    4.JSON的键值可以是如下类型:“字符串”,数字,true/false,对象,数组,null
    5.JSON中的键名和字符串键值必须用引号,而且是双引号
    6.JSON中两个数据间的分隔符用逗号表示,但是最后一个数据后面不能加逗号
九、JSON
    序列化
        把服务器编程语言中的数据转换为JSON格式的字符串
            let  jsonString=JSON.stringify(obj)
    反序列化
        把浏览器中接收到的JSON格式的字符串转回js对象
            let  jsonDate=JSON.parse(jsonString)
十、CSS
1.W3C公司推出的
    1996-CSS1
    1998-CSS2
    2005-至今CSS3
2.伪类选择器
    :hover{}悬停触发
    :active{}按住触发
    :link{}未激活前状态
    :visited{}激活之后的状态
    a标签伪类元素的优先级排序
        :link>:visited>:hover>:active
    :focus{}获取焦点
3.伪元素
    ::before{content:"";}
        指的是元素内容最开始的位置插入
    ::after{content:"";}
        指元素内容最末尾的位置插入
4.选择器权重计算
    标签和伪元素:1
    伪类,属性类:10
    id选择器:100
    内联:1000
    !important   10000
5.rgba()
6.opacity透明度
    0-1取值
7.去除幽灵空白节点(img)
    display:block
8.三角形写法
    .sjx{width:0;border:100px solid transparent;border-top:red;}
9.怪异盒子模型
    box-sizing:border-box
10.overflow
    overflow:visible
        默认允许溢出
    overflow:auto
        溢出方向出现拖动条
    overflow:scroll
        双方向出现拖动条
    overflow:hidden
        溢出隐藏,超出父元素范围的
11.如何形成BFC结界(子元素不会洒落出父元素)
    1.overflow属性的三个值形成bfc结界:auto,scroll,hidden(BFC解决高度坍塌)
    2.给父元素设置高度(解决高度坍塌)
    3.给父元素也加float让父子元素同层(解决高度坍塌)
          4.clearfix::after{
              context:'';
              display:block;
              clear:both;
          }
    BFC结界一旦形成就能避免了父子组件粘连的问题
    BFC结界一旦形成,重新计算在父元素内部浮动元素所占的高度,防止高度坍塌
12.背景图background-image
    background-image:URL(路径)
        重复方式
            background-repeat:repeat  -x
                x轴方向平铺重复
            background-repeat:repeat  -y
            background-repeat:no-repeat
                不重复平铺
        背景图定位
            background-position
                left   bottom
                -128   0
        背景图大小
            background-size:100% auto
            background-size:contain(最长边占满为止)
            background-size:cover(最短边占满为止)
    background-image:linear-gradient(90deg,blue 10px, red  20px)(渐变色)
13.em父元素字体的倍数
    rem根元素字体的倍数
14.定位position
    z-index层级没有单位,值越大层级越高,可以为负数
    相对定位relative
        相对自己原来位置的定位
    绝对定位absolute
        参照距离自己最近的祖先元素的定位(证据是这个祖先元素存在定位属性),如果一直没有,就会找到根元素头上
    固定定位fixed
        参考HTML根元素的定位(浏览器的窗口)
15.谷歌浏览器默认字号16px,最小12px
    font-size
    font-family
    font-weight
16.行高
    line-height
17.span
文本修饰线
    text-decoration:underline;下划线
    text-decoration:none;无线条
    text-decoration:line-through;删除线
文本溢出省略号三句话
    white-space:nowrap;
    overflow:hidden;
    text-overflow:ellipsis;
首行缩进
    text-indent:2em;
18.垂直对齐方式
    vertical-align:top
    vertical-align:middle
    vertical-align:bottom
19.结构性伪类选择器
    :nth-child(2)
        odd奇数
        even偶数
20.弹性布局
    display:flex;
    主轴的排序
        flex-direction:row/column
        flex-direction:row/column-reverse
    换行表现
        flex-wrap:nowrap
        flex-wrap:wrap
        flex-wrap:wrap-reverse
    简写
        flex-flow:row wrap
    主轴对齐方式
        justify-content:flex-start;
        justify-content:flex-end;
        justify-content:center;
        justify-content:space-evenly
        justify-content:space-around
        justify-content:space-between
    交叉轴对齐方式
        align-items:flex-start
        align-items:flex-end
        align-items:center
        多行交叉轴对齐方式(多行显示的前提是要换行flex-wrap:wrap)
            align-centent:flex-start
            align-centent:flex-end
            align-centent:center
            align-centent:space-between
            align-centent:space-around
            align-centent:space-evenly
    收缩规则
        flex-shrink项目中缩小的比例,默认值是1,不允许为负数
        flex-grow项目中放大的比例,默认值是1,不允许为负数
        flex-basis项目初始尺寸,设置之后主轴上设置的长度失效,以本属性设置的为准
        简写
            flex:放大  缩小   主轴尺寸
                flex:1 0 200px
21.过渡
transtion:1s    background-color, 1s  1s    border-radius;
/*过渡      用1s过渡背景颜色            等待一秒,然后用1s过渡圆角
22.变换transform
平移函数
transform:translateX(20px);
transform:translateY(30px);
transform:translate(20px,30px);对应:【x,y】
如果只写一个默认是X
transfrom:translate(150px)

旋转函数:
z轴旋转:transform:rotate(-30deg)
x轴旋转:transform:rotateX(-10deg)
y轴旋转:transform:rotateY(20deg)

缩放
0-1缩小,大于一放大
transform:scaleX(2)
transform:scaleY(2)
transform:scale(2)【X,Y同时放大】

扭曲
transform:skewX(-40deg);
transform:skewY(-40deg);
transform:skew(-40deg);【X,Y同时扭曲】

以上函数可以同时使用
transfrom:rotate(10deg)  scale(2)

23.动画
关键帧
@keyframes move{
0%{transform:translateX(0);}
100%{transform:translateX(300px);}
}
动画
animation:name        duration;
               关键帧名字   执行时间
十一、JS高级
【小常识:判断是否是闰年:(i%4===0&&i%100!==0)】
1.声明提升
声明操作(var/function) 会提升到作用域的顶部, 然后再执行代码
function: 整体提升 && 如果是函数表达式 不会提升
2.作用域: 一个具有特殊功能的对象类型
全局: window
局部: 函数运行时临时生成的对象, 函数执行结束后会销毁
3.作用域链
就近原则: 函数中使用一个变量, 优先使用自身声明的, 自己没有则到上层查找
4.闭包
为什么: 防止使用的来自其他作用域的变量被销毁
我们利用他: 规避全局变量污染, 制作私有的变量,缺点是会占用内存
5.arguments
保存所有函数收到的实参
6.函数的重载(技巧)
通过判断实参的类型 或 个数不同, 执行不同的逻辑代码
7.原型链:原型链是一条对象隐式原型不断往上指向的一条指向链,尽头是Object的隐式原型,也就是null
function Rect(length, width) {
var obj = {}
obj.length = length
obj.width = width
// 如何让 对象 obj 知道是哪个函数生的他
// 对象的 __proto__ 属性: 称为 原型链
// 对象通过 __proto__ 属性, 链接到他爸爸的原型
obj.__proto__ = Rect.prototype
return obj
}
// JS作者, 为构造函数提供了一个仓库, 用来存放公共的方法
// prototype: 原型, 就是公共的仓库
console.dir(Rect);
8.// 面试题: new运算符做了什么事?
// 再次创建矩形构造函数
function Rect(length, width) {
// new运算符会自动声明名字是 this 的变量
// this: 这个; 外国人理解: 这个对象
// var this = {}
// 对于外国人的意思: 这个对象 的 长度 = 长度;
this.length = length
this.width = width
// prototype是对象类型, 引用类型. 地址存储到 __proto__ 里
// this.__proto__ = Rect.prototype
// return this
}
9.默认的前缀是 window.
10.// 只要书写 'use strict' 在JS脚本的顶部, 那么其下方的代码就会进入严格模式
// 1. 没有用var声明过的变量, 不允许使用! -- 有效规避写错单词导致的全局污染
'use strict'
// 严格模式: 来自 ES5 -- JS第五个版本, 在2009年出版. 也称为ES2009
// 可以为JS开启严格模式: 很多存在风险的代码 书写时会产生报错, 辅助程序员写出更加健壮的代

10.this指向
对象.函数名() : 对象
函数名() : window
new 函数名(): 实例对象
11. var a = 10;
      function test() {
        // new触发: 隐式 var this = {}
        this.a = 100;
      }
      var t = new test(); // 其中的this是实例对象
      console.log("t:", t); //t: test {a: 100}
      console.log(a); //10
      test(); //直接触发, this 是window
      console.log(a); //100
12.原型的继承操作
修改this指向
    (1)暂时修改
        call
            临时借用: 先把函数存储到对象中, 然后调用, 删除

                 call: 所有的实参要1个一个传递
giveMoney.call(emp, 0.7, 2000) 
        apply
             apply: 所有的实参放在数组里传递
giveMoney.apply(emp, [0.7, 2000])

                应用场景: 可以把数组作为参数传递给 不接收数组做参数的函数

    (2)永久修改
        bind: 与call 和 apply 很相似
// call, apply: 会临时放在对象中, 然后立刻触发函数
// bind: 绑定. 函数和对象绑定在一起, 但是不会触发. 返回绑定完毕的新函数
            var gm = giveMoney.bind(emp, 0.4, 5000)
console.dir(gm);
13.展开符...
    ... : 去掉[], 称为展开
14./ let/const 是否存在提升?
// 通常说法: let/const 不存在提升
// 准确答案: let/const 存在提升, 但是 提升之后处于`暂存死区`状态 -- 在声明代码未执行前,
变量不可使用
// 利用强制的报错: 规范程序员的行为 先声明 再使用
// Cannot access 'a' before initialization
// 无法访问a, 在 声明a的代码运行前
15.高阶函数
    every
        every: 每个, 用来检查数组中的每个元素 是否都满足条件
// 全真则真, 有假为假, 逻辑类似于 逻辑与 &&
            var a = nums.every((value, index, array) => {
// 参数1: 当前元素
// 参数2: 当前元素的序号
// 参数3: 当前元素所在的数组, 即 nums
console.log('value:', value);
console.log('index:', index);
console.log('array:', array);
// 他们的关系: array[index] == value
// 返回值: 验证的结果 布尔类型
return value < 50
 })
    some
         some: 一些, 判断数组中是否有一些满足条件的. 即只要有就行
// 类似逻辑运算符中的 逻辑或 || , 有一个为真就算真
    filter: 过滤数组中的每一个元素, 把符合要求的过滤出来, 组成新的数组
        var a = emps.filter(v => v.salary > 10000)
console.log(a)
     ${}: 就是在字符串中, 可以书写 JS 代码的范围
var words = `${sname}今年${age}岁, 明年${age + 1}岁`
console.log(words);
    map
        // map: 映射 - 按照一定的规则把数组的每个元素修改后 形成新的数组
var nums = ['mike', 'lucy', 'lily', 'kitty']             
 var a = nums.map(v => v.toUpperCase())
console.log(a)
    forEach
         遍历数组的方案:

    for..in: 用于遍历对象类型的

    reduce: 数组的元素整合, 最终得到一个值
16.解构语法
    var phone = {
name: "iPhone13",
price: 7999,
desc: {
maker: 'Apple',
year: '2021.9'
 },
tags: ['最佳cpu', 'iOS系统', '动态高刷']
 }
// 要求: 解构出所有的属性
var { name: pname, price, desc: { maker, year }, tags: [t1, t2, t3] } = phone
console.log(pname, price, maker, year, t1, t2, t3);
17.Promise
    // 面试必背概念:
// Promise 分三种状态
// pending: 准备状态, 刚new出来 还没执行
// fulfilled(已完成): 调用resolve之后进入
// rejected(被拒绝): 调用 reject 之后计入
// 状态切换, 只能是:
// pending -> fulfilled
// pending -> rejected
        new Promise((resolve, reject) => {
// resolve: 解决, 代表成功
// 触发 resolve, 就会把其参数传递给 then中的函数
resolve({ msg: 'resolve被触发' })
// reject: 拒绝, 代表失败
// 触发 reject, 就会把参数传递给 catch中的函数
reject({ msg: "reject被触发" })
 })
 .then(res => {
console.log('res:', res);
 }).catch(err => {
console.log('err:', err);
 })
【async function(){ awaite function(注意:异步函数promise)】
18.正则表达式
    正则表达式的字面量写法: 用 /正则表达式/
// 修饰符: /正则/修饰符
// g: global全局, 所有

        var words = '壮壮666, 今天250 还是 520'      
 var r = /\d/g       // 类似于 '' 是字符串, // 就是正则
console.dir(r) // direct:直接输出
// 字符串拥有一个 match 方法, 可以查询出符合正则要求的字符
// match: 匹配
var a = words.match(r)
console.log(a)
    // 正则替换: 把字符串中指定的内容进行替换
var words = 'Hello壮壮, goodgay'
// 要求: 把英文换成 *
// replace: 替换
// 参数1: 正则 参数2: 要换成什么
var a = words.replace(/[a-z]/ig, '*')
console.log(a)
var phone = '18845987878'
// 需求: 中间4个数字改成*
// \d : 代表1个数字
// {n}: 代表n个
// () : 称为捕获组 -- 抓取正则表达式中的一部分, 序号从1开始数
var r = /(\d{3})(\d{4})(\d{4})/
//捕获组序号 1 2 3
var a = phone.replace(r, '$1****$3')
// 猜猜 $1 $3 什么意思? $n 就代表 第n个捕获组的值
console.log(a)
// 变化: xxx-xxxx-xxxx
var a = phone.replace(r, '$1-$2-$3')
console.log(a
    // 用户输入手机号, 我们来验证是否正确
// prompt: 弹出一个提示框 手机用户信息
var phone = prompt('亲, 请输入手机号. 壮壮会尽快联系您')
console.log(phone)
// 正则验证
// 正则表达式.test(字符串)
// ^: 代表字符串开头
// $: 代表字符串结尾
// 第一位是1 第二位3-9 剩下9个数字, 一共11位
var r = /^1[3-9]\d{9}$/
// test: 测试 正则.测试(字符串)
// 验证字符串是否符合正则的要求
var a = r.test(phone)
console.log(a ? '合法手机号' : '手机号错误,壮壮很气哦');
十二、DOM
1.DOM核心理念: 找到他 -> 操作他

     document.getElementById()
    document.getElementsByClassName()
    document.getElementsByTagName('h4')

     document.getElementsByName('sex')
    选择根元素:document.documentElement
    document.body.firstElementChild.firstElementChild
     document.body.children[0]

    querySelector: 查单个, 返回值是对象本身
querySelectorAll: 查多个, 返回值是类数组, 拥有forEach 能遍历
    document.querySelector('#zz')
     document.querySelectorAll('.ok')
    id: getElementById 返回值是一个元素
tag: getElementsByTagName 返回值类数组
class: getElementsByClassName 返回值类数组
name: getElementsByName 返回值类数组
2.自定义属性
    <!-- 每个元素本身自带很多很多属性: 系统属性 -->
<!-- 自定义属性: 需要用 data- 来声明, 存储在 dataset 里 -->
<!-- 自定义属性名可以用 多个 - 讲个, 最终转成小驼峰 -->
<!-- y-zz-kk-kaka 转为 yZzKkKaka -->
<a data-x="鹏鹏" data-y-zz-kk-kaka="壮壮" data-z="边边" href="http://tmooc.cn"
id="a1" class="danger">tmooc</a>
<script>
const a1 = document.querySelector('#a1')
console.dir(a1) //后台找到这些属性
// 读取自定义属性:
console.log(a1.dataset.x);

        自定义属性
语法: data-属性名=值
读取: dataset.属性名
3.事件冒泡
    事件的冒泡机制: 当子元素发生事件, 会传递给父元素
4.事件委托
    事件冒泡机制: 元素上触发的事件,会传递给父元素
事件委托: 通过父元素 帮子元素完成事件
适用场景: 子元素动态新增
注意: 父元素可能有很多子元素, 所以需要做判断 来针对某一类子元素做事
        box.onclick = function (e) {
console.log('box: 侦测到点击');
// 事件触发的当事人(元素)
console.log('target:', e.target)
// 判断: 如果是子元素 img 触发的, 才变圆
console.dir(e.target)
//后台查看: 哪个属性能够判断是 图片标签??
// 有三个属性: localName : 值是全小写
// nodeName tagName : 值是全大写
if (e.target.localName == 'img') {
e.target.style.borderRadius = '50%'
 }
 }

        
事件参数中, target 属性代表触发事件的当事人
5.阻止默认事件
    const a = document.querySelector('a')
// 默认情况: 点击 a 触发 href 的跳转操作
a.onclick = function (e) {
// 事件参数中, 包含很多事件相关的属性
// prevent:阻止 default:默认
// preventDefault: 阻止默认事件的发生
e.preventDefault()
alert("访问Tmooc")
事件监听器
 }
6.事件监听器
    // 团队合作时: 多人同时为一个按钮添加不同的事件
const btn = document.querySelector('button')
// onclick: 是一个属性, 同一时间只能存储一个函数
// 后赋值的覆盖之前的值
//1
btn.onclick = function () {
alert("范凯喜欢壮壮")
 }
//2
btn.onclick = function () {
alert('东东喜欢壮壮')
 }
// addEventListener: 可以为一个事件绑定多个函数
// 参数1: 事件名 (没有on) 参数2:相关的函数
btn.addEventListener('click', function () {
alert('边边喜欢壮壮')
 })
btn.addEventListener('click', function () {
alert('浩浩喜欢壮壮')
 })
// 面试题: 为DOM元素绑定事件的方式有哪些?
// onclick 或 事件监听器
// 面试题: 有什么区别
// onclick: 只能绑定一个
// 事件监听器: 可以绑定多个事件
7.页面滚动事件
     scrollTop: 滚动 顶部 -- 滚动距离顶部的偏移量
// 版本原因: 旧版本从body中读, 新版本从 documentElement读
// 用户的浏览器是新的还是旧的不知道, 所以从左到右, 哪个能读到 就用哪个
const y = document.body.scrollTop || document.documentElement.scrollTop
console.log('y:', y);
十三、BOM
BOM
// open(要打开的网页地址, 打开方式)
// 打开方式: _blank新标签 _self:当前标签
open('http://www.baidu.com', '_self')

    location.reload()刷新
    location.replace('http://tmooc.cn')替换网址
    history.forward()前进
    history.back()后退
    history.go(1)前进
    history.go(0)刷新
    history.go(-1)后退
十四、jquery
    // 函数重载技巧: 函数根据参数的个数/类型不同, 做不同的事
// 参数是对象类型: 用于同时设置多个样式
$('div').css({
// css的属性名存在大量的 -
// 但是JS中, - 是变量名的非法字符, 所以两个方案:
// 要么用字符串代表, 要么改成小驼峰
'font-size': '30px',
backgroundColor: 'blue',
'border-radius': '10px',
margin: '5px'
 })
    $('#box span').click(function () {
// this: 原生的DOM元素, 代表当前点击项
// this.classList.toggle('active')
console.log(this)
// 要想用JQ提供的方法, 就需要把原生DOM元素转成JQ的
// $(DOM元素): 转为JQ类型的对象
console.log($(this))
// $(this).toggleClass('active')
// 排他:
// siblings: 兄弟姐妹
// 当前项.添加样式.兄弟项.移除样式
$(this).addClass('active').siblings().removeClass('active')
 })

    选择器简单: 写法 和 判断
$ 代替 document.querySelectorAll
判断: 无需判断单个还是多个, 都用同一个选择器写法$
自带遍历:
JQ提供的各种方法, 都会自动遍历查找出来的元素, 挨个做操作
函数重载技巧:
同一个方法, 传递不同的参数 个数/类型, 出现不同的效果
    class操作
addClass: 添加
removeClass: 删除
toggleClass: 切换
hasClass: 判断有没有
siblings(): 查询到所有兄弟元素
    <a href="http://tmooc.cn" title="Hello Tmooc" id="a1" class="danger" data-xx="XXX"
data-yy="YYY">Tmooc</a>
<script src="./vendor/jquery-3.6.0.js"></script>
<script>
// 属性分两种: 系统的 和 自定义的
// 原生读取方式分 直接读 和 getAttribute
const $a = $('a')
// 底层是: a.href 的读法
console.log($a.prop('href')) //property: 属性,资源
// attribute: 属性, 底层是 a.getAttribute('href')
console.log($a.attr('href'))
// 总结: prop 用的更多
// 自定义属性: 原生 元素.dataset.xx
console.log($a.data('xx'))
console.log($a.data('yy'))
// 修改: 两个参数是修改
$a.prop('title', '晕晕')
$a.attr('id', 'aaaa')
    lt: 小于
gt: 大于
eq: 等于
兄弟关系
next:下一个兄弟
prev:上一个兄弟
    // 期望: 点击英雄后, 替换
$('#heros img').click(function () {
// replace: 替换
// with: 和...
// clone: 克隆, 即 复制元素
$('h2+img').replaceWith($(this).clone())
 })
    更多的选择器
上方的兄弟们: prevAll
下方的兄弟们: nextAll
内容中包含: contains
准备就绪
当在外部JS文件中书写, 需要把代码放在 $(function(){ }) 中执行
使用外部JS文件, 理论上 应该在body的最后进行引入.
防止使用者 在head 中引入, 导致DOM未加载前 就使用了JS的情况
输入框事件
焦点 focus
失去焦点 blur
变化 change
实时变化 input
作者没有封装对应函数, 需要使用通用事件绑定语法: on
键盘 keyup
通过事件参数 读取按键编号 keyCode 区分按键, 13是回车
新增子元素: append
委托: 通过on 携带3个参数实现
on(事件名, '选择器,选中指定的子元素', 回调函数)
this指向:修改为触发事件的当事元素
委托模式适合场景: 动态新增的子元素
删除元素: remove
克隆: clone 复制元素
替换: replaceWith
ajax:
get请求: $.get(请求地址, 回调函数) 回调函数接收到数据
十五、跨域问题
    同源策略:浏览器的安全策略,URL有三个基本组成部分:协议+ip/域名+端口号,三者必须完全相同称之为同源

协议+ip/域名+端口号
    不满足同源策略就是跨域
    vue如何处理跨域
@vue/cli@5.0  配置vue.config.js

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    // 配置代理服务器
    proxy: {
      // 自定义请求头,指定是有 /demo 开头的请求都是用代理服务器
      '/demo': {
        // 往哪个服务器请求
        target: 'http://localhost:3000/',
        pathRewrite: {
          // 去掉请求路径中的 /demo
          "^/demo": ""
        }
      },
    }
  }
})
注意:在启动脚手架的时候会启动一个内置的web服务器,同源策略是浏览器的行为,而服务器和服务器之间发请求不存在跨域,所以我们配置代理实际由内置的web服务器中转了请求,此种方式仅局限于开发阶段

@vue/cli@4.5 默认没有vue.config.js,需要手动创建

module.exports = {
  devServer: {
    proxy: {
      '/demo': {
        target: 'http://localhost:3000/',
        pathRewrite: {
          "^/demo": ""
        }
      },
    }
  }
}
    cors模块
        const express = require('express')
// 安装cors模块: npm i cors 在my-server目录下执行
const cors = require('cors')
明日安排
说完express的 代理解决跨域
开始Vue阶段
jQuery特点: 通过封装技巧, 简化了DOM的代码
Vue特点: 通过自动化技巧, 让你不用写DOM代码 一样能做项目!
const app = express()
app.listen(3000, ()=>{
console.log('服务器开启成功!');
})
app.use(express.static('public'))
// 在所有接口前书写:
// app.use(cors()) //解决跨域: 允许所有来源
// 白名单: 指定某几个
app.use(cors({
// 把允许的域名放在数组里即可
origin:['http://127.0.0.1:3000', 'http://127.0.0.1:5500']
}))
    跨域: 如果网页通过ajax请求数据, 数据所在的接口服务器和当前网页非同一个, 就会触发浏览器的同源
策略
解决方案:
CORS: 最推荐 -- 在服务器上添加一个白名单, 如果发送请求的来源 属于白名单范围, 就能正常访问,
不会被拒绝
PROXY: 代理 -- 适合服务器代码不可修改的场景
例如: 使用斗鱼的接口, 但是遭遇跨域报错 -- 无法修改
        创建文件夹 my-server
在my-server 下执行: npm init -y 初始化
再执行: npm i express 安装express模块
再执行: npm i cors 安装跨域模块
再执行: npm i express-http-proxy 代理模块
    proxy代理
        const express = require('express')
// 跨域
const cors = require('cors')
// 代理
const proxy = require('express-http-proxy')
const app = express()
// 启动代理服务器: nodemon app.js 或 node app.js
app.listen(3000, ()=>{
console.log('服务器启动完毕!');
})
app.use(cors())
// 代理负责转发请求, 必须放在跨域 下方书写
// 所有访问 /dy 接口的请求, 都进行转发
// 即 localhost:3000/dy
app.use('/xyz', proxy('http://dy.xin88.top'))
//http://localhost:3000/xz/data/product/index.php
app.use('/xz', proxy('http://www.codeboy.com:9999'))
// 范式:
// app.use('接口地址', proxy(要代理到的网站))
            服务器传给同源的服务器,同源的服务器再传给浏览器
————————————————————————————————
    注意小错题
        <!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>
  </head>
  <body>
    <button id="btn" class="danger">按钮</button>

    <script>
      let student = {
        className: "软件版",
        say() {
          console.log("我的名字是" + this.className);
          return undefined; //不写return,系统会自动在后面加return undefined
        },
      };
      //btn.onclick = student.say();//btn.οnclick=undefined//赋值操作从右向左进行
      // btn.onclick = student.say;
      // btn.onclick = function () {
      //   student.say();
      // };
      // btn.onclick = function () {
      //   student.say;
      // };
    </script>
  </body>
</html>

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨布

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值