前端面试知识点

目录

html&css

w3c标准

ECMAScript

CommonJS

h5特性

本地存储

flex布局(弹性盒布局)

js基础

闭包

同步异步

作用域

原型原型链

深拷贝

es6

解构赋值

箭头函数

promise

then

catch

all

async/await

数组函数

字符串函数

vue相关

常用指令

监听和计算属性

生命周期

防抖节流

节流:

防抖:

响应式数据原理

双向数据绑定原理

组件通信

xuex

vue路由

优化

网络

跨域

ajax

axios

axios二次封装

echarts

git指令

MVVM和mvc

MVVM

MVC

区别

Webpack

 


html&css
w3c标准

万维网联盟标准是一些列标准的集合,分为结构(html)、表现(css)和行为(js和dom)

w3c提出了规范化的要求

1)标签和属性名字母要小写
2)标签要闭合
3)标签不允许随意嵌套
4)尽量使用外链css样式表和js脚本。让结构、表现和行为分为三块,符合规范。同时提高页面渲染速度,提高用户的体验。
5)样式尽量少用行间样式表,使结构与表现分离
6)标签的id和class等属性命名要做到见文知义,更利于seo,代码便于维护
7)使用注释:正确的应用等号或者空格替换内部的虚线。<!--这里是注释============这里是注释-->
8)所有属性值必须用引号括起来(”” ”)双引号或单引号
9)CSS必须要用<style type=“text/css”>开头来定义,为保证各浏览器的兼容性,在写CSS时请都写上数量单位,例如:错误:.space_10{padding-left:10} 正确:.space_10 {padding-left:10px}
10)需要声明(DOCTYPE)

ECMAScript

是 JavaScript 的核心语言规范,描述了 JavaScript 的语言语法、类型、语句、关键字、保留字、运算符、对象等基本特性

CommonJS

是JS社区在2009年提出的一系列标准的统称,其中包含了模块、文件、IO、控制台等标准。日常工作中所说的CommonJS实际上是指Node.js中实现的版本,不是它的原始定义。CommonJS中规定每个文件是一个模块。模块化开发

主要使用模块化的导入导出功能

导出:export xxxx   export{ xxxx,xxxx,xxx}

默认导出:export default xxxx

        一个文件只能有一个默认导出

导入:import xxx form url

h5特性

语义化标签、音视频、图形绘画、本地存储

本地存储

localStorage-没有时间限制,sessionStorage-session 关闭浏览器窗口数据删除

flex布局(弹性盒布局)

可以根据父元素的大小自动调整自身的尺寸和位置

在F12内使用,调整多个元素水平或垂直居中、平分父元素空间、排列方向等操作。

js基础
闭包

闭包有三个特性:

1.函数嵌套函数

2.函数内部可以引用外部的参数和变量

3.参数和变量不会被垃圾回收机制回收

释放闭包:闭包所在变量设置为null

同步异步

同步:

从上往下按顺序依次执行

只有将一个任务完全执行完后, 才执行后面的

会阻塞后面的代码执行

异步

启动任务后, 立即向下继续执行, 等同步代码执行完后才执行回调函数

不会阻塞后面的代码执行

异步回调函数会即使触发了, 也是要先放入队列中待执行, 只有当同步任务或前面的异步任务执

行完才执行

作用域

作用域

一个变量可以合法使用的范围/区域

作用域起到了隔离变量, 避免了变量重名冲突的问题(也就是允许了不同作用域中可以有同名的

变量)

    分类:

        全局作用域

        函数作用域

        块作用域 => ES6的let或const变量

作用域链

多个嵌套的作用域形成的由内向外的结构, 用于查找变量

当查找一个变量, 在整个作用域链中都找不到时: 会报引用错误, 错误信息为这个变量没有定义

原型原型链

原型

每个函数都有一个显式原型属性: prototype

每个实例都有一个隐式原型属性: proto

实例的 proto 与对应函数的 prototype 都指向原型对象

函数的默认的原型对象是Object的实例, 也就是一个{}

原型对象上有一个 constructor 属性指向对应的构造函数

显示原型与隐式原型

原型链

从对象的 proto 开始, 连接的所有对象。也可称为“隐式原型链”

原型链的作用:

