前端菜鸟第一次写文章,记录自己成长经历

112 阅读8分钟

HTML相关知识

HTML5添加了新属性

  • 标签语义化 header、nav、footer、select、aside、article
  • 音视频:video、audio
  • 画布:canvas,矢量图:svg
  • 存储:localStorage,sessionStroage
  • web worker 语义化的好处:代码块清晰,便于维护,页面结构清晰,便于浏览器搜索引擎解析和爬虫,利于seo

canvas常用api

  • getContext() 返回指定的canvas的绘画环境
  • fillStyle、fillRect(x,y,width,height) 填充
  • strokeStyle、strokeRect(x,y,width,height) 描边
  • beginPath() 绘制开始
  • moveTo(x,y) 移动画笔位置
  • lineTo(x,y) 画线段
  • translate(x,y) 原点位置
  • clearRect(x,y,width,height) 清除
  • stroke() 描绘路径
  • closeRath() 绘制结束

loaclStorage、sessionStorage

  • loaclStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
  • sessionStorage 用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。 提到loaclStorage和sessionStroage就一定要说cookie

三者区别:

cookieloaclStoragesessionStorage
默认服务器生成,有失效时间长期保存,手动清除会话结束自动清除
大小为4K左右5M5M
每次携带在HTTP头客户端保存,不与服务器通信客户端保存,不与服务器通信

CSS相关知识

说一下盒模型:CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。

标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin

低版本IE盒子模型:宽度=内容宽度(content+border+padding)+ margin

改变盒模型的代码:box-sizing: border-box

css样式的优先级

!important > 行内样式 > ID选择器 > 类选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

css中可继承的属性有 font-size, font-family, color

用css写一个三角形

.div{ //使用border实现
    display:inline-block;
    width:0;
    height:0;
    border-top:100px solid red;
    border-right: 50px solid transparent;
    border-left: 50px solid transparent;
   }
.div{ //使用伪元素实现
    position:relative;
    width:50px;
    height:50px;
}
.div::after{
    content: '';
    position:absolute;
    top:0;
    left:0;
    width:0;
    height:0;
    border: 50px solid transparent;
    border-bottom-color: lightgoldenrodyellow;
}

BFC(块级格式化上下文)

块格式化上下文(Block Formatting Context,BFC) 是 Web 页面的可视 CSS 渲染的一部分,是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。 ---来自MDN

简单点来说就是在BFC内部的元素和外部的元素不会互相影响

  1. 触发BFC条件:

    body 根元素

    浮动元素:floatnone 以外的值

    绝对定位元素:position (absolute、fixed)

    displayinline-block、table-cells、flex

    overflow 除了 visible 以外的值 (hidden、auto、scroll)

  2. 解决了什么问题:

    阻止外边距折叠:margin塌陷问题

    包含浮动元素:高度塌陷问题

    阻止元素被浮动元素覆盖:div浮动兄弟问题

水平垂直居中 display: flex;一把梭,top: 50%; left: 50%; transform: translate(-50%,-50%);

左边固定宽度右边自适应宽度 left{flex:1}orleft{float:left;width:200px} right{margin-left: 200px;}

JavaScript

1.let、const和var

  • var 变量提升 可重复声明 变量值可改
  • let 不可变量提示、不可重复声明、变量值可改 会有暂时性死区问题
  • const 不可变量提示、不可重复声明、变量值不可改且必须初始定义就有值

2.Set、Map、Object区别

  • Set总结

    1. 类似数组,值不重复
    2. 可存储任何类型
    3. 值不会进行类型转换,5和“5”是不同的
    4. 两个NaN也是重复的
    5. NaN和undefined都可以被存
  • Map总结

    1. 支持的所有数据类型做为键
    2. 本质上是键值对的集合,类似集合
    3. 两个NaN也是重复的
    4. NaN和undefined都可以被存
  • Set和Map区别

    1. Set以[value, value]的形式储存元素,Map以[key,value]的形式储存元素
    2. Map的值不作为键,键和值是分开的
  • Map和Object区别

    1. Object的key 必须是简单数据类型(整数、字符串、symbol),Map的key可以是任何类型
    2. Map元素插入顺序是FIFO,object没有
    3. Map继承Object
    4. Map在存储大量元素的时候性能表现更好
    5. 写入删除密集的情况应该使用 Map

3.闭包

闭包的概念:一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。

function init() {
  let name = "xiaoer"; // name 是一个被 init 创建的局部变量
  function displayName() { // displayName() 是内部函数,一个闭包
      console.log(name); // 使用了父函数中声明的变量
  }
  displayName();
}
init();

有什么优缺点:优点创建类似私有变量避免变量污染,缺点就是容易造成内存泄漏

4.深拷贝浅拷贝

浅拷贝: 只拷贝一层,深层只引用。拷贝的新对象改变,原对象也会改变。

function shallowCopy (object) {
    if (typeof object !== 'object') return object //传入的不是object或者array直接return出去
    let newObj = Arrar.isArray(object) ? [] : {}
    for (let key in object) {
        if (object.hasOwnProperty(key)) {//只遍历自身属性不需要原型上的属性
            newObj[key] = object[key]
        }
    }
    return newObj
}

