国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

前端八股文

這篇具有很好參考價值的文章主要介紹了前端八股文。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

Vue

Vue3的一些基本配置

  • 去掉ESLint校驗(yàn):package.json中的extends去掉eslint:commends

  • 引入icon圖標(biāo)

    // main.js中
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import * as ElementPlusIconsVue from '@element-plus/icons-vue'
    const app = createApp(App)
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component)
    }
    
    // vue頁面使用
    <el-icon><edit /></el-icon>
    

Vuex

  • state: 存放數(shù)據(jù)
  • mutations: 同步操作,寫方法用于改變state里面的數(shù)據(jù),vue可以監(jiān)聽數(shù)據(jù)的改變進(jìn)行更新(相當(dāng)于methods)
  • actions:所有異步操作都放在這里,改變的數(shù)據(jù)不能夠被vue監(jiān)聽
  • getters: 進(jìn)行邏輯處理(相當(dāng)于computed屬性)
  • module:單一狀態(tài)樹,存放所有模塊
  1. 新建store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
        state:{
            count: 0
        },
        mutations:{
            // state是必要參數(shù)
            addCount(state, number){
                state.count+=number
            }
        },
        actions:{
        	setCount(content, payload){
        	    //增加setCount方法,默認(rèn)第一個參數(shù)是content,其值是復(fù)制一份store,第二個是自定義參數(shù)
        	    return new Promise(resolve => {
        	        setTimeout(()=>{
        	            content.commit('addCount', payload);
        	            resolve();
        	        }, 1000);
        	    })
        	}
        },
        getters:{
            // 不能改變state里面的值
            alertCount(state){
                return `當(dāng)前值${state.count}`
            }
        }
    })
    
    export default store;
    
  2. 頁面使用

    <template>
      <div><b>count: {{this.$store.state.count}}</b></div>
      <button @click="addCount">count++</button>
    </template>
    <script>
    export default {
      name: 'HelloWorld',
      mounted() {
        console.log(this.$store.state.count)		// 獲取state值
        console.log(this.$store.getters.alertCount)	// 執(zhí)行g(shù)etters里的方法
      },
      methods:{
        addCount() {
          this.$store.commit('addCount', 1)		// 執(zhí)行mutation里的方法
        }
      }
    }
    </script>
    

    簡寫vuex

    • 采用解構(gòu)方法import {mapState, mapMutations, mapGetters} from "vuex";
    <script>
    import {mapState, mapMutations, mapGetters} from "vuex";
    
    export default {
      name: 'HelloWorld',
      mounted() {
        console.log(this.count)		// 解構(gòu)后,采用this.xx調(diào)用vuex的內(nèi)容
        console.log(this.name)
      },
      methods:{
        ...mapMutations(['addCount']), //mutations和actions要在methods里面解構(gòu)
        ...mapActions(['setCount']),
        
        btnAdd() {
          this.addCount(1)
        }
      },
      computed:{
        ...mapState(['count', 'name']),	//state和getters要在computed里面解構(gòu)
        ...mapGetters(['alertCount']),
      }
    }
    </script>
    
  3. 異步action在頁面的使用

    async mounted() {
      console.log(`舊值: ${this.count}`)
      await this.$store.dispatch('setCount', 3);	// 默認(rèn)寫法
      await this.setCount(3);	// 解構(gòu)寫法
      console.log(`新值:${this.count}`)
    },
    

v-model低層原理