在查找对象属性或调用对象方法时, 会先在对象自身上查找, 找不到就会沿着原型链查

利用原型链可以实现继承

深拷贝

使用第三方库lodash中的cloneDeep()方法

使用递归方式实现


 function copy(obj) {
     // 创建一个空对象用来拷贝之后的内容
     let newObj = {}
     //判断数据是否为 复杂数据类型
     if (typeof obj === 'object') {
        // 是 就将该数据进行 遍历
        for (let k in obj) {
             // 当 obj[k] 的值依然为 复杂数据类型时 重新调用该函数 
             // 将obj[k] 当实参 进行调用 直至 obj[k] 的值不在为 复杂数据类型
             newObj[k] = copy(obj[k])
        }
     } else {
         newObj = obj
      }
     return newObj
     let newArr = [];
    for (let i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            newArr.push(copy(arr[i]));
        } else if (typeof arr[i] === 'object' && arr[i] !== null) {
            newArr.push(copy(arr[i]));
        } else {
            newArr.push(arr[i]);
        }
    }
      // 将 copy 的对象返回出去
      return newArr
}

es6
解构赋值
  • 解构对象: let {x, y} = {x: 1, y: 2};
  • 解构数组: let [a, b, c] = [1, 2, 3];
  • 可以使用别名:let {x: aliasX, y: aliasY} = {x: 1, y: 2};
  • 引入模块解构: import { getProductList } from '@/api'
箭头函数
  • 没有自己的this, 使用外部作用域中的this, 不能通过bind来绑定this***
  • 不能通过new来创建实例对象
  • ***内部没有arguments, 可以通过rest参数来代替
promise

Promise有三种状态,pending(等待状态),fulfilled(成功状态),rejected(失败状态)。

Promise还有state属性和result属性,state值是当前状态值,result值是当前结果值。

then

传两个参数 ,成功和失败。可以链式调用,只有返回失败promise和抛出错误会执行链式失败

catch

捕获上层未能捕获到的错误

all

接受promise数组作为参数,所有promise都是成功时才返回成功promise,内容是成功promise结果的数组,否则返回失败的,内容是第一个失败的值

async/await

解决异步的最终方案

async声明这是异步函数,返回promise对象

await会阻止后续代码,等待右侧promise对象结果

缺点:滥用 await 可能会导致性能问题,因为 await 会阻塞代码

async function test2() {
    const result = await test();
    console.log(result);
}
数组函数

一、改变原数组的方法 1.push() 末尾添加数据 2. pop() 末尾出删除数据 3.unshift() 头部添加数据 4.shift() 头部删除数据 5.reverse() 翻转数组 6.sort() 排序 7.splice() 截取数组 二、不改变原数组的方法 1.concat() 合并数组 2.join() 数组转字符串 3.slice()截取数组的一部分数据 4.indexOf 从左检查数组中有没有这个数值 5.lastIndexOf 从右检查数组中有没有这个数值 三、ES6新增的数组方法

  1. forEach() 用来循环遍历的 for 2.map 映射数组的 3.filter 过滤数组 4.every 判断数组是不是满足所有条件 5.some() 数组中有没有满足条件的 6.find()用来获取数组中满足条件的第一个数据 7.reduce()叠加后的效果
字符串函数

1.str.charAt()下标查找,根据下标参数查找对应的字符,没取到则是空字符串

2.str.indexOf()根据指定字符串查询对应的索引,返回索引值或-1

3.#### str.slice()字符串截取(开始的位置,结束的位置(不包括))

4.#### str.substr()也是截取字符串,(开始位置,返回字符串的个数)

5.#### str.split()分割字符,碰到参数字符就分割,返回数组

6.#### str.concat()拼接字符,把参数拼接到str后边

7.#### str.replace(旧内容,新内容)字符串替换,识别到旧内容并替换成新内容


vue相关
常用指令

v-show、v-if / v-else、v-for、v-on简写@、v-model简写:

监听和计算属性

计算属性必须同步返回计算结果, 而watch中可以在异步操作后更新数据显示

watch可以深度监视, 计算属性只是监视了使用到的数据

生命周期

