答: 原型:每個對象都與另外一個對象相關聯,那個關聯的對象就稱爲原型。
例如:函數Person有一個屬性prototype,指向一個對象,對於普通函數來講沒多意義,對於構造函數就有做用了,當使用new操做符時,會把Person.prototype(原型對象)賦值給實例的__proto__(原型實例)屬性。javascript
JS有一個原型查找機制,把原來定義在實例上的方法,放到原型對象上去,經過構造函數的new操做,會把原型對象賦值給實例的__proto__屬性,那麼當使用返回的實例去調用某一個方法的時候,若是實例自己上沒有,就去自動去實例的__proto__上去查找,這樣達到方法的複用,減小內存開銷。前端
原型鏈:每個對象,都有一個原型對象與之關聯,這個原型對象它也是一個普通對象,這個普通對象也有本身的原型對象,這樣層層遞進,就造成了一個鏈條,這個鏈條就是原型鏈。經過原型鏈能夠實現JS的繼承,把父類的原型對象賦值給子類的原型,這樣子類實例就能夠訪問父類原型上的方法了。java
2Person.prototype.constructor == Person 3 4Person.prototype.__proto__.constructor == Object 5 6Person.prototype.__proto__ == Object.prototype 7 8Object.prototype.__proto__ == null
10 function Anima(name){ //父類 11 this.name = name; 12 } 13 14 Anima.prototype.sayName = function(){ 15 console.log(this.name) 16 } 17 18 function Person(name,age){ //子類 19 Anima.call(this,name); 20 this.age = age; 21 } 22 23 Person.prototype = Object.create(Anima.prototype, { 24 constructor: { 25 value: Person, 26 enumerable: false 27 } 28 }) 29 30 31 var p = new Persion("haha",12); 32 Extends //ES6
點擊獲取 web前端全棧架構視頻課程ios
答:做用域是指程序源代碼中定義變量的區域,限定一個變量可訪問的範圍的,做用域的本質是對象。在JS採用的詞法做用域,在書寫代碼的時候(定義函數的時候),做用域就已經肯定好了。 在ES6環境下,包含3個做用域,全局globel,函數做用域,快級做用域( {} ) (eval)web
做用域鏈:由多級做用域對象,逐級引用的鏈式結構。本質爲執行上下文的scope屬性,存儲全部的變量,包括局部與全局,控制變量的使用順序。面試
var b = 10; //1:輸出?2:改造代碼輸出10或20 (function b(){ b = 20; console.log(b); })(); var b = 10; (function b(b) { 在這個函數b是一個常量,在函數b內部是可使用的,可是不能修改,若是加上use strict 嚴格模式就會報錯。 window.b = 20; console.log(b) //輸出10 })(b)
var a = 10; (function () { console.log(a) a = 5 console.log(window.a) var a = 20; console.log(a) })()
答:當函數能夠記住並訪問外部做用域時,就產生了閉包,那個外部做用域就稱爲閉包。axios
造成的緣由:外層函數的做用域對象沒法釋放。
做用:保護一個變量,重用一個變量。壞處:使用不當,會形成內存泄漏。api
大白話來解釋:函數A和函數B,當內部函數B引用了A 的局部變量時,函數A 稱爲閉包
緣由是:JS是詞法做用域,B的做用域鏈上有對A執行環境的引用(這個執行環境用函數來表示),A的執行環境AO就不會回收。跨域
答:JS在運行過程當中會產生執行上下文環境(context),context記錄了包含函數在哪裏被調用,做用域scope,this等信息。this就是context的其中一個屬性,會在函數的執行過程當中使用。This是在運行時候綁定的,它指代的上下文對象取決於函數調用的各類條件。
this提供了一種優雅的方式來隱式的傳遞一個對象的引用,因此在函數中使用this能夠更加方便的複用函數。數組
一、全局使用 this === window 不多使用
二、函數當中 在全局調用這個fn() this === window
三、在方法當中使用 this === 調用當前這個函數的所在的對象啊
四、構造函數this執向的是 new 建立出來的實例對象啊
五、DOM事件處理函數中的this,指向當前的DOM節點
六、經過 bind,call,apply 操做符來顯示的設置 this的指向
bind:綁定函數裏面的this,返回新函數, call,apply:綁定並執行這個函數,前者傳參是「,」隔開,後者是數組
七、ES6的箭頭函數 箭頭函數沒有本身的this,父做用域的this
var x = 3; var foo = { x: 2, baz: { x: 1, bar: function() { return this.x; } } } var go = foo.baz.bar; go()? foo.baz.bar()? //綜合面試題 function Foo() { Foo.a = function() { console.log(1) } this.a = function() { console.log(2) } } Foo.prototype.a = function() { console.log(3) } Foo.a = function() { console.log(4) } Foo.a(); let obj = new Foo(); obj.a(); Foo.a();
答案:以上都是Function原型上的方法。
Function.prototype.myCall = function(context,...args){//綁定並執行 //執行函數 var fn = this; context.fn = fn; context.fn(...args); delete context.fn } Function.prototype.myBind = function(context){//綁定返回新的執行函數 //判斷調用者是否是函數 if(typeof this != 'function'){ throw new Error("Error") } //截取傳遞的參數 let args = [...arguments].slice(1); var _this = this;//保存一下當前的調用者 return function F() { return _this.apply(context,args.concat([...arguments])) } }
答:淺拷貝,就是複製一個對象,當對象的屬性值沒有引用類型的時候。
Object.assign 迭代(for..in for..of object.enteries) 擴展運算符等。
反之若是對象中還有引用類型,連着引用類型一併拷貝稱爲深拷貝。
JSON對象的方法(會忽略到值爲函數和null的屬性),遞歸。
function deepCopy(obj){ //判斷對象的類型 var newObj = Array.isArray(obj)?[]:{}; if(obj && typeof obj == "object"){ //迭代 for(var key in obj){ if(typeof obj[key] == 'obj'){ newObj[key] = deepCopy(obj[key]) }else{ newObj[key] = obj[key] } } } return newObj }
答:Ajax的全稱是異步的js與xml技術,經過它與後臺服務器進行數據交換,可使網頁實現異步更新,言外之意是在不從新加載整個頁面的狀況下,對網頁進行局部更新。
1.nex xmlhttprequset對象 2.open(method,url,false) 3.綁定redaystatechange事件 4.調用send方法,若是是post請求,能夠傳遞參數
前端的請求方式除了經常使用Get和Post,還有update,delete,put等(restful api設計)
GET 請求可被緩存,保留在瀏覽器歷史記錄中 ,請求的參數是直接跟在URL上,所以不該傳遞敏感數據。
GET 請求有長度限制(2048字符),IE和Safari瀏覽器限制2k;Opera限制4k;Firefox,Chrome限制8k 。
GET 請求一般只應當用於從後臺獲取數據。
POST 請求不會被緩存,不會保留在瀏覽器歷史記錄中
POST 請求對數據長度沒有要求。
POST 請求一般用於日後臺提交數據。
答: let,count快級做用域;解構,從對象和數組中提取值;箭頭函數;字符串模版;擴展運算符...;對象的簡寫;module;promise(async);class;對原生對象的擴展(新增長了不少方法) ;for-of (Object.keys,values,entries等);Symbal();
不經常使用的proxy,reflect,generate函數
答:Promise是解決異步回調的ES語法的標準,一般用來解決異步嵌套和多異步同時完成回調等問題。
Promise是一個構造函數,至關於一個容器,把異步代碼包裹在裏面,promise有三個狀態(pending(進行中)、fulfilled(已成功)和rejected(已失敗))初始化爲pending,當異步請求成功後調用resolve函數,狀態從pending--->fulfilled,失敗的時候調用reject,狀態從pending--->rejected。狀態不可逆。 缺點:書寫麻煩,不能實現異步代碼,同步執行的需求(配合async函數使用便可)
答:跨域是瀏覽器端行爲,根據同源策略,當請求的協議、域名、端口只有一個不一樣,就會跨域,跨域是瀏覽器爲了安全存在的機制,瀏覽器會把跨域請求的數據去掉,同行報錯。
在實際開發不免會出現跨域的狀況,解決方案一般有
1.JSONP技術,利用了script的src屬性沒有跨域限制
2.CORS,當在相應頭信息中添加access-control-allow-origain屬性,瀏覽器讀取到就會容許返回數據。後臺配置,或者下一個瀏覽器插件便可。
3.後臺代理(Node)
4.Iframe域的提高(不多)
答:防抖和節流都是爲了提高運行效率,減小函數的執行次數。
防抖:把屢次函數執行,合併成一次執行
function debounce(fn,delay){ //fn真正執行的函數,delay間隔時間 var timer = null; return function(){ var args = arguments; var that = this; if(timer) clearTimeout(timer) timer = setTimeout(function(){ fn.apply(that,[...arguments]) },delay) } }
節流 :規定一個單位時間,在單位時間內觸發一個事件回調,觸發時超過間隔時間則執行,不然不執行。
function throttle(fn,gapTime){ let _lastTime = null; return function(){ var that = this; var args = arguments; let _nowTime = + new Date(); if(_nowTime-_lastTime > gapTime || !_lastTime){ fn.apply(that,args); _lastTime = _nowTime; } } }
答:js是非阻塞單線程語言,js在執行過程當中會產生執行環境,執行環境會被順序的加入到執行棧,當遇到異步任務,會添加到task隊列當中,執行同步棧,當同步棧執行完之後,event loop 就會從異步task隊列當中提取要執行的代碼放到執行棧中。這個一個過程稱爲事件循環。因此JS的異步仍是同步過程。
console.log('script start') setTimeout(function() { console.log('setTimeout') }, 0) new Promise(resolve => { console.log('Promise') resolve() }) .then(function() { console.log('promise1') }) .then(function() { console.log('promise2') }) console.log('script end') //輸出結果?
答:前端的安全問題,在工做過程當中會注意這些問題。
一、XSS 代碼注入問題,一般不信任用戶的輸入,轉義輸入輸出內容()encodeURIComponent),括號 尖括號等。利用用戶對站點的信任 二、CSRF 跨站請求僞造 是一種挾制用戶在當前已登陸的web應用中執行非本意的攻擊 大白話:利用用戶登陸態發起惡意請求 網站對用戶的信任
添加驗證碼(體驗稍微差一些),不讓第三方訪問cookie 對cookie設置 samesite, 請求驗證 加 token ,
三、密碼問題:對密碼進行加密(MD5等)
答:產生的緣由:JS使用Number類型表示一個數字,使用64位。
計算機先把10進制轉位2進制,0.1和0.2轉成二進制的時候還會無限循環,因爲有51位位數的限制,多餘的會被裁掉,因此在進制之間轉換就會丟掉精度。
一般能夠把小數乘以倍數轉成正整數,計算完後再轉回去。
parseFloat((0.1 + 0.2).toFixed(10))
答:前端進行網絡請求經常使用的form,Ajax,fetch
經常使用的庫文件Jquery或者axios等。 Form提交數據頁面會刷新,使用體驗不佳。 Ajax是一個綜合技術,能夠實現異步更新頁面內容。使用起來方便,一般使用JQ的封裝,會額外的JS加載代價。 Fetch是新的API,比較底層。目前瀏覽器兼容性問題多一些,好比老版本不會攜帶cookie,不能直接傳遞JS對象做爲參數,不支持JSONP等
答:一、Object.prototype.toString.call(),前提是toString方式沒有被重寫。
二、instanceof 內部機制是經過判斷對象的原型鏈中是否是能找到類型的 prototype。
[] instanceof Object; // true
三、Array.isArray() ES5新增的方法,兼容性稍微差一些。
答:會
defer:並行下載,在頁面解析完後執行,會按照script的順序執行。(經常使用)
async:異步下載代碼,下載完畢後離職執行代碼,不會按照頁面的script順序。
20.常見前端性能優化有哪些?
答:
1:加載優化
CDN,文件壓縮混淆合併,按需加載(異步組件),前端緩存,瀏覽器緩存(cache-control,exprices) DNS預先解析,服務器渲染 nuxt,next(SEO),圖片懶加載
2:腳本優化
減小合併DOM操做(createDocumentFragment),CSS3代替js動畫,緩存變量,用requestAnimationFrame代理setTimeout,減小reflow與repain,事件代理,開啓GPU渲染tranfrom:translateX(0)
3:圖片優化
雪碧圖(減小請求),使用SVG和iconfont(字體圖片)代替圖片,圖片壓縮