<h2>v-model低層原理</h2>
<input placeholder="請輸入數(shù)值" id="username" />
<p id="uName"></p>
<script>
    let obj={}
    Object.defineProperty(obj, 'username', {
        // 取值
        get:function (){
            console.log("取值")
        },
        // 設(shè)置值
        set(val) {
          console.log(val)
          document.getElementById('uName').innerText = val
        }
    document.getElementById('username').addEventListener('keyup', function (){
        // 監(jiān)聽事件
        obj.username = event.target.value;
        // console.log(event)
    })
 </script>

vue理解

  • 漸進(jìn)式框架,聲明式渲染,借鑒MVVM思想
  • 采用虛擬dom(不會重新渲染所有頁面,先進(jìn)行對比,有更新的部分會進(jìn)行重新渲染(render函數(shù)))
  • 高內(nèi)聚,低耦合,使用組件化開發(fā)
  • computed屬性:如果多次調(diào)用某個方法,computed里面只會計算一次,減少了資源消

vue2.0生命周期

  1. 創(chuàng)建前后:組件實(shí)例被創(chuàng)建
  2. 掛載前后 :組件掛載到實(shí)例
  3. 更新前后 :組件數(shù)據(jù)更新
  4. 銷毀前后:組件實(shí)例銷毀

vue性能優(yōu)化

  • 數(shù)據(jù)層級不能過深,合理設(shè)置響應(yīng)數(shù)據(jù)
  • v-if 和 v-show合理選擇
  • 使用數(shù)據(jù)緩存,不頻繁取值、組件緩存(keep-alive)
  • 分頁、虛擬滾動

vue組件通信

  • props通信:子組件通過props接受來自父級組件的參數(shù)

  • $emit: 子組件傳遞數(shù)據(jù)給父組件

  • ref:父組件使用子組件的時候設(shè)置ref(ref = ‘foo’),通過 this.$refs.foo 獲取子組件實(shí)例

  • EventBus: 兄弟組件傳值

  • $parent 或 $root: 通過共同祖輩搭建通信橋梁

  • provide 與 inject
    父級組件:

    provide(){  
        return {  
            foo:'foo'  
        }  
    }  
    

    子組件:

    inject:['foo'] // 獲取到祖先組件傳遞過來的值
    

    父組件向子組件動態(tài)傳參

    需求

    • 父組件是文章管理列表,帶有一個編輯按鈕
    • 子組件(editor)是一個內(nèi)嵌的富文本編輯器:點(diǎn)擊編輯按鈕,彈出Dialog框,富文本編輯器的內(nèi)容顯示為當(dāng)前文章內(nèi)容(暫且設(shè)為content屬性)
    • 我們需要傳遞content屬性到子組件(editor),但是子組件中v-model無法綁定props中的content,因此子組件中的文本內(nèi)容綁定的是data中的html屬性,我們需要將content傳遞并且賦值給html。

    當(dāng)前問題

    • 按照props傳參(子組件第一次可以接收content并且更新頁面內(nèi)容,當(dāng)時當(dāng)我們點(diǎn)擊編輯其他文章,這時候content雖然有變化,但是無法更新到子組件html屬性上面(相當(dāng)于沒有監(jiān)聽變化),導(dǎo)致頁面無法更新到當(dāng)前文章的content,仍然顯示的是之前的content)

      父組件

      <el-form-item label="內(nèi)容">
        <WangEditor ref="editor" :content="formLabelAlign.content" />
      </el-form-item>
      

      子組件

      <template>
          <Editor
              style="height: 500px; overflow-y: hidden;"
              v-model="html"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="onCreated"
          />
      </template>
      <script>
      import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
      export default{
        name: 'WangEditor',
        data() {
          return {
            html: this.content,
          }
        },
        props:['content'],
      }
      </script>
      

    解決辦法

    在子組件加上content的監(jiān)聽,當(dāng)content變化,再給文本編輯器內(nèi)容綁定的html屬性賦值.

    watch:{
      content(newVal, oldVal){
        console.log('content change')
        console.log(newVal)
        this.html = this.content
      }
    },
    

vue-router

1.路由守衛(wèi)

A.全局路由

全局使用

  • router.beforeEach((to, from, next)=>{}):路由跳轉(zhuǎn)前執(zhí)行的操作
    to:需要跳轉(zhuǎn)的路徑
    from:當(dāng)前頁面路徑
    next:執(zhí)行當(dāng)前操作

    // 登錄攔截器
    router.beforeEach((to, from, next) =>{
      if(to.path == '/login' || to.path == '/front/home'){
        next();
      }else{
        // 不是登錄頁面
        localStorage.getItem("user")?next():next("/login")
      }
    })
    
  • router.beforeResolve

  • router.afterEach((to, from) =>{}):路由跳轉(zhuǎn)后
    一般用于跳轉(zhuǎn)后更改頁面標(biāo)題、聲明頁面等輔助功能

B.路由獨(dú)享守衛(wèi)

某個單頁面渲染使用

  • boforeEnter(路由獨(dú)享的守衛(wèi))

    const routes = [
      {
        path: '/users/:id',
        component: UserDetails,
        beforeEnter: (to, from) => {
          // reject the navigation
          return false
        },
      },
    ]
    
    

C.組件路由

組件渲染的時候使用

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave

2.hash和history的區(qū)別

hash模式
  • 帶#號,改變URL時,頁面不會重新加載

  • 利用window.onhashchange事件實(shí)現(xiàn),每次改變hash值,瀏覽器訪問歷史會新增一個記錄

  • hash值是URL中#后面的值,不會傳遞給服務(wù)器

  • 使用"后退"按鈕,返回上一個頁面

    history模式

  • 通過window.history實(shí)現(xiàn)頁面無刷新跳轉(zhuǎn)

  • 路徑會隨http請求發(fā)送給服務(wù)器,因此前端URL必須和請求的后端URL一致,否則404

  • 404舉例
    當(dāng)我們把 history 項目部署到服務(wù)器中后,此時我們在瀏覽器輸入一個網(wǎng)址(比如是 www.test.com ), 此時會經(jīng)過 dns 解析,拿到 ip 地址后根據(jù) ip 地址向該服務(wù)器發(fā)起請求,服務(wù)器接受到請求后,然后返回相應(yīng)的結(jié)果(html,css,js)。如果我們在前端設(shè)置了重定向,此時頁面會進(jìn)行跳轉(zhuǎn)到 www.test.com/home ,在前端會進(jìn)行匹配對應(yīng)的組件然后將其渲染到頁面上。此時如果我們刷新頁面的話,瀏覽器會發(fā)送新的請求 www.test.com/home, 如果后端服務(wù)器沒有 /home 對應(yīng)的接口,那么就會返回404。

computed和watch的區(qū)別

  • computed是計算屬性,函數(shù)內(nèi)的變量可以緩存,除非變量發(fā)生變化,才會重新進(jìn)行計算
  • watch主要是監(jiān)聽,每次值變化就會立即進(jìn)行回調(diào)。

v-show和v-if的區(qū)別

  • v-show是控制display來讓元素隱藏(會渲染到頁面,不會觸發(fā)生命周期)
  • v-if顯示隱藏時是把整個元素刪除(為true才會渲染組件,會觸發(fā)生命周期)

created和mounted請求數(shù)據(jù),有什么區(qū)別

  • created:渲染前調(diào)用,先初始化屬性,再做渲染

  • mounted:渲染完成之后,先初始化頁面,再對元素節(jié)點(diǎn)進(jìn)行操作 (這里請求數(shù)據(jù),可能會出現(xiàn)閃屏問題)

vue中的修飾符

  • 事件修飾符
    • .stop 阻止冒泡
    • .prevent 阻止默認(rèn)行為
    • .self 只有在event.target是當(dāng)前元素觸發(fā)
    • .capture
    • .once 事件只觸發(fā)一次
    • .passive 立即觸發(fā)默認(rèn)行為
  • 按鍵修飾符
    • .keyup .keydown
  • 系統(tǒng)修飾符
  • 鼠標(biāo)修飾符
  • 表單修飾符

keep-alive組件

用來緩存組件 ==》減少頁面刷新、網(wǎng)絡(luò)請求次數(shù),提升性能

Vue el-upload上傳圖片 + express

思路:

  • 以formData的數(shù)據(jù)格式上傳圖片
  • 后端存儲圖片到文件夾(/images/)下,并且返回給前端圖片名稱(imgUrl)
  • 前端通過’http://localhost:3000/images/imgUrl’的形式訪問圖片地址,用于展示

前端代碼

<el-upload
    class="avatar-uploader"
    action="string"
    method="post"
    :http-request="uploadImage"		// 自定義上傳圖片函數(shù)
>
  <img v-if="formLabelAlign.imageUrl" :src="resource+formLabelAlign.imageUrl" class="avatar">
  <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
<script>
export default {
  name: "Attractions",
  data() {
    return {
      formLabelAlign: { title: '', date: '', content: '', imageUrl: '', filename: '', label: ''},
      resource: 'http://localhost:3000/images/',
    }
  },
  methods: {
    uploadImage(params){
    // 圖片以formData格式上傳,并且請求頭需要設(shè)置'Content-Type': 'multipart/form-data'
      let formData = new FormData()   
      formData = { file: params.file,}
      const config = {
        headers:{
          'Content-Type': 'multipart/form-data'
        }
      };
      this.request.post('/attractions/uploadImage', formData, config).then(res=>{
        // console.log("upload: ", res)
        this.formLabelAlign.imageUrl = res.data.data
      })
    }
  },
}
</script>

后端代碼(express)

const MsgCode = require("../config/MsgCode");
const multer = require('multer')	// 引入multer:圖片處理的工具包
const path = require('path')
const storage = multer.diskStorage({
  // 配置文件上傳后存儲的路徑
  destination: function (req, file, cb) {
    // NodeJS的兩個全局變量
    // console.log("__dirname: ", __dirname);  //獲取當(dāng)前文件在服務(wù)器上的完整目錄
    // console.log("__filename: ", __filename); //獲取當(dāng)前文件在服務(wù)器上的完整路徑
    cb(null, path.join(__dirname, '../public/images'))
  },
  // 配置文件上傳后存儲的路徑和文件名
  filename: function (req, file, cb) {
    let defineFilename = new Date().getTime() + file.originalname     // 防止圖片名重復(fù)
    cb(null, defineFilename)
  }
})
const upload = multer({
  fileFilter(req, file, callback) {
    // 解決中文名亂碼的問題
    file.originalname = Buffer.from(file.originalname, "latin1").toString("utf8");
    callback(null, true);
  },
  storage: storage
})

// 上傳首頁圖
router.post('/uploadImage',upload.single('file'), function (req, res, next){
  // console.log(req.file)
  MsgCode(res, req.file.filename, "")	// 返回前端的自定義函數(shù),讀者可以自己使用res.end()進(jìn)行數(shù)據(jù)傳輸
})

this.$nexttick

當(dāng)數(shù)據(jù)被修改后,獲取dom更新之后的數(shù)據(jù),用于異步獲取更新后的數(shù)據(jù),性能優(yōu)化

Object.defineProperty有什么缺點(diǎn)

  • 無法監(jiān)聽到數(shù)組變化
  • 無法檢測對象屬性的添加和刪除

vue2和vue3區(qū)別

  • 選項式API(vue2)和組合式API(vue3)
  • vue3:多根節(jié)點(diǎn)
  • 響應(yīng)式原理:vue2(Obejct.defineProperty)vue3(proxy)
  • Diff算法優(yōu)化
  • 虛擬dom增加patchFlag字段

MVC

view(視圖層)-controller(控制器)-model(數(shù)據(jù)模型)

view主要用于UI界面展示和響應(yīng)用戶交互,controller用于監(jiān)聽數(shù)據(jù)改變和處理用戶交互,model用于存放數(shù)據(jù)

MVVM

model-viewmodel-viewcontroller

在MVC的基礎(chǔ)上,把contrler的數(shù)據(jù)和邏輯處理部分抽離出來,放到viewmodel中,是model與controller溝通的橋梁。

JS

JS組成三部分

  • ECMAScript: JS的核心內(nèi)容,描述了JS的基礎(chǔ)語法(var for 數(shù)據(jù)類型…)
  • 文檔對象模型(DOM)
  • 瀏覽器對象模型(BOM): 對瀏覽器窗口訪問和操作

location對象

包含了當(dāng)前url的屬性,主要有

  • protocol(‘http:’)協(xié)議
  • host(‘www.xx.com’) 網(wǎng)址
  • hostname(帶了端口號)
  • path (/home/list) 訪問路徑
  • search (‘?id=123456&sort=discount’) 參數(shù)
  • hash (‘#title’)

innerText 和 innerHTML的區(qū)別

  • innerText不識別html標(biāo)簽,不保留空格和換行
  • innerHTML識別html標(biāo)簽,保留空格和換行

和=區(qū)別

  • ==: 比較的是值(如string類型和number類型比較,會進(jìn)行隱士轉(zhuǎn)化)
  • ===:除了比較值,也比較數(shù)據(jù)類型(object類型比較的是地址)

構(gòu)造函數(shù)

  • 函數(shù)名首字母大寫
  • 不需要return就可以返回結(jié)果
  • 調(diào)用函數(shù)必須使用關(guān)鍵字new
// 構(gòu)造函數(shù)
function Star(name, age, gender){
    this.name = name;
    this.age = age;
    this.gender = gender;
}
var dz = new Star('DZ', 18, 'male');
console.log(dz.age)

cookie sessionStorage localStorage的區(qū)別

  • 三者均保存在本地瀏覽器
  • cookie:存儲量小,由服務(wù)器寫入,若設(shè)置了固定的時間,時間過后失效
  • session:頁面關(guān)閉自動清除(主要用于檢測用戶刷新頁面)
  • localStorage:一直保存在本地(存儲不易變動的數(shù)據(jù)),不會自動清除

token的登錄流程

  • 客戶端用賬號密碼請求登錄
  • 服務(wù)器驗(yàn)證請求,成功之后,給客戶端簽發(fā)一個token,
  • 客戶端將token保存在本地(localstorage或者cookie中)
  • 每次客戶端發(fā)送請求,都要攜帶token
  • 服務(wù)端收到請求,需要先驗(yàn)證token,驗(yàn)證成功,給客戶端返回請求數(shù)據(jù)

Token存localStorage還是session里面?

  • 存localStorage里面,每次請求接口都需要把它當(dāng)做字段傳到服務(wù)器(容易被XSS攻擊)
  • 存cookie中,會自動發(fā)送,不能跨域(CSRF攻擊)

基本&引用數(shù)據(jù)類型(JS內(nèi)置對象)

  • 基本數(shù)據(jù)類型:string,number,undefined,null,boolean,symbol,bigint
    保存在棧內(nèi)存中,保存的是一個值

  • 引用類型:object(普通對象)Array Function Date
    保存在堆內(nèi)存中,保存的是引用數(shù)據(jù)類型的地址(多個引用會同時改變)。例如下:

    let obj = {
        name: 'xm',
        age: 18
    }
    let obj1 = obj
    obj1.name = 'change'
    console.log(obj)
    console.log(obj1)
    

常用的對象

  • Math(abs, ceil, sqrt, max, min…)
  • Date(getYear, getMonth…)
  • Array(push, foreach)
  • String(concat, length, slice, split)

操作數(shù)組的方法

  • push() pop() sort()

  • splice():數(shù)組刪除,返回刪除的元素,會改變原數(shù)組

  • slice:數(shù)組截取

  • unshift() shift() reverse() concat() join() map() filter() reduce() isArray() findIndex()

  • find 和 filter
    find 返回第一個滿足條件的內(nèi)容
    filter 返回一個新的數(shù)組

      let arr = [1, 2, 3, 4, 5, 5]
      let a = arr.find(item=>item>2)
      let b = arr.filter(item=>item>2)
      console.log(a)	// 3
      console.log(b)	// [3, 4, 5, 5]
    
  • 改變原數(shù)組的方法:push() pop() sort() reverse() unshift() shift() splice()

JS判斷數(shù)組的方法

  • Array.isArray() 、instanceof Array() 、 constructor、prototype

      let arr = [1, 2,3]
      let str = 'hello'
      console.log(Array.isArray(arr))
      console.log(arr instanceof Array)
      console.log(Object.prototype.toString.call(arr).indexOf('Array') > -1)
      console.log(arr.constructor.toString().indexOf('Array') > -1)
    

數(shù)組去重

  • Set

  • indexOf

  • filter

      let arr = [1, 2, 2, 3, 1, 4]
      // set去重
      console.log(Array.from(new Set(arr)))
      // indexof去重
      function unique(arr){
        let brr = []
        arr.forEach(item=>{
          if(brr.indexOf(item) == -1){
            brr.push(item)
          }
        })
        return brr;
      }
      unique(arr)
      // 方式三:filter
      var arr2 = arr.filter((item, index,self)=>{
        console.log(item, index, self)
        return self.indexOf(item)===index
      })
      console.log(arr2)
    

多維數(shù)組最大值

  let arr = [
          [1, 2,3],
          [1,3,5],
          [95, 25, 36]
  ]
  let brr = []
  arr.forEach(item=>{
    console.log(Math.max(...item))
    brr.push(Math.max(...item))
  })

數(shù)據(jù)類的檢測方法

  • typeof() 判斷基本數(shù)據(jù)類型

  • instanceof() 判斷引用數(shù)據(jù)類型

  • constructor 基本可以判斷基本數(shù)據(jù)類型和引用數(shù)據(jù)類型

    console.log(('abc').constructor === String)
    
  • Object.prototype.toString.call() 可以判斷所有數(shù)據(jù)類型

    var opt = Object.prototype.toString
    console.log(opt.call(2))     // [object Number]
    console.log(opt.call('abc')) // [object String]
    console.log(opt.call([]))   // [object Array]
    console.log(opt.call({}))   // [object Object]
    console.log(opt.call(true)) // [object Boolean]
    

閉包

  • 優(yōu)點(diǎn):可以重復(fù)利用內(nèi)部變量,不會污染全局變量,一直保存在內(nèi)存中,不會被垃圾機(jī)制回收

  • 缺點(diǎn):閉包較多的時候,會消耗內(nèi)存,導(dǎo)致頁面性能下降,在IE瀏覽器會導(dǎo)致內(nèi)存泄漏

  • 應(yīng)用:防抖(防止重復(fù)點(diǎn)擊,n秒后執(zhí)行事件,在n秒內(nèi)重復(fù)點(diǎn)擊,從最后一次點(diǎn)擊開始計時 — 點(diǎn)擊事件)節(jié)流(n秒內(nèi)重復(fù)點(diǎn)擊,只有一次生效 – 滾動條)

  • function fn(){
        let name = 'xiaoxie'
        function getName(){
            alert(name)
        }
        getName()
    }
    fn()
    

防抖和節(jié)流的實(shí)現(xiàn)

  // 防抖:n次內(nèi)重復(fù)點(diǎn)擊,執(zhí)行最后一次
  function FD_debounce(func, wait){
    let timeout;
    return function (){
      let context = this;	// 保存this指向,context指向當(dāng)前對象
      let args = arguments
      clearTimeout(timeout)
      timeout = setTimeout(function (){
        func.apply(context, args);
        console.log(context)
      }, wait);
    }
  }
  let func = function (){
    console.log('我是func')
  }
  res = {
    a: debounce(func, 2000)
  }
  res.a()

  // 節(jié)流: n秒多次點(diǎn)擊,只執(zhí)行一次
  function JL_debounce(func, wait){
    let timeout;
    return function (){
      let context = this
      if(!timeout){
        timeout = setTimeout(function (){
          func.apply(context)
          timeout = null
        }, wait);
      }
    }
  }

內(nèi)存泄漏

JS里已經(jīng)分配內(nèi)存地址對象,但由于長期沒辦法回收和清除釋放,造成長期占有資源的情況,導(dǎo)師運(yùn)行速度緩慢甚至崩潰。

因素

  • 未清空的定時器
  • 過度的閉包
  • 一些元素沒被清除

事件委托(事件代理)

原理:利用事件冒泡的機(jī)制實(shí)現(xiàn),把子元素的事件綁定到父元素身上

父元素添加addEventListener('click', 函數(shù)名, true/false) 默認(rèn)true, false代表阻止(子元素)冒泡

原型鏈

原型鏈:一個實(shí)例對象在調(diào)用屬性和方法的時候,會以此從實(shí)例本身=》構(gòu)造函數(shù)原型 =》原型的原型 去查找

以下例子的原型鏈:p1 -> Person -> Object -> null

原型就是一個普通的對象,它是為構(gòu)造函數(shù)的實(shí)例共享屬性和方法,所有實(shí)例中引用的原型都是同一個對象

<!--原型-->
function Person(){
    this.say = function (){
        console.log('sing')
    }
}
let p1 = new Person()
let p2 = new Person()
p1.say()
p2.say()

例:say調(diào)用了兩次,在內(nèi)存中占用了兩個(如果多次使用,會造成資源浪費(fèi)),為了解決這個問題,原型:將方法掛載到prototype上,所有實(shí)例共享這個方法,減少了內(nèi)存消耗。

__proto__: 可以理解為指針,實(shí)例對象中的屬性,指向了構(gòu)造函數(shù)的原型(prototype)

p1.__proto__ === Person.prototype // 返回true

例如下:

<!--原型-->
function Person(){
    this.say = function (){
        console.log('sing')
    }
}
Person.prototype.run = function (){
    console.log('跑步')
}
let p1 = new Person()
let p2 = new Person()
//p1.say()
//p2.say()
p1.run();
p2.run();

new關(guān)鍵字

實(shí)現(xiàn)new關(guān)鍵字

    function newFun(Fun, ...args){
        // 1.創(chuàng)建空對象
        let obj = {}    // 引用類型
        // 2.把空對象和構(gòu)造函數(shù)通過原型鏈進(jìn)行連接
        obj.__proto__ = Fun.prototype
        // 3.把構(gòu)造函數(shù)的this綁定到新的空對象身上
        const res = Fun.apply(obj, args)    // 值類型
        // 4.根據(jù)構(gòu)造函數(shù)返回的類型判斷,如果是值類型,返回對象;是引用類型,返回這個引用類型
        return res instanceof Object ? res:obj;
    }
    // 測試newFun
    function Person(name){
        this.name = name
    }
    Person.prototype.printName = function (){
        console.log(this.name)
    }
    let p1 = newFun(Person, 'xym')
    p1.printName()

JS的繼承

  • 原型鏈繼承(子類繼承父類,new出來的實(shí)例擁有父類相同的屬性和方法)
    缺點(diǎn):無法向父類傳參

        function Person(){
            this.info={
                name: '張三',
                age: 12
            }
        }
        function Child(){}
        Child.prototype = new Person();
    
  • 構(gòu)造函數(shù)繼承(使用call / apply 方法實(shí)現(xiàn)繼承,在子類里面調(diào)用父類)
    缺點(diǎn):無法實(shí)現(xiàn)函數(shù)的復(fù)用

    function Person(){
        this.info={
            name: '張三',
            age: 12
        }
    }
    function Child(){
        Person.call(this)
    }
    let c1 = new Child();
    c1.info.nick = 'nick name'
    console.log(c1.info)
    
  • 組合繼承(調(diào)用了兩次父類構(gòu)造函數(shù))

    function Person(gender){
        this.info={
            name: '張三',
            gender: gender,
            age: 19
        }
    }
    Person.prototype.getInfo = function (){
        console.log(this.info)
    }
    function Child(gender){
        Person.call(this, gender)   // 構(gòu)造函數(shù)繼承
    }
    Child.prototype = new Person()  // 原型鏈繼承
    let c1 = new Child('男')
    c1.info.nickname = '小張'
    c1.getInfo()
    
    let c2 = new Child('女')
    c2.info.nickname = '小紅'
    // c1 和 c2 互不影響
    c1.getInfo()
    c2.getInfo()
    
  • ES6使用class關(guān)鍵字繼承父類
    某些瀏覽器可能不支持

    class Animal{
        constructor(kind) {
            this.kind = kind
        }
        getKind(){
            return this.kind
        }
    }
    
    // 繼承animal類
    class Cat extends Animal{
        constructor(name) {
            // 子類構(gòu)造方法必須調(diào)用super方法
            super('cat');
            this.name = name
        }
        getCatInfo(){
            console.log(this.name+' : '+this.getKind())
        }
    }
    let cat = new Cat('buding')
    cat.getCatInfo()
    
  

## JS設(shè)計原理

- JS引擎
- 運(yùn)行上下文
- 調(diào)用棧
- 事件循環(huán)
- 回調(diào)

## JS中的this指向

- 全局對象的this指向window
- 全局作用域/普通函數(shù)中this指向window
- this永遠(yuǎn)指向最后調(diào)用他的對象
- apply call bind可以改變this指向
- 箭頭函數(shù)this指向箭頭函數(shù)外的一層

## setTimeout和setInterval最小時間

- setTimeout   4ms
- setInterval   10ms

## promise

- 解決回調(diào)問題

?```js
const myPromise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('foo');
    }, 300);
});

myPromise.then(value => {
    console.log(value)
})

跨域?如何解決跨域?

跨域:當(dāng)前頁面接口訪問的 協(xié)議/域名/接口 不同,(瀏覽器的同源策略)。(瀏覽器能發(fā)出請求,服務(wù)器能響應(yīng)數(shù)據(jù),返回的時候被瀏覽器攔截了)

解決辦法

  • script調(diào)用js文件
  • 服務(wù)器實(shí)現(xiàn)cors接口,前端正常訪問就行。服務(wù)器收到前端請求,設(shè)置Access-Control-Allow-Origin

異步操作實(shí)現(xiàn)

  • 回調(diào)函數(shù)callback

    function f(x){
        console.log(x)
    }
    function printTime(){
        setInterval(function (){
            console.log('print fn exe')
            c = 1
        }, 3000)
    }
    var c = 0
    printTime()
    f(c)
    

    js內(nèi)部執(zhí)行不是按照順序的,因此這里先打印0,再輸出"print fn exe"。采用回調(diào)函數(shù)實(shí)現(xiàn)異步

    <script type="text/javascript">
        <!--回調(diào)函數(shù),實(shí)現(xiàn)異步操作-->
        function f(x){
            console.log(x)
        }
    
        function printTime(callback){
            setInterval(function (){
                console.log('print fn exe')
                c = 1
                callback(c)
            }, 3000)
        }
        var c=0
        //方法一
        printTime(f)
        // 方法二
        printTime(function (x){
            console.log(x)
        })
    </script>
    
  • async / await

    function print(time){
        setTimeout(function(){
            console.log(time);
            return 1;
        },time)
    }
    async function fun(){
        let a = await print(1000);
        // let b = await print(3000);
        // let c = print(2000);
        console.log(a);
        // console.log(1)
    
        setTimeout(()=>{
            alert(a)
        }, 3000)
    }
    fun();
    
  • setTimeout(利用定時器實(shí)現(xiàn)異步操作)

ES6新特性有哪些?

  1. 新增了箭頭函數(shù)
    不能作為構(gòu)造函數(shù)使用,不能new
    沒有arguments
    不能用call,apply,bind改變this指向
    箭頭函數(shù)的this是在函數(shù)定義時就決定了,不可以修改:this指向定義時外層第一個普通函數(shù)的this
  2. 新增塊級作用域(let 和 const)
    不存在變量提升(在變量聲明之后才能使用)
    存在暫時性死區(qū)問題
    塊級作用域的內(nèi)容
    不能在同一個作用域內(nèi)重復(fù)聲明
  3. Promise
    解決回調(diào)地獄問題
    自身有all,reject,resolve,race等方法
    原型上有then,catch
    把異步操作隊列化
    三種狀態(tài):pending-初始狀態(tài),fulfilled-操作成功,rejected-操作失敗
    async/await
    同步代碼做異步操作
  4. 解構(gòu)賦值
    從對象或者數(shù)組中取值,然后給變量賦值
  5. set和map
    set:數(shù)組去重
    map的key類型不受影響
  6. 定義類語法糖(class)
  7. 數(shù)據(jù)結(jié)構(gòu)(symbol)
  8. 模塊化(export,import)

call、aply、bind區(qū)別

  • 都能改變this的指向
  • call和aply功能類似,傳參方法不同
  • call傳的是一個參數(shù)列表
  • aply傳的數(shù)組

實(shí)現(xiàn)深拷貝

深拷貝就是完全拷貝一個新的對象,會在堆內(nèi)存開辟新空間,拷貝的對象被修改后,原對象不受影響

主要針對引用數(shù)據(jù)類型

  • 擴(kuò)展運(yùn)算符

  • JSON.parse(JSON.stringify())

  • 遞歸實(shí)現(xiàn)

    // 深拷貝
    let obj = {
        name: '張三',
        age: 18,
        say(){console.log('say name')},
        arr:[[1, 2], 3, 4, 5]
    }
    // let obj1 = {...obj}     // 方法一:擴(kuò)展運(yùn)算符
    // obj1.name = 'xxx'
    // console.log(obj)        // name : "張三"
    // console.log(obj1)       // name : 'xxx'
    
    // 方法二:json.parse   =>  不能拷貝函數(shù),即say沒有拷貝進(jìn)來
    // let obj2 = JSON.parse(JSON.stringify(obj))
    // obj2.name = 'aaa'
    // console.log(obj)
    // console.log(obj2)
    
    // 方法三 遞歸實(shí)現(xiàn)深拷貝
    function exten(origin, deep){
        let res = {}
        if(origin instanceof Array) res = []    // 判斷數(shù)組, 更改返回類型
        for(let key in origin){
            let value = origin[key]
            res[key] = (deep && typeof value == 'object' && value != null) ? exten(value, deep):value
        }
        return res
    }
    let obj3 = exten(obj, true)
    obj3.name = 'bbb'
    obj3.arr[0].push('ccc')
    console.log(obj)
    console.log(obj3)
    

ajax

ajax:交互式網(wǎng)頁開發(fā)技術(shù),在不重新加載整個頁面的情況下,與服務(wù)器交換數(shù)據(jù)并更新部分內(nèi)容

通過XmlHttpRequest對象向服務(wù)器發(fā)送異步請求,然后從服務(wù)器拿到數(shù)據(jù),最后通過js操作dom更新頁面

  1. 創(chuàng)建XmlHttpRequest對象 xml
  2. xml.open()和服務(wù)器建立連接
  3. xml.send()發(fā)送數(shù)據(jù)
  4. xml.onreadystate() , xml.change()事件監(jiān)聽服務(wù)器和通信狀態(tài)
  5. 接收并處理服務(wù)器響應(yīng)的數(shù)據(jù)
  6. 更新數(shù)據(jù)到html頁面

ajax/fetch/axios區(qū)別

  • fetch是es6的一個用于網(wǎng)絡(luò)請求的api
  • axios是一個網(wǎng)絡(luò)請求庫
  • ajax是異步j(luò)s和xmlhttprequest

axios封裝

vue2.0

npm install axios  // 安裝
  1. 創(chuàng)建service.js配置文件

    import axios from 'axios'
    import { Message, Loading } from 'element-ui'
    const ConfigBaseURL = 'http://localhost:8080/' //默認(rèn)路徑,這里也可以使用env來判斷環(huán)境
    let loadingInstance = null //這里是loading
    //使用create方法創(chuàng)建axios實(shí)例
    export const Service = axios.create({
        timeout: 7000, // 請求超時時間
        baseURL: ConfigBaseURL,
        method: 'post',
        headers: {
            'Content-Type': 'application/json;charset=UTF-8'
        }
    })
    // 添加請求攔截器(請求前執(zhí)行)
    Service.interceptors.request.use(config => {
        loadingInstance = Loading.service({
            lock: true,
            text: 'loading...'
        })
        return config
    })
    // 添加響應(yīng)攔截器(服務(wù)器響應(yīng)后執(zhí)行)
    Service.interceptors.response.use(response => {
        loadingInstance.close()
        return response.data
    }, error => {
        console.log('TCL: error', error)
        const msg = error.Message !== undefined ? error.Message : ''
        Message({
            message: '網(wǎng)絡(luò)錯誤' + msg,
            type: 'error',
            duration: 3 * 1000
        })
        loadingInstance.close()
        return Promise.reject(error)
    })
    
  2. main.js使用

    import {Service} from '@/utils/service'
    
    Vue.prototype.request = Service	//將axios放在vue的this上(vue2)
    app.config.globalProperties.request = Service //(vue3)
    
  3. 使用

    // post方法
    this.request.post(`/menu/delete?id=${val}`).then(res=>{
      	// 請求成功
      }else{
        // 請求失敗
      }
    });
    // get方法
    this.request.get("/echarts/getList").then(res =>{
         console.log(res)
    })
    

vue3.0

  1. 創(chuàng)建http.js

    import axios from "axios";//創(chuàng)建一個axios的對象
    //生成一個axios的實(shí)例
    const http=axios.create({
        baseURL:"http://localhost:8080/",// baseURL會在發(fā)送請求的時候拼接在url參數(shù)前面
        timeout:3000,//請求超時
    });
    export default http;//導(dǎo)出
    
  2. main.js使用

    import axios from "axios";
    const app = createApp(App)
    app.config.globalProperties.axios = axios
    
  3. 單頁面使用

    getWeather:function (){
          this.axios.get(url).then(res =>{
            // console.log(res)
          })
        }
    
  4. 封裝API的js文件使用(異步調(diào)用)
    封裝函數(shù)js文件

    import http from "./http";
    export const getWeather = ()=>{
        return new Promise((resolve, reject)=>{
            http.get(url).then(res =>{
                resolve(res)
            })
        })
    }
    
      頁面調(diào)用
    
    // 1.引入
    import  {getWeather} from '../request/HomeHeader.js'
    // 2.獲取返回值
    let res = getWeather()
    // 方法一 采用promise實(shí)現(xiàn)異步
    res.then((res)=>{
      console.log(res)
    })
    // 方法二 采用async/await實(shí)現(xiàn)異步
      async created() {
        let res = await getWeather()
        console.log(res)
      }
    

get和post請求

  • get是請求數(shù)據(jù),post是提交數(shù)據(jù)
  • get的請求參數(shù)放在url中,不安全,post請求參數(shù)放在body中
  • get請求會緩存,post不會緩存
  • 刷新或回退頁面get不會重新請求,post會重新請求
  • get請求只能進(jìn)行url編碼,post支持多種編碼方式

promise和async/await的區(qū)別是什么

  • 都是處理異步請求的方式
  • async/await是基于promise實(shí)現(xiàn)的
  • promise是返回對象,使用then,catch方法處理和捕獲異步請求,鏈?zhǔn)綍鴮?,造成代碼重疊,維護(hù)差
  • async/await使用try,catch捕獲異常

SVG格式

基于XML語法的圖像格式,可縮放矢量圖,本質(zhì)是文本文件,無論縮放都不會失真

JWT

JSON Web Token 通過JSON形式作為在web應(yīng)用中的令牌

JWT認(rèn)證流程

  1. 前端發(fā)送登錄請求給接口
  2. 服務(wù)器核對賬號密碼成功,把用戶id等信息作為jwt負(fù)載,和他和頭部進(jìn)行base64編碼,形成jwt
  3. 前端每次請求都會把jwt放在http請求頭的Authorization字段內(nèi)
  4. 服務(wù)器驗(yàn)證jwt的有效性,返回對應(yīng)結(jié)果

JSON

JSON是一種純字符串形式的數(shù)據(jù),適合網(wǎng)絡(luò)傳輸

  • JSON.parse()
  • JSON.stringfy()

數(shù)據(jù)沒有請求過來時,該怎么做?

給數(shù)據(jù)設(shè)默認(rèn)值,最后進(jìn)行判斷

無感登錄

用戶不需要重新登錄,優(yōu)化用戶體驗(yàn)

方案如下

  • 在響應(yīng)器中攔截,判斷token過期后,調(diào)用刷新token的接口
  • 后端返回過期時間,前端判斷token過期時間,去調(diào)用刷新token的接口
  • 設(shè)置定時器,定時刷新token

大文件上傳

采用分片上傳思想

  1. 把文件按照一定規(guī)則分塊,分割成相同大小的數(shù)據(jù)
  2. 初始化一個分塊上傳,返回本次上傳唯一標(biāo)識
  3. 按照一定規(guī)則把各個數(shù)據(jù)上傳
  4. 服務(wù)器判斷文件完整性,完整就把文件塊合并

斷點(diǎn)續(xù)傳

JS為什么是單線程

為什么是單線程:比如當(dāng)一個用戶執(zhí)行添加節(jié)點(diǎn)和刪除節(jié)點(diǎn)的任務(wù),如果不是單線程,則會出問題

JS微任務(wù)和宏任務(wù)

  • js是單線程的

  • js代碼執(zhí)行流程:同步執(zhí)行完 ==》事件循環(huán)[微任務(wù)、宏任務(wù)] ==》微任務(wù) ==》宏任務(wù) ==》微任務(wù) …

    for(let i=0; i<3; i++){
        setTimeout(function (){
          console.log(i)
        }, 1000*i)
      }
    // 輸入三個3
    
  • 微任務(wù):promise.then

  • 宏任務(wù):setTimeOut

JS作用域

  • 除了函數(shù)外,js無塊級作用域

  • 作用域鏈:內(nèi)部可以訪問外部變量,但外部不能訪問內(nèi)部
    注:如果內(nèi)部有相同的變量,則優(yōu)先訪問內(nèi)部的變量

      let a = 10;
      function fun(){
        let a = 20;
        console.log(a)
      }
      fun();
    
  • js變量提升機(jī)制

    function c(){
        var b = 1;
        function a(){
          console.log(b)	//undifined
          var b = 2;
          console.log(b)	// 2
        }
        a()
        console.log(b)	// 1
      }
      c()
    
  • 優(yōu)先級:聲明變量 > 聲明普通函數(shù) > 參數(shù) > 變量提升

JS對象

  • 對象都是new構(gòu)建的,所以對象之間不相等

    console.log([1,2,3] === [1,2,3]) // false
    
  • 對象的key都是string類型

  • 原型鏈:對象本身obj ==》構(gòu)造函數(shù)Fun =》對象的原型(obj._proto_) =》構(gòu)造函數(shù)的原型(Fun.prototype) => Object => null

var let const的區(qū)別

  • let const 不存在變量提升,var有

  • var可以聲明同一個變量多次,let const 只能聲明一次同一個變量

  • const聲明常量,一旦賦值不可以修改(const為object/數(shù)組,里面的值是可以修改的)

  • let const有塊級作用域

      if(true){
        let a  = 1;
        const b = 2;
        var c = 3;
      }
      console.log(c)	// c能打印,a,b會報錯
      console.log(a)
      console.log(b)
    

object對象的合并

  const a = {a:1, b:4}
  const b = {b:2, c:3}
  //方式1
  let obj = Object.assign(a, b)	// {1,2,3}
  // 方式二
  let obj2 = {...a, ...b} // {1,2,3}

websocket(vue2.0實(shí)現(xiàn))

  • 前端
    登錄頁:輸入用戶信息,進(jìn)入聊天室
    聊天頁:輸入消息,點(diǎn)擊按鈕發(fā)送

    <template>
      <div>
        <ul>
          <!--   消息展示   -->
          <li v-for="item in msgList" :key="item.id">
            <div>用戶:{{item.username}}</div>
            <div>時間:{{new Date(item.dateTime)}}</div>
            <p>消息:{{item.msg}}</p>
          </li>
        </ul>
    
        <input type="text" placeholder="請輸入消息" v-model="msg">
        <button @click="sendMsg">發(fā)送</button>
      </div>
    </template>
    
    <script>
    // npm install ws
    const ws = new WebSocket('ws://localhost:8080')
    
    export default {
      name: "Two",
      data(){
        return{
          msg: '',
          username: '',
          msgList: []
        }
      },
      methods:{
        sendMsg(){
          const msg = this.msg
          ws.send(JSON.stringify({
            id: new Date().getTime(),
            username: this.username,
            dateTime: new Date().getTime(),
            msg: this.msg
          }))
        },
        handleWsOpen(e){
          console.log('websocket open', e)
        },
        handleWsClose(e){
          console.log('websocket close', e)
        },
        handleWsError(e){
          console.log('websocket error', e)
        },
        // 接收消息
        handleWsMessage(e){
          // console.log('websocket message', e)
          let msg = JSON.parse(e.data)
          this.msgList.push(msg)
          console.log(msg)
        },
      },
      mounted() {
        this.username = localStorage.getItem('username')
        if(!this.username){
          this.$router.push('/login')
        }
        // 事件綁定
        ws.addEventListener('open', this.handleWsOpen.bind(this), false);
        ws.addEventListener('close', this.handleWsClose.bind(this), false);
        ws.addEventListener('error', this.handleWsError.bind(this), false);
        ws.addEventListener('message', this.handleWsMessage.bind(this), false);
      }
    }
    </script>
    <style scoped></style>
    
  • 后端
    新建index.js文件

    const Ws = require('ws')
    
    // 立即執(zhí)行函數(shù)
    ;((Ws)=>{
        const server = new Ws.Server({port: 8080});	// 要和前端監(jiān)聽同一個端口
    	
        // 初始化函數(shù)
        const init = ()=>{
            bindEvent();
        }
    
        function bindEvent(){
            server.on('open', handleOpen);
            server.on('close', handleClose);
            server.on('error', handleError);
            server.on('connection', handleConnection);
        }
    
        function handleOpen(){
            console.log('wb open')
        }
        function handleClose(){
            console.log('wb close')
        }
        function handleError(){
            console.log('wb error')
        }
        // 消息接收
        function handleConnection(ws){
            console.log('wb connection')
            ws.on('message', handelMsg)
        }
        // 消息處理
        function handelMsg(msg){
            // c : 表示每個客戶端
            let oMsg = msg.toString()
            server.clients.forEach((c)=>{
                c.send(oMsg)
            })
        }
        init()
    })(Ws);
    

HTTP協(xié)議以及瀏覽器原理

http協(xié)議

web端發(fā)送請求報文(請求頭、URL、請求方法、請求數(shù)據(jù)、協(xié)議版本) ==》 服務(wù)器端返回數(shù)據(jù)(響應(yīng)頭、協(xié)議版本、響應(yīng)數(shù)據(jù)、響應(yīng)代碼(success/error)、服務(wù)器信息)

http協(xié)議是無狀態(tài)協(xié)議 導(dǎo)致了 cookies的產(chǎn)生(用于驗(yàn)證服務(wù)器的合法性)

http協(xié)議版本

  • 1.0 只能
  • 1.1
  • 2.0

瀏覽器原理

  1. 輸入網(wǎng)址
  2. DNS域名解析(有該網(wǎng)頁則返回,沒有返回錯誤信息)
  3. TCP三次握手(建立連接)
  4. HTTP請求(獲取資源) =》 HTTP響應(yīng)
  5. 瀏覽器渲染頁面。HTML解析 =》 DOM樹,css =》css規(guī)則樹,兩者結(jié)合渲染成render樹,瀏覽器通過render對頁面進(jìn)行渲染布局

http緩存

  • 強(qiáng)緩存(本地緩存)和協(xié)商緩存(弱緩存)
  • 網(wǎng)頁請求資源
    • 沒有緩存 =》 使用服務(wù)器資源 =》返回請求資源。
    • 有緩存 =》強(qiáng)緩存命中 =》使用緩存內(nèi)容 =》返回資源。
    • 強(qiáng)緩存未命中 =》協(xié)商緩存命中,使用緩存內(nèi)容;未命中 =》服務(wù)器資源 =》返回資源

瀏覽器如何渲染頁面

  • html解析成DOM樹,CSS解析成CSS規(guī)則樹
  • 瀏覽器將CSS規(guī)則樹附著在DOM樹上,結(jié)合生成Render渲染樹
  • 生成布局:瀏覽器解析渲染樹節(jié)點(diǎn)的位置和大小,在屏幕上渲染出所有節(jié)點(diǎn)(重排)
  • 將布局繪制在屏幕上,生成整個頁面(重繪)

Http請求頭和響應(yīng)頭

  • 請求頭
    • Accept(瀏覽器可接受服務(wù)器返回數(shù)據(jù)類型, text/html, ‘/’ 代表所有)
    • Accept-Encoding(gzip, deflate 申明瀏覽器接受的編碼方法)
    • Connection(keep-alive / close , 當(dāng)瀏覽器與服務(wù)器建立了TCP連接,keep-alive表示不斷開,下次請求服務(wù)器使用相同的TCP連接)
    • Host(服務(wù)器ip和端口)
    • Referer(瀏覽器的地址)
    • User-Agent(瀏覽器的操作系統(tǒng)和名稱、版本)
    • Cookie(存儲用戶信息)
  • 響應(yīng)頭
    • Content-Type(Content-Type:text/html;charset=UTF-8):資源文件的類型以及編碼方式
    • Content-Encoding: 編碼格式
    • Date:服務(wù)器時間
    • Server:服務(wù)器信息
    • Connection(keep-alive/ close)
    • Access-Control-Allow-Origin:指定可以訪問服務(wù)器的網(wǎng)址(Access-Control-Allow-Origin: *代表所有網(wǎng)站可以跨域資源共享)
    • Access-Control-Allow-Methods(GET, POST, DELETE, PUT)
    • Access-Control-Allow-Credentials(是否允許發(fā)送cookie)

同源策略

協(xié)議(http)+域名(www.a.com)+端口號(8080)三者一致,其中一個不同就不是同源,需要跨域

跨域的方法

  • JSONP(利用script標(biāo)簽不存在跨域的方式)
  • CORS(服務(wù)器配置響應(yīng)頭Access-Control-Allow-Origin)
  • websocket
  • 反向代理(中間件)

CSS

BFC(塊級格式化上下文)

  • bfc就是一個隔離容器,日期里面的子元素不會影響到外面的元素
  • bfc的原則:如果一個元素具有bfc,那么內(nèi)部元素任何操作都不會影響到外部元素
  • 如何觸發(fā)bfc(一般給內(nèi)部元素加overflow:hidden):
    float:none
    overflow: visible
    display:inline-block、table-cell
    position: absolute、fixed

清除浮動有哪些方式

// li標(biāo)簽會自己浮動,沒有包裹在ul標(biāo)簽里面
<style>
    *{margin: 0; padding: 0}
    ul{
      list-style: none;
      border: 10px solid red;
    }
    li{
      width: 100px;
      height: 100px;
      background: yellow;
      float: left;
    }
  </style>
  <body>
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
  </body>
// 方法1:觸發(fā)bfc清楚浮動
    ul{
      overflow: hidden;
    }
// 方法2:after方式
	ul:after{
      content: '';
      display: block;
      clear: both;
    }

position有哪些值,分別根據(jù)什么定位

  • static:默認(rèn)值,代表沒有定位
  • fixed:固定定位,相對于瀏覽器窗口進(jìn)行定位,(使用left,right, top,bottom)
  • absolute:相對于第一個有relative父元素定位
  • relative:相對定位,相對于自身定位,不脫離文檔流(位置改變了,其原有位置不會被其他元素占據(jù))

flex布局

flex 表示 flex-grow(設(shè)置擴(kuò)展比例), flex-shrink(設(shè)置收縮比例), flex-basis(不伸縮的情況下子容器的原始尺寸)

flex:1: (1, 1, 0%) 不管內(nèi)容多少,都是平分空間

flex:auto: (1, 1, auto) 根據(jù)內(nèi)容的大小來分,不是均分的(除非內(nèi)容都是一樣,才均分)

flex:0: (0, 1, 0%)可縮小,不可擴(kuò)大

flex:none:(0, 0, auto) 不可擴(kuò)大 不可縮小

CSS樣式優(yōu)先級(權(quán)重)

  • !import > 行內(nèi)樣式 > id選擇器 > class選擇器 > 標(biāo)簽選擇器 > 通配符

盒子模型

在html頁面中所以元素都可以看成是一個盒子

盒子組成

  • 內(nèi)容content
  • 內(nèi)邊距padding
  • 邊框border
  • 外邊距margin

盒模型類型

  • 標(biāo)準(zhǔn)盒模型 margin+border+padding+content
  • IE盒模型 margin+content(padding + border)

控制盒模型的模式:box-sizing:content-box(默認(rèn)值), border-box(IE盒模型)

隱藏元素的方法

  • display: none(元素消失,不占空間)
  • opacity: 0 (透明度,占空間)
  • visibility: hidden(元素消失,占空間)
  • position: absolute(將元素移除頁面)
  • clip-path(將元素剪掉)

px和rem區(qū)別

  • px: 像素,絕對單位長度,每個顯示器像素大小一樣
  • rem:相對單位,相對html根節(jié)點(diǎn)font-size的值改變,html的根節(jié)點(diǎn)默認(rèn)16px :font-size = 62.5% => 1rem = 10px (16px * 62.5% = 10px)
  • em: 相對父元素的font-size改變

重繪和重排(回流)

  • 重排(回流):布局引擎根據(jù)所有樣式計算出盒模型在頁面的位置和大小
  • 重繪:計算好盒模型在頁面的位置和大小以及其他屬性,然后根據(jù)每個盒模型的特性進(jìn)行繪制
  • 對DOM的大小、位置修改,重排
  • 對DOM的樣式修改,重繪

元素水平居中方式

  • 定位+margin
  • flex布局
  • grid布局
  • table布局

例:

<div id="app">
    <div id="sub"></div>
</div>
	 <!--   定位+margin     -->
        #app{
            width: 400px;
            height: 400px;
            position: relative;
            border: 3px solid royalblue;
        }
        #sub{
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: red;
            top: 0;
            right: 0;
            left: 0;
            bottom: 0;
            margin: auto;
        }

H5C3新特性

H5新特性

  1. 語義化標(biāo)簽
  2. 新增音頻視頻
  3. 畫布canvas
  4. localStorage和sessionStorage
  5. 表單控件email url search
  6. 拖拽釋放api

css3的新特性

  1. 選擇器:屬性選擇器、偽類選擇器、偽元素選擇器
  2. 增加了媒體查詢
  3. 文字陰影
  4. 邊框
  5. 盒子模型box-sizing
  6. 漸變
  7. 過度
  8. 自定義動畫
  9. 2D和3D

CSS屬性繼承

css三大特性 繼承(子元素繼承父元素屬性)、層疊、優(yōu)先級

CSS可以繼承的屬性

  • 文字:font
  • 文本:line-height
  • 元素可見性:visibility: hidden
  • 列表屬性: list-style

預(yù)處理器

css的預(yù)處理器增加了函數(shù)、變量等,便于維護(hù)

  • SASS
  • LESS

例:

<div id="app">
    <span></span>
</div>

#app{
    span{
        // 這里寫span的樣式
    }
}

@global: #eee;	// 定義全局變量,利于維護(hù)使用	
#app{
    color: @global;
}

Node.js

入門

數(shù)據(jù)庫連接,登錄小案例

<form action="http://localhost:8080" method="post">
    <input type="text" class="username" name="username" />
    <input type="password" class="password" name="password"/>
    <input type="submit" value="提交" />
</form>
const mysql = require('mysql')
const http = require('http')
const queryString = require('querystring')

const server = http.createServer((req, res)=>{
    let postVal = "";
    req.on("data", (chunk)=>{
        postVal+=chunk;
    })
    req.on('end', ()=>{
        let formVal = queryString.parse(postVal)
        let username = formVal.username;
        let pwd = formVal.password;
        console.log(username, pwd)

        // 連接數(shù)據(jù)庫
        const conn = mysql.createConnection({
            host: 'localhost',
            port: 3306,
            user: 'root',
            password: '116054',
            database: 'test'
        })
        conn.connect();
        conn.query('select * from user where username=? and password=?', [username, pwd], (err, result, fields)=>{
            if(err) throw err;
            console.log(result);
            if(result.length>0){
                res.writeHead(200, {'Content-Type': 'text/html;charset=utf8'});
                res.write('登錄成功')
                res.end();      // 關(guān)閉http連接
            }
        });
        conn.end();     // 關(guān)閉數(shù)據(jù)庫連接
    })
})

server.listen(8080)     // 端口監(jiān)聽

express

處理404

// catch 404 and forward to error handler
// 方法一
var createError = require('http-errors');
app.use(function(req, res, next) {
  next(createError(404));
});
// 方法二
// 所有路由之后配置處理404
app.use((req, res, next)=>{
  console.log('錯誤', err)
  res.status(404).send('404 Not Found')
})

Java

面向?qū)ο蠛兔嫦蜻^程

面向過程:更注重任務(wù)順序(簡單高效)

面向?qū)ο螅焊⒅貐⑴c者(易于維護(hù)、拓展)

封裝、繼承、多態(tài)

  • 封裝:內(nèi)部細(xì)節(jié)對外部調(diào)用透明,外部調(diào)用無需修改或關(guān)心內(nèi)部實(shí)現(xiàn)
    1.javabean的屬性私有,提供getset對外訪問數(shù)據(jù)
    2.orm框架:不需要關(guān)心鏈接如何建立,只需要調(diào)用mybatis,調(diào)方法即可

  • 繼承:繼承基類方法,進(jìn)行拓展

  • 多態(tài):基于對象所屬類的不同,外部對同一個方法調(diào)用,實(shí)際執(zhí)行的邏輯不同

    父類類型 變量名 = new 子類對象
    變量名.方法名();
    

JDK、JRE、JVM

  • jdk(java開發(fā)工具)
  • jre(java運(yùn)行環(huán)境)
  • jvm(虛擬機(jī))
    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-VuzCPhs5-1690204973231)(C:\Users\11605\AppData\Roaming\Typora\typora-user-images\image-20230711192250851.png)]

==和equals

  • ==對比的是棧中的值:基本數(shù)據(jù)類型的變量值,引用類型是堆內(nèi)存對象的地址
  • equals: 直接對比的值:value

final的作用

  • 修飾類:類不可被繼承
  • 修飾方法:不可被子類覆蓋,但可以重載
  • 修飾變量:一旦被賦值不可被修改

String StringBuffer StringBuilder

  • String是final修飾的,每次操作都會產(chǎn)生新對象(賦值變量會創(chuàng)建一個新的內(nèi)存地址)
  • string buffer和string builder都是在原對象操作
  • buffer是線程安全的,builder是線程不安全的
  • stringbuffer方法都是synchronized修飾的
  • 性能:string builder > stringbuffer > string
  • 場景:經(jīng)常改變字符串就使用后兩者,優(yōu)先使用stringbuilder,多線程使用共享變量時使用string buffer

重載和重寫的區(qū)別

  • 重載:發(fā)生在同一個類中,方法名必須相同,參數(shù)類型、個數(shù)、順序不同,方法返回值和訪問修飾符可以不同

  • 重寫:發(fā)生在父子類中,方法名、參數(shù)列表必須相同,返回值范圍小于父類,拋出的異常范圍小于父類;父類方法修飾符是private,子類就不能重寫該方法

    public int add(int a, String b)
    public String add(int a, String b)
    // 編譯報錯
    

List和Set的區(qū)別

  • list: 有序,按對象進(jìn)入順序保存,可重復(fù),允許多個null對象,可遍歷,可使用get(int index)獲取元素

  • set: 無序,元素不可重復(fù), 最多一個null對象,只能使用iterator獲取元素文章來源地址http://www.zghlxwxcb.cn/news/detail-601934.html

    List<Object> list = new ArrayList<>();
    

hashCode與equals

ArrayList和LinkedList區(qū)別

  • Arraylsi:基于動態(tài)數(shù)組,連續(xù)內(nèi)存,下標(biāo)(隨機(jī))訪問,擴(kuò)容機(jī)制:因?yàn)閿?shù)組長度固定,超出長度存數(shù)據(jù)時需要新建數(shù)組,然后將老數(shù)組的數(shù)據(jù)拷貝到新數(shù)組
  • LinkedList: 基于鏈表,存儲分散在內(nèi)存中,適合做數(shù)據(jù)插入和刪除,不適合查詢(一般不用)

到了這里,關(guān)于前端八股文的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 前端面試八股文匯總

    在HTML頁面中的所有元素都可以看成是一個盒子 盒子的組成:內(nèi)容content、內(nèi)邊距padding、邊框border、外邊距margin 盒模型的類型: 標(biāo)準(zhǔn)盒模型 margin + border + padding + content IE盒模型 margin + content(border + padding) 控制盒模型的模式:box-sizing:content-box(默認(rèn)值,標(biāo)準(zhǔn)盒模型)、border-b

    2024年02月04日
    瀏覽(27)
  • 前端常見面試八股文

    前端常見面試八股文

    1、H5新增標(biāo)簽有哪些? 一、語義化標(biāo)簽 header、footer、nav、aside、section、article 語義化的意義? 1、更適合搜索引擎的爬蟲爬取有效的信息,利于SEO。 2、對開發(fā)團(tuán)隊很友好,增加了標(biāo)簽的可讀性,結(jié)構(gòu)更加的清晰,便于團(tuán)隊的開發(fā)和維護(hù)。 二、多媒體標(biāo)簽 視頻標(biāo)簽:video 屬性

    2023年04月08日
    瀏覽(29)
  • 【面試】前端面試八股文

    【面試】前端面試八股文

    前端思維導(dǎo)圖 優(yōu)點(diǎn) 大可愛html+css+js+node 全面可下載 千峰html+css 簡潔漂亮 千峰js 簡潔漂亮 (1)標(biāo)簽引用 (2)文件引用 解釋型語言:JS不需要被編譯為機(jī)器碼而是直接執(zhí)行,開發(fā)輕松 動態(tài)型語言:JS變量與任何值類型都不關(guān)聯(lián),都可以重新分配類型值 弱類型語言:變量數(shù)據(jù)

    2024年02月02日
    瀏覽(26)
  • 前端八股文(性能優(yōu)化篇)

    前端八股文(性能優(yōu)化篇)

    目錄 1.CDN的概念 2.CDN的作用 3.CDN的原理 ? 4.CDN的使用場景 5.懶加載的概念 6.懶加載的特點(diǎn) 7.懶加載的實(shí)現(xiàn)原理 8.懶加載與預(yù)加載的區(qū)別 9.回流與重繪的概念及觸發(fā)條件 (1)回流 (2)重繪 10.?如何避免回流與重繪? CDN(內(nèi)容分發(fā)網(wǎng)絡(luò))是指一種通過互聯(lián)網(wǎng)互相連接的電腦網(wǎng)

    2024年01月20日
    瀏覽(20)
  • 前端基礎(chǔ)面試題八股文

    前端基礎(chǔ)面試題八股文

    代碼結(jié)構(gòu): 使頁面在沒有css的情況下,也能夠呈現(xiàn)出好的內(nèi)容結(jié)構(gòu) 有利于SEO: 爬蟲根據(jù)標(biāo)簽來分配的權(quán)重,因此可以和搜索引擎建立良好的溝通,幫助爬蟲抓取更多的有效信息 方便其他設(shè)備解析: 如屏幕閱讀器、盲人閱讀器、移動設(shè)備等,以有意義的方式來渲染頁面 便于

    2024年02月07日
    瀏覽(21)
  • 前端面試題八股文匯總(最新)

    前端面試題八股文匯總(最新)

    前言:小伙伴們,本篇文章是博主自己在面試過程中的一些面試題的記錄,自己在總結(jié)回顧記錄的同時希望也能幫助到你們,可以結(jié)合對應(yīng)的知識點(diǎn)去理解和查看!有什么不對的地方歡迎伙伴們指正!大家一起學(xué)習(xí)!一共有五大回合,如果在后續(xù)面試過程中還會持續(xù)更新!

    2023年04月08日
    瀏覽(47)
  • 前端八股文(三)—— 性能優(yōu)化部分

    前端八股文(三)—— 性能優(yōu)化部分

    1、懶加載的概念 懶加載也叫做延遲加載、按需加載,指的是在長網(wǎng)頁中延遲加載圖片數(shù)據(jù),是一種較好的網(wǎng)頁性能優(yōu)化的方式。在比較長的網(wǎng)頁或應(yīng)用中,如果圖片很多,所有的圖片都被加載出來,而用戶只能看到可視窗口的那一部分圖片數(shù)據(jù),這樣就浪費(fèi)了性能。 如果使

    2024年02月22日
    瀏覽(29)
  • 面試 JavaScript 框架八股文十問十答第七期

    作者:程序員小白條,個人博客 相信看了本文后,對你的面試是有一定幫助的!關(guān)注專欄后就能收到持續(xù)更新! ?點(diǎn)贊?收藏?不迷路!? 1)原型修改、重寫 在 JavaScript 中,可以通過修改或重寫對象的原型來改變對象的行為。原型修改指的是直接修改對象的原型,而原型

    2024年02月20日
    瀏覽(18)
  • 史上最全前端八股文來了

    史上最全前端八股文來了

    由于最近比較忙活沒時間學(xué)習(xí)新東西,現(xiàn)在得空想著能不能好好整理出一些有用的東西,讓記憶深刻一點(diǎn),免得到時候?qū)嵙?xí)找工作面試的時候一問三不知,也希望大家能指正出錯誤和對大家有點(diǎn)幫助,一起進(jìn)步,加油奧里給!??! 那么廢話不多說直接進(jìn)入正題,如果覺得可以

    2024年02月08日
    瀏覽(55)
  • 前端八股文everybody準(zhǔn)備好了沒

    前端八股文everybody準(zhǔn)備好了沒

    由于最近比較忙活沒時間學(xué)習(xí)新東西,現(xiàn)在得空想著能不能好好整理出一些有用的東西,讓記憶深刻一點(diǎn),免得到時候?qū)嵙?xí)找工作面試的時候一問三不知,也希望大家能指正出錯誤和對大家有點(diǎn)幫助,一起進(jìn)步,加油奧里給?。?! 那么廢話不多說直接進(jìn)入正題,如果覺得可以

    2024年02月08日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包