初始阶段: mounted: VM挂载完毕会执行一次 beforeCreate:所有生命周期函数中最先执行的 在VM未完成初始化时执行,获取不了VM属性、方法 created: VM初始化完毕时执行,可以获取属性方法 beforeMount: VM挂载之前执行,可以获取VM的属性/方法,但获取不到真实DOM节点 更新阶段: beforUpdate: 响应式数据发生变化时触发一次 updated: 响应式数据发生变化之后触发一次 销毁阶段: 可以看到VM,但VM不工作了 beforeDestroy:VM销毁之前执行 destroyed:VM销毁之后执行,进行收尾工作

防抖节流
节流:

在时间内,不管触发几次,都只执行一次

应用:页面滚动,请求按钮

实现:

函数内设置布尔变量为true,if判断buer,触发事件,改变布尔值为false,设置定时器(多少时间后改变布尔值为true),

防抖:

事件触发后延迟执行,如果延迟期间有新触发,就重新计算

应用:实时搜索,拖拽

实现:

函数内用if判断,如果函数已经有执行的定时器的话,就把它清除掉。

函数添加定时器,内部调用函数,调用后删除定时器标记

响应式数据原理

对象: 通过Object.defineProperty()添加setter方法来监视属性数据的改变 + 订阅-发布

数组: 重写更新数组元素的一系列方法 + 订阅-发布

调用原生的对应对数组元素进行相应的操作

更新界面去

双向数据绑定原理

将动态的data数据通过value属性传给input显示 ==> data到view的绑定

给input标签绑定input监听, 一旦输入改变读取最新的值保存到data对应的属性上 ==> view到data的绑定

组件通信
  1. 父向子

v-model传递,props接收

¥refs

是一个对象,在组件或dom标签内添加ref使用,子组件中使用 ref属性,会将其添加到父组件的$refs对象中。

父组件通过this.¥refs.属性名.函数

  1. 子向父

vue自定义事件

