隔着超薄肉丝进入小说_男女刺激性视频大片_女教师的诱波多野结衣_一级欧美过瘾大片

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

2020-07-23

web前端培訓

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

好程序員

  一、說說你對閉包的認識

  (一)什么是閉包

  一句話解釋:

  能夠讀取其他函數內部變量的函數。

  稍全面的回答:

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

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

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

  1. 可以讀取函數內部的變量

  2. 讓這些變量的值始終保持在內存中。不會在函數調用后被清除

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

  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實際上就是閉包函數myFunction, 它一共運行了三次,diyi次的值是1,第二次的值是2,第三次的值是3。這證明了,函數addCounter中的局部變量counter一直保存在內存中,并沒有在addCounter調用后被自動清除。

  (三)閉包的應用場景

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

  下面是具體應用的栗子:

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

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

  setTimeout(function () {

  console.log(i) //10個10

  }, 1000)

  }

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

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

  ((j) => {

  setTimeout(function () {

  console.log(j) //1-10

  }, 1000)

  })(i)

  }

  聲明了10個自執行函數,保存當時的值到內部

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

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

  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

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

  (四)閉包的缺點

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

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

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

  跨域解決方案

  1. 通過jsonp跨域

  2. 跨域資源共享(CORS)

  3. nodejs中間件代理跨域

  4. nginx反向代理中設置proxy_cookie_domain

  Ⅰ.通過jsonp跨域

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

  1. 原生實現

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

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

  2. jquery方式實現

  $.ajax({

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

  type: 'get',

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

  jsonpCallback: "handleCallback", // 自定義回調函數名

  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快速實現

  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())

  // 監聽端口

  ...

 ?、?nodejs中間件代理跨域

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

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

  · 在vue框架下實現跨域

  利用node + webpack + webpack-dev-server代理接口跨域。在開發環境下,由于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{

  # 監聽9099端口

  listen 9099;

  # 域名是localhost

  server_name localhost;

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

  location ^~ /api {

  proxy_pass http://localhost:9871;

  }

  }

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

  三、for...in 和 for...of的區別

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

  2. for...in 循環出的是key,for...of循環出的是value

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

  4. 推薦在循環對象屬性的時候,使用for...in,在遍歷數組的時候的時候使用for...of

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

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

  1. 創建一個新對象,如:var obj = {};

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

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

  4. 執行構造函數內部的代碼,將屬性添加給obj中的this對象。

  5. 返回新對象obj。

  五、js的防抖和節流是什么

  · 防抖: 在事件被觸發n秒后再執行回調,如果在這n秒內又被觸發,則重新計時。

  使用場景:

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

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

  簡單的防抖(debounce)代碼:

  function debounce(fn, wait) {

  var timeout = null;

  return function () {

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

  timeout = setTimeout(fn, wait)

  }

  }

  // 處理函數

  function handle() {

  console.log(Math.random())

  }

  //滾動事件

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

  · 節流: 就是指連續觸發事件但是在 n 秒中只執行一次函數。節流會稀釋函數的執行頻率。

  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));

  區別:

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

好程序員公眾號

  • · 剖析行業發展趨勢
  • · 匯聚企業項目源碼

好程序員開班動態

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

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

    開班盛況

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

    開班盛況
  • 大數據+人工智能 <高端班>

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

    開班盛況

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

    開班盛況
  • JavaEE分布式開發 <高端班>

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

    開班盛況

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

    開班盛況
  • Python人工智能+數據分析 <高端班>

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

    預約報名

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

    開班盛況
  • 云計算開發 <高端班>

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

    預約報名

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

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

Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號