国产另类ts人妖一区二区_欧美肥老太做爰视频_快穿高h肉_国产欧美综合在线

當前位置: 首頁 / 技術干貨 / 正文
好程序員web前端培訓分享JS面試題總結一

2020-07-23

web前端培訓

  好程序員web前端培訓分享JS面試題總結一,準備參加面試的小伙伴們一起看一看吧,希望本篇文章能夠?qū)氖聎eb前端工作的小伙伴們有所幫助。

好程序員

  一、說說你對閉包的認識

  (一)什么是閉包

  一句話解釋:

  能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。

  稍全面的回答:

  在js中變量的作用域?qū)儆诤瘮?shù)作用域, 在函數(shù)執(zhí)行完后,作用域就會被清理,內(nèi)存也會隨之被回收,但是由于閉包函數(shù)是建立在函數(shù)內(nèi)部的子函數(shù), 由于其可訪問上級作用域,即使上級函數(shù)執(zhí)行完, 作用域也不會隨之銷毀, 這時的子函數(shù)(也就是閉包),便擁有了訪問上級作用域中變量的權限,即使上級函數(shù)執(zhí)行完后作用域內(nèi)的值也不會被銷毀。

  這里涉及到對函數(shù)作用域的認識: js變量分為全局變量和局部變量;函數(shù)內(nèi)部可以直接讀取全局變量,而在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量

  (二)閉包解決了什么問題

  1. 可以讀取函數(shù)內(nèi)部的變量

  2. 讓這些變量的值始終保持在內(nèi)存中。不會在函數(shù)調(diào)用后被清除

  可以通過下面的代碼來幫助理解上面所說的:

  function addCounter() {

  let counter = 0

  const myFunction = function () {

  counter = counter + 1

  return counter

  }

  return myFunction

  }

  const increment = addCounter()

  const c1 = increment()

  const c2 = increment()

  const c3 = increment()

  console.log('increment:', c1, c2, c3);

  // increment: 1 2 3

  在這段代碼中increment實際上就是閉包函數(shù)myFunction, 它一共運行了三次,diyi次的值是1,第二次的值是2,第三次的值是3。這證明了,函數(shù)addCounter中的局部變量counter一直保存在內(nèi)存中,并沒有在addCounter調(diào)用后被自動清除。

  (三)閉包的應用場景

  在開發(fā)中, 其實我們隨處可見閉包的身影, 大部分前端 JavaScript 代碼都是“事件驅(qū)動”的,即一個事件綁定的回調(diào)方法; 發(fā)送ajax請求成功|失敗的回調(diào);setTimeout的延時回調(diào);或者一個函數(shù)內(nèi)部返回另一個匿名函數(shù),這些都是閉包的應用。

  下面是具體應用的栗子:

  1. 老掉牙的取正確值問題

  for (var i = 0; i < 10; i++) {

  setTimeout(function () {

  console.log(i) //10個10

  }, 1000)

  }

  怎么取到每一次循環(huán)的正確值呢? 閉包這樣用:

  for (var i = 0; i < 10; i++) {

  ((j) => {

  setTimeout(function () {

  console.log(j) //1-10

  }, 1000)

  })(i)

  }

  聲明了10個自執(zhí)行函數(shù),保存當時的值到內(nèi)部

  2.使用閉包模擬私有變量

  私有變量在java里使用private聲明就可以了, 但是在js中還沒有,但是我們可以使用閉包模擬實現(xiàn)。

  var counter = (function () {

  var privateCounter = 0;

  function changeBy(val) {

  privateCounter += val

  }

  return {

  increment: function () {

  changeBy(1)

  },

  decrement: function () {

  changeBy(-1)

  },

  value: function () {

  return privateCounter

  }

  }

  })();

  counter.value() //0

  counter.increment() //1

  counter.increment() //2

  counter.decrement() //1

  匿名函數(shù)已經(jīng)定義就立即執(zhí)行, 創(chuàng)建出一個詞法環(huán)境包含counter.increment、counter.decrement、counter.value三個方法,還包含了兩個私有項:privateCounter變量和changeBy函數(shù)。這兩個私有項無法在匿名函數(shù)外部直接訪問,必須通過匿名包裝器返回的對象的三個公共函數(shù)訪問。

  (四)閉包的缺點

  1. 由于閉包會是的函數(shù)中的變量都被保存到內(nèi)存中,濫用閉包很容易造成內(nèi)存消耗過大,導致網(wǎng)頁性能問題。解決方法是在退出函數(shù)之前,將不再使用的局部變量全部刪除。

  2. 閉包可以使得函數(shù)內(nèi)部的值可以在函數(shù)外部進行修改。所有,如果你把父函數(shù)當作對象(object)使用,把閉包當作它的公用方法(Public Method),把內(nèi)部變量當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。

  二、跨域問題有哪些處理方式

  跨域解決方案

  1. 通過jsonp跨域

  2. 跨域資源共享(CORS)

  3. nodejs中間件代理跨域

  4. nginx反向代理中設置proxy_cookie_domain

  Ⅰ.通過jsonp跨域

  通常為了減輕web服務器的負載,我們把js、css,img等靜態(tài)資源分離到另一臺獨立域名的服務器上,在html頁面中再通過相應的標簽從不同域名下加載靜態(tài)資源,而被瀏覽器允許,基于此原理,我們可以通過動態(tài)創(chuàng)建script,再請求一個帶參網(wǎng)址實現(xiàn)跨域通信。

  1. 原生實現(xiàn)

  服務器端返回如下(返回即執(zhí)行全局函數(shù))

  jsonCallback({"status": 0, "user": "admin"})

  2. jquery方式實現(xiàn)

  $.ajax({

  url: 'http://www.domain2.com:8080/login',

  type: 'get',

  dataType: 'jsonp', // 請求方式為jsonp

  jsonpCallback: "handleCallback", // 自定義回調(diào)函數(shù)名

  data: {}

  });

  Ⅱ.跨域資源共享(CORS)

  CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)跨域資源共享 CORS 詳解。看名字就知道這是處理跨域問題的標準做法。CORS有兩種請求,簡單請求和非簡單請求。

  · 簡單請求

  只要同時滿足以下兩大條件,就屬于簡單請求:

  1. 請求方法是以下三種方法之一:

  · HEAD

  · GET

  · POST

  2. HTTP請求頭的信息不超出以下幾種字段:

  · Accept

  · Accept-Language

  · Content-Language

  · Last-Event-ID

  · Content-Type:只限于三個值application/x-www-form-urlencoded、multipart/form-data、text/plain

  如果是簡單請求, 后端處理即可, 前端什么也不用干; 這里注意的是如果前端要帶cookie, 前端也需要單獨設置

  · 原生ajax (前端)

  var xhr = new XMLHttpRequest();

  // 前端設置是否帶cookie

  xhr.withCredentials = true;

  ...

  · jquery (前端)

  $.ajax({

  ...

  xhrFields: {

  withCredentials: true // 前端設置是否帶cookie

  },

  crossDomain: true, // 會讓請求頭中包含跨域的額外信息,但不會含cookie

  ...

  });

  · vue中使用axios (前端)

  axios.defaults.withCredentials = true

  · 后端node

  可以借助koa2-cors快速實現(xiàn)

  const path = require('path')

  const Koa = require('koa')

  const koaStatic = require('koa-static')

  const bodyParser = require('koa-bodyparser')

  const router = require('./router')

  const cors = require('koa2-cors')

  const app = new Koa()

  const port = 9871

  ...

  // 處理cors

  app.use(cors({

  origin: function (ctx) {

  return 'http://localhost:9099'

  },

  credentials: true,

  allowMethods: ['GET', 'POST', 'DELETE'],

  allowHeaders: ['t', 'Content-Type']

  }))

  // 路由

  app.use(router.routes()).use(router.allowedMethods())

  // 監(jiān)聽端口

  ...

  Ⅲ.nodejs中間件代理跨域

  跨域原理: 同源策略是瀏覽器的安全策略, 不是HTTP協(xié)議的一部分。服務器端調(diào)用HTTP接口只是使用HTTP協(xié)議, 不會執(zhí)行js腳本, 不需要檢驗同源策略,也就不存在跨域問題。

  實現(xiàn)思路:通過起一個代理服務器, 實現(xiàn)數(shù)據(jù)的轉發(fā),也可以通過設置cookieDomainRewrite參數(shù)修改響應頭cookie中域名,實現(xiàn)當前域下cookie的寫入

  · 在vue框架下實現(xiàn)跨域

  利用node + webpack + webpack-dev-server代理接口跨域。在開發(fā)環(huán)境下,由于vue渲染服務和接口代理服務都是webpack-dev-server同一個,所以頁面與代理接口之間不再跨域,無須設置headers跨域信息了。后臺可以不做任何處理。

  webpack.config.js部分配置

  module.exports = {

  entry: {},

  module: {},

  ...

  devServer: {

  historyApiFallback: true,

  proxy: [{

  context: '/login',

  target: 'http://www.daxihong.com:8080', // 代理跨域目標接口

  changeOrigin: true,

  secure: false, // 當代理某些https服務報錯時用

  cookieDomainRewrite: 'www.daxihong.com' // 可以為false,表示不修改

  }],

  noInfo: true

  }

  }

  Ⅳ.nginx反向代理中設置

  和使用node中間件跨域原理相似。前端和后端都不需要寫額外的代碼來處理, 只需要配置一下Ngnix

  server{

  # 監(jiān)聽9099端口

  listen 9099;

  # 域名是localhost

  server_name localhost;

  #凡是localhost:9099/api這個樣子的,都轉發(fā)到真正的服務端地址http://localhost:9871

  location ^~ /api {

  proxy_pass http://localhost:9871;

  }

  }

  對于跨域還有挺多方式可以實現(xiàn), 這里就不一一列舉了。

  三、for...in 和 for...of的區(qū)別

  1. for...of 是ES6新引入的特性,修復了ES5引入的for...in的不足

  2. for...in 循環(huán)出的是key,for...of循環(huán)出的是value

  3. for...of不能循環(huán)普通的對象,需要通過和Object.keys()搭配使用

  4. 推薦在循環(huán)對象屬性的時候,使用for...in,在遍歷數(shù)組的時候的時候使用for...of

  四、new一個對象,這個過程中發(fā)生了什么

  var obj = new Object("name","sansan");

  1. 創(chuàng)建一個新對象,如:var obj = {};

  2. 新對象的_proto_屬性指向構造函數(shù)的原型對象。

  3. 將構造函數(shù)的作用域賦值給新對象。(也所以this對象指向新對象)

  4. 執(zhí)行構造函數(shù)內(nèi)部的代碼,將屬性添加給obj中的this對象。

  5. 返回新對象obj。

  五、js的防抖和節(jié)流是什么

  · 防抖: 在事件被觸發(fā)n秒后再執(zhí)行回調(diào),如果在這n秒內(nèi)又被觸發(fā),則重新計時。

  使用場景:

  1. 給按鈕加函數(shù)防抖防止表單多次提交。

  2. 對于輸入框連續(xù)輸入進行AJAX驗證時,用函數(shù)防抖能有效減少請求次數(shù)。

  簡單的防抖(debounce)代碼:

  function debounce(fn, wait) {

  var timeout = null;

  return function () {

  if (timeout !== null) clearTimeout(timeout)

  timeout = setTimeout(fn, wait)

  }

  }

  // 處理函數(shù)

  function handle() {

  console.log(Math.random())

  }

  //滾動事件

  window.addEventListener('scroll', debounce(handle, 2000));

  · 節(jié)流: 就是指連續(xù)觸發(fā)事件但是在 n 秒中只執(zhí)行一次函數(shù)。節(jié)流會稀釋函數(shù)的執(zhí)行頻率。

  function throttle(func, delay) {

  var prev = Date.now();

  return function () {

  var context = this;

  var args = arguments;

  var now = Date.now();

  if (now - prev >= delay) {

  func.apply(context, args);

  prev = Date.now();

  }

  }

  }

  function handle() {

  console.log(Math.random());

  }

  window.addEventListener('scroll', throttle(handle, 2000));

  區(qū)別:

  函數(shù)節(jié)流不管事件觸發(fā)有多頻繁,都會保證在規(guī)定時間內(nèi)一定會執(zhí)行一次真正的事件處理函數(shù),而函數(shù)防抖只是在最后一次事件后才觸發(fā)一次函數(shù)。 比如在頁面的無限加載場景下,我們需要用戶在滾動頁面時,每隔一段時間發(fā)一次Ajax請求,而不是在用戶停下滾動頁面操作時才去請求數(shù)據(jù)。這樣的場景,就適合用節(jié)流技術來實現(xiàn)。

好程序員公眾號

  • · 剖析行業(yè)發(fā)展趨勢
  • · 匯聚企業(yè)項目源碼

好程序員開班動態(tài)

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數(shù)據(jù)+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發(fā) <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數(shù)據(jù)分析 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發(fā) <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2019-07-22(北京)

    開班盛況
IT培訓IT培訓
在線咨詢
IT培訓IT培訓
試聽
IT培訓IT培訓
入學教程
IT培訓IT培訓
立即報名
IT培訓

Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號