¥emit(自定义事件)

    this.¥emit(父组件函数,数据)

    父组件给子组件传参时添加.sync修饰符,子组件通过this.¥emit(updata:参数名,新值)传回父组件

  • 3.兄弟或其它/任意

    全局事件总线bus

        在入口文件创建vue实例作为bus,把bus挂在到vue原型上

    Vue.prototype.$bus= bus;
    //发送事件
    this.$bus.$emit('eventName', data);
    //接受事件
    this.$bus.$on('eventName', (data) => {
          // 处理事件
        }
    
    // 组件销毁前取消事件监听,避免内存泄露
        this.$bus.$off('eventName'););

    Vuex

    xuex
    const store = new Vuex.Store({
      modules: {
        cart: {//模块
          state: {//存放数据的地方
            items: []
          },
          mutations: {/同步修改state数据
            pushProductToCart (state, payload) {
              state.items.push({
                id: payload.id,
                quantity: 1
              })
            }
          },
          actions: {//异步操作和提交mutations
            addProductToCart ({ state, commit }, product) {
              const cartItem = state.items.find(item => item.id === product.id)
              if (!cartItem) {
                commit('pushProductToCart', product)
              }
            }
          },
          getters: {//对state中的数据进行计算处理,相当于计算属性
            cartItems: state => {
              return state.items
            }
          }
        }
      }
    })
    这个代码创建了一个包含cart模块的Vuex store对象,其中cart模块包含state、mutations、actions和getters四个属性,用于管理购物车数据。在addProductToCart action中,使用state.items和commit方法来修改cart模块中的数据。在cartItems getter中,使用state.items来计算购物车中的商品数量和总价。
    组件中使用
    this.$store.state.属性名
    this.$store.setters.计算属性名
    this.$store.commit('同步函数名')
    this.$store.dispatch('异步函数名')
    
    vue路由

    ¥router是用于做编程式导航的(改变路由的);¥route是获取路由信息的。

    路由导航

    路由导航,它默认会被渲染成一个带有链接的a标签,通过to属性指定链接地址
    <router-link to="/xxx">xxxx</router-link>
    编程式导航
    this.$router.push({
        path:'路由路径',
        query:{name:'xxx'}//git传参
    })
    this.$router.push({
        name:'路由名字',
        params:{name:'xxx'}//post传参
    })
    this.$route.params接收参数

    路由配置文件

    
    路由配置文件
    [
        {
            path:'/',//路径地址
            name:'xxx',
            component:()=>import("@/App.vue"),//跳转到对应组件
            children:[//子路由
                // {
                //     path:'topics',
                //     component:()=>import("@/views/topics"),
                // },
            ]
        },
    ]

    路由重定向,path地址访问根目录或者无效地址时跳转首页使用

    动态路由,根据路由传参,在目的地读取参数并使用

    优化

    v-for 遍历列表

        指定非下标的唯一key, 尽量不用index, 如果只用于展示就没关系

    v-if和v-show按需使用

    路由组件懒加载 ==> 预加载

    第三方插件的按需引入打包

    对高频事件进行节流或防抖处理

    及时销毁事件监听

    网络
    跨域

    同源策略

    vue处理跨域vue.config.js

        devServer下proxy里配置,target是代理跨域目标接口、changeOrigin是否改变请求的源地址、pathRewrite重写请求的路径

    ajax

    浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据

    /* 
    xhr + promise 封装一个异步ajax请求的通用函数  简洁版
    */
    function ajax(url) {
      return new Promise((resolve, reject) => {
        // 创建一个XHR对象
        const xhr = new XMLHttpRequest()
        // 初始化一个异步请求(还没发请求)
        xhr.open('GET', url, true)
    
        xhr.onreadystatechange = function () { 
            /*
            ajax引擎得到响应数据后
                将xhr的readyState属性指定为4
                将响应数据保存在response / responseText属性上
                调用此回调函数
            */
    
          // 如果状态值不为4, 直接结束(请求还没有结束)
          if (xhr.readyState !== 4) {
            return
          }
          // 如果响应码在200~~299之间, 说明请求都是成功的
          if (xhr.status>=200 && xhr.status<300) {
            // 指定promise成功及结果值
            resolve(JSON.parse(xhr.responseText))
          } else { // 请求失败了
            // 指定promise失败及结果值
            reject(new Error('request error staus '+ request.status))
          }
        }
        xhr.send(null)
      })
    }
    axios

    axios.get(url, {配置}) axios.post(url, data, {配置}) axios.put(url, data, {配置}) axios.delete(url, {配置})

    axios二次封装

    配置请求响应拦截器,请求拦截器里请求头携带token,相应拦截器里分开处理成功和失败回调,成功返回data,失败返回报错信息,token过期跳转登录

    api接口

    接口名(参数){
        return axios({
        url:'xxxxx'+参数
        methon:get
        data:参数
    })
    }

    echarts

    title标题 series根据type设置图表类型并配置渲染样式


    git指令

    Sourcetree可视化提交代码

    查看分支:git branch

    创建分支:git branch 分支名

    切换分支:git checkout 分支名

    工作区提交到暂存区:git add

    将更改添加到本地存储库的必要命令:git commit -m描述信息

    将本地代码推送到远程仓库:git push

    从远程仓库拉取最新代码并合并到本地分支:git pull


    MVVM和mvc
    1. state:存放数据的地方

    2. getters对state中的数据进行计算处理,相当于计算属性

    3. mutations同步修改state数据

    4. actions异步操作和提交mutations,负责api数据接入处理,接受context作为第一个参数,包含了state、getters和commit。不能对satate修改,但可以通过commit通知mutations修改

    5. modules将store模块化,每个模块都有自己的仓库

    • 同源: 协议, 域名, 端口, 三者都相同
    • ajax请求时, 浏览器要求当前网页和服务器必须同源(安全), 否则会抛出跨域的错误
    • 加载image/link/script不受同源策略限制
    • 配置通用的基础路径和超时

    • 显示请求进度条

      1. 显示进度条: 请求拦截器回调
      2. 结束进度条: 响应拦截器回调
    • 成功返回的数据不再是response, 而直接是响应体数据response.data

    • 统一处理请求错误, 具体请求也可以选择处理或不处理

    • 每个请求自动携带userTempId的请求头: 在请求拦截器中实现

    • 如果当前有token, 自动携带token的请求头

    • 对token过期的错误进行处理