如果是拷贝的对象是数组还可以用slice()和concat()

深拷贝:将对象拷贝成一个新变量,新变量指向不同地址。新对象改变原对象不变

最简单的就是JSON.parse(JSON.stringify())但是不能拷贝函数和undefined等

function deepClone (object) {
    if (typeof object !== 'object') return object //传入的不是object或者array直接return出去
    let newObj = Arrar.isArray(object) ? [] : {}
    for (let key in object) {
        if (object.hasOwnProperty(key)) {//只遍历自身属性不需要原型上的属性
            newObj[key] = 
            typeof object[key] === 'object' ? deepClone(object[key]) : object[key]
        }
    }
    return newObj
}

其实还有一些特殊情况需要处理,但是这里已经够大部分场景使用了。

5.节流防抖

  • 防抖 多次触发一个条件只在最后一次执行
function antiShake(fn, delay) {
    let timer = null
    return () => {
        const args = [...arguments]
        const _this = this;
        timer && clearTimeout(timer)
        timer = setTimeout(function () {
            fn.apply(_this,args)
        },delay)
    }
}
  • 节流 一段时间内只执行一次
function throttle(fn, delay) {
    let flag = true;
    return () => {
        if (!flag) {
            return;
        }
        const _this = this
        const args = [...arguments];
        flag = false;
        setTimeout(() => {
            fn.apply(_this, args);
            flag = true;
        }, delay);
    }
}

使用场景: 轮播图,模糊查询,滚动事件,点击事件

6. Promise

Promise是承诺的意思,是一种解决异步编程的方式,还解决了链式回调地狱的问题。

Promise有三种状态,分别是pending(进行中),fulfilled(已完成),rejected(已失败)

既然是承诺,就是状态一但变化就不会再变,Promise的状态只会从pending变成fulfilled或者从pending变成rejected

状态流转是这样的

pending ---> resolve(value) ---> fulfilled
pending ---> reject(reason) ---> rejected

用法: Promise对象是一个构造函数,用来创建实例 传入两个参数,分别是resolve(成功)和reject(失败)

const promise = new Promise(function(resolve,reject) {})

实例有几种方法可以调用

  • .then() 根据PromiseA+规范,Promise应该提供一个then()方法来访问最终结果,无论结果是成功(value)还是失败(reason)
  • .catch() 是发生错误时的回调函数
  • .finally() 不管promise最后状态如何都会执行 构造函数的方法
  • Promise.all() all()接受一个数组,将多个Promise实例包装成一个新的Promise实例,只有数组中所有实例成功才会返回一个包含结果的数组
  • Promise.race() race()接受一个数组,将多个Promise实例包装成一个新的Promise实例,只要数组中的实例有一个状态改变,新的Promise实例就会改变,不管返回失败还是成功。

7. Async/await

async/awaitGenerator 的语法糖

async可以单独出现await出现必然有async

执行async返回的是一个promise

await相当于promise.then()

可以用try/catch去包裹处理异常

8. 原型/原型链

  • 原型:每一个 JavaScript 对象(null 除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性,其实就是 prototype 对象。
  • 原型链:由相互关联的原型组成的链状结构就是原型链。 看下别人写的吧轻松理解JS 原型原型链
function Player(color) { //是一个构造函数
  this.color = color;
  this.start = function () {
    console.log(color + "下棋");
  };
}
const play1 = new Player('白子')
play1.__proto__ === Player.prototype //true

9.手写一个关键字new

实现new关键字需要以下几个步骤

  1. 创建一个空对象
  2. 根据原型链,设置空对象的 __proto__ 为构造函数的 prototype
  3. 改变this指向
  4. 判断函数的返回值类型,如果是引用类型,就返回这个引用类型的对象
function myNew (fn,...args) {
    //fn必须是一个函数
    if (typeof fn !== 'function') throw new Error('fn must be a function.')
    myNew.target = fn
    // 原型继承
    const temp = Object.create(fn.prototype) // 步骤 1. 2.
    // fn执行绑定 this 环境
    const res = fn.apply(temp, ...args) // 步骤 3.
    // 如果该函数没有返回对象,则返回this。
    return typeof res === "object" ? res : temp
}

10.数组去重

给定一个数组 let arr = [1,2,3,4,4,4,3,2]

1.使用es6中的Set和解构去重

const result = [...new Set(arr)]

2.使用indexOf

function result(arr) {
    let obj = []
    for (let i = 0; i < arr.length; i++) {
        if (obj.indexOf(arr[i]) === -1) {
            obj.push(arr[i])
        }
    }
    return obj
}

3.使用sort

function unique1(arr) {
    let obj = []
    arr = arr.sort() //排序后根据下标
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            obj.push(arr[i])
        }
    }
    return obj
}

还有其他的方法,这里就不完全写上去了。

总结

想到的目前只有这么多,其实还有vue的相关东西,就不在这篇文章里写了。前端菜鸟一个,有不对的地方请多多指教。