MVVM
M : Model(模型), 后端传递的数据
V : View(视图),前端渲染给用户看到的页面
VM : ViewModel(视图模型),链接后端数据和前端页面,

        将后端数据转化成页面内容:数据绑定

        将页面内容转化成后端数据:dom事件监听、双向绑定

MVC
M: Model(模型)后端传递的数据
V: View(视图)前端渲染给用户看到的页面
C: Controller (控制器)页面业务逻辑
        单向通信,数据和页面必须通过业务逻辑操作
区别
mvvm解决了mvc中大量dom操作影响页面渲染性能,通过虚拟dom只更新有变化的值
Webpack

打包用的

Webpack本身只能处理JavaScript模块,但通过加载器(Loader)的使用,可以将其他类型的文件(如CSS、LESS、图片等)转换为有效的模块,使其能够被打包到最终的结果中。

Webpack的核心概念包括entry(入口)、output(输出)、loader(加载器)和plugin(插件)。

  • entry指定Webpack的入口文件
  • output定义打包输出的文件及路径
  • loader用于处理不同类型的文件
  • plugin用于扩展Webpack的功能
  1. Entry(入口):Webpack将从指定的入口文件开始分析和构建依赖关系树。入口可以是单个文件或多个文件,Webpack会根据入口配置找出所有的依赖模块。

  2. Output(输出):指定Webpack打包后的文件输出的路径和文件名。可以通过配置output选项来指定输出文件的路径、名称和格式等。

  3. Loader(加载器)Webpack本身只能处理JavaScript模块,但通过Loader的使用,可以处理其他类型的文件(如CSS、LESS、图片等)。Loader的作用是在模块加载时对其进行转换和处理。

  4. Plugin(插件):插件用于扩展Webpack的功能。它可以在打包的不同阶段执行特定的任务。例如,可以使用插件来压缩代码、拆分代码、生成HTML文件等。插件通过在Webpack配置中引入并实例化,然后将其添加到plugins数组中。

    Webpack的loader是用于处理模块文件的转换工具

    它们可以将不同类型的文件(如CSS、LESS、图片等)转换为可以被Webpack处理的有效模块,以便将其包含在最终的打包结果中。

    1. babel-loader:将ES6+代码转换为ES5语法,以便在旧版本的浏览器中运行。
    2. style-loader 和 css-loader:用于处理CSS文件。css-loader主要负责处理样式文件中的importurl语句,而style-loader将转换后的CSS模块直接注入到HTML页面中。
    3. sass-loader 和 less-loader:用于处理Sass和Less预处理器。它们将Sass和Less代码转换为普通的CSS代码。
    4. html-loader:用于处理HTML文件,将其中的图片等资源转换为Webpack可以识别的模块。

    在Webpack中,插件(plugin)是用来扩展和定制构建过程的工具,可以用于处理和优化资源、自动化任务、注入变量等。

    TerserWebpackPlugin:用于对JS代码进行压缩和混淆,减小文件体积,提高加载速度。

移动端兼容和适配

页面适配

        媒体查询:比较麻烦,需要在每个页面上写媒体查询的代码

        百分比布局:使用百分比单位设置元素的宽度、高度和边距等。这样可以根据父元素的尺寸自动调整子元素的大小,实现一定程度的自适应效果。因为不同属性的百分比值,相对的可能是不同的参照物,所以百分比往往很难统一,在移动端适配中使用是非常少的。

        弹性盒子(flex)布局
使用CSS3弹性盒子布局模型,通过设置弹性容器和弹性项目的属性,实现灵活的布局。弹性盒子布局可以根据容器的尺寸和内容的大小,自动调整项目的 布局和排列。

        rem单位 + 动态的font-size

是CSS3新增的一个相对单位,是指相对于根元素的字体大小的单位。flexible 的原理就是这个。
使用rem(根元素字体大小的倍数)作为单位来设置元素的尺寸。通过设置根元素的字体大小,可以控制整个页面的缩放比例,从而实现不同设备的适配。

        vw、vh

是css3中提出来的,基于视图窗口的单位。将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 等分为 100 份。

需要做单位转化,而且px转换成vw不一定能完全整除,因此有一定的像素差。可以使用less或者scss进行换算,也可以在webpack解析css 的时候用postcss-loader 有个postcss-px-to-viewport插件能自动实现px到vw的转化

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值