1、如何正確判斷一個數據的基本類型?javascript
一、typeof css
typeof 對於原始類型(null undefined string number boolean symbol),除了null 都能顯示正確的類型html
typeof null === 'object'
複製代碼
typeof 對於對象來講,除了函數外其餘都是object 類型前端
typeof [] === 'object'
typeof console.log === 'function'
複製代碼
因此typeof 沒法正確區分對象和null(數組和null)vue
二、instanceof 判斷已知對象類型的方法java
MDN 的解釋: instanceof
運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype
屬性node
判斷一個對象是不是數據類型的實例
webpack
於是能夠衍生出 用constructor 來判斷類型({}).constructor == Object,可是constructor 是能夠修改的ios
function Fn(){};
Fn.prototype=new Array();
var f=new Fn()
console.log(f.constructor===Fn); // false複製代碼
,於是不許確。css3
三、通用型,借用Object.prototype.toString.call 來實現
var gettype=Object.prototype.toString
gettype.call('aaaa') 輸出 [object String]
gettype.call(2222) 輸出 [object Number]
gettype.call(true) 輸出 [object Boolean]
gettype.call(undefined) 輸出 [object Undefined]
複製代碼
// 進行一層封裝
let Type = (function(){
let type = {};
let typeArr = ['String', 'Object', 'Number', 'Array', 'Undefined', 'Null', 'Symbol'];
for(let i = 0; i < typeArr.length; i++){
type['Is'+ typeArr[i]] = function(obj){
return Object.prototype.toString.call(obj) === '[object '+ typeArr[i] +']'
}
}
return type
})()
複製代碼
eg:(第一個字母小寫,第二個字母大寫)
Type.IsFunction(function() {}) Type.IsObject({}) 這樣使用。複製代碼
2、對象的深淺拷貝
什麼是淺拷貝?如何實現淺拷貝?什麼是深拷貝?如何實現深拷貝?
淺拷貝
利用Object.assign({}, obj) or 展開運算符 ... 來實現淺拷貝
let a = {
age: 1
}
let b = Object.assign({}, a)
a.age = 2
console.log(a.age) // 1
console.log(b.age) // 2複製代碼
let a = {
age: 1
}
let b = { ...a }
a.age = 2複製代碼
深拷貝
利用JSON.parse(JSON.stringify(object)) 來解決,(基本夠用了)但這個有侷限性,
自個封裝 lodash 深拷貝函數
function deepClone(obj){
function isObject(o){
return (typeof o === 'object' || typeof o === 'function') && o !== null
}
if(!isObject(obj)){
throw new Error('not object')
}
let isArray = Array.isArray(obj)
let newObj = isArray? [...obj] : { ...obj }
Reflect.ownKeys(newObj).forEach((key)=>{
newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
})
return newObj
}
// eg
let obj = {
a: [1,2,3],
b:{
c:2,
d:3
}
}
let newObj = deepClone(obj)
newObj.b.c = 33
console.log(obj.b.c) // 2複製代碼
3、call、apply 和 組合繼承
function Product(name, price){
this.name = name;
this.price = price;
}
function Food(name, price){
Product.call(this, name, price)
this.category = 'food'
}
let foot1 = new Food('chees', 5);
foot1 // 複製代碼
經過Food 構造方法裏的call()
,成功使Food 擴展了name 以及price .(借用)
apply()
和 call()
都是爲了改變某個函數運行時的上下文而存在的(就是爲了改變函數內部的 this
指向)。而後,由於這兩個方法會當即調用,因此爲了彌補它們的缺失,還有個方法 bind()
。
/*apply()方法 參數是已數組的形式 add.apply(sub, [4,2]) */
function.apply(thisObj[, argArray])
/*call()方法 參數*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);複製代碼
4、寄生組合繼承(經典例子):
function Parent(value){
this.val = value
}
Parent.prototype.getValue = function(){
console.log(this.val)
}
function Child(value){
Parent.call(this, name)
}
// Child.prototype = new Parent() 組合繼承
// 缺點就是在繼承父類函數的時候調用了父類構造函數,致使子類的原型上多了不須要的父類屬性,存在內存上的浪費
Child.prototype = Object.assign(Parent.prototype, {
constructor:{
value: Child,
enumerable: false,
writable: true,
configurable: true
}
})
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
複製代碼
繼承實現的核心就是將父類的原型賦值給了子類,而且將構造函數設置爲子類,這樣既解決了無用的父類屬性問題,還能正確的找到子類的構造函數。
es6 class 繼承
class Parent{
constructor(value){
this.val = value
}
getValue(){
console.log(this.val)
}
}
class Child extends Parent{
constructor(value){
super(value)
this.val = value
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent //true複製代碼
js 原型與原型鏈能夠參考這個: https://juejin.im/post/5c72a1766fb9a049ea3993e6
5、防抖與節流
防抖即延時執行,指觸發事件後在規定時間內回調函數只能執行一次,若是在規定時間內又觸發該事件,則會從新開始算規定時間。
應用場景: 輸入聯想功能,用戶不斷輸入時,用防抖來節約資源。
function callFn(content){
console.log('這是防抖回調函數')
}
// 利用回調函數 保存定時器標識
function debounce(func ,delay = 500){
let timer = null
return function(args){
let that = this
let _args = args
if(timer) clearTimeout(timer)
timer = setTimeout(function(){
func.call(that, _args)
}, delay)
}
}
let currDebounce = debounce(callFn, 500) // 返回延時函數
// 使用
let evtFn= document.querySelector('body')
evtFn.addEventListener('click', function(e){
currDebounce (e.target.value)
})複製代碼
節流
當持續觸發事件時,在規定時間段內只能調用一次,如再規定時間內又觸發該事件,則return
,什麼也不作。
應用場景,頻繁觸發事件,如滾動、resize 等。
// 定時器版
function throttle(func, delay = 500){
let timer = null;
return function(args){
let that = this;
let _args = args;
if(!timer){
timer = setTimeout(function(){
timer = null;
func.apply(that, _args)
}, delay)
}
}
}
// 時間戳版
function throttle(fun, delay = 500){
let previous = 0;
return function(args){
let now = Date.now();
let that = this;
let _args = args;
if(now - previous > delay){ // 若是時間差大於規定時間,則觸發
fun.apply(that, _args)
previous = now
}
}
}複製代碼
垃圾回收主要分爲:標記清除算法(主流都是這個)與引用計數算法。
將cookie設置成HttpOnly是爲了防止XSS攻擊,竊取cookie內容,這樣就增長了cookie的安全性。
把cookie設置爲secure,只保證 cookie 與服務器之間的數據傳輸過程加密複製代碼
6、渲染機制及重繪和迴流
瀏覽器的渲染機制通常分爲如下幾個步驟:
迴流一定會發生重繪,重繪不必定會引起迴流。
瀏覽器優化:
現代瀏覽器大多都是經過隊列機制來批量更新佈局,瀏覽器會把修改操做放在隊列中,至少一個瀏覽器刷新(即16.6ms)纔會清空隊列,但當你獲取佈局信息的時候,隊列中可能有會影響這些屬性或方法返回值的操做,即便沒有,瀏覽器也會強制清空隊列,觸發迴流與重繪來確保返回正確的值。
主要包括如下屬性或方法:
offsetTop
、offsetLeft
、offsetWidth
、offsetHeight
scrollTop
、scrollLeft
、scrollWidth
、scrollHeight
clientTop
、clientLeft
、clientWidth
、clientHeight
width
、height
getComputedStyle()
getBoundingClientRect()
因此,咱們應該避免頻繁的使用上述的屬性,他們都會強制渲染刷新隊列。
減小重繪與迴流:
一、CSS
table
的從新佈局。transform
、opacity
、filters
這些動畫不會引發迴流重繪 。可是對於動畫的其它屬性,好比background-color
這些,仍是會引發迴流重繪的,不過它仍是能夠提高這些動畫的性能。
避免頻繁操做樣式,最好一次性重寫style
屬性,或者將樣式列表定義爲class
並一次性更改class
屬性。
避免頻繁操做DOM,建立一個documentFragment
,在它上面應用全部DOM操做
,最後再把它添加到文檔中。
避免頻繁讀取會引起迴流/重繪的屬性,若是確實須要屢次使用,就用一個變量緩存起來。
<script type="text/javascript">
var pNode,fragment = document.createDocumentFragment();
for(var i=0; i<20; i++){
pNode = document.createElement('p');
pNode.innerHTML = i;
fragment.appendChild(pNode);
}
document.body.appendChild(fragment);
</script>複製代碼
documentFragment
節點不屬於文檔樹,所以當把建立的節點添加到該對象時,並不會致使頁面的迴流。
7、前端安全性XSS 攻擊與CSRF攻擊
Cross-Site Scripting (跨站腳本攻擊)簡稱XSS,是一種代碼注入攻擊。攻擊者經過在目標網站上注入惡意腳本,使之在用戶的瀏覽器上運行,進而實現攻擊。
XSS 常見的注入方法:
javascript:
(僞協議)等可執行代碼。background-image:url("javascript:...");
的代碼(新版本瀏覽器已經能夠防範)。expression(...)
的 CSS 表達式代碼(新版本瀏覽器已經能夠防範)。經常使用防範方法:
對輸入(和url參數)進行過濾,對輸出進行編碼,cookie 設置成 http-only
用戶輸入、url參數、post 請求參數、ajax
function escape(str) {
str = str.replace(/&/g, '&')
str = str.replace(/</g, '<')
str = str.replace(/>/g, '>')
str = str.replace(/"/g, '&quto;') str = str.replace(/'/g, ''') str = str.replace(/`/g, '`') str = str.replace(/\//g, '/') return str }複製代碼
一、驗證碼;強制用戶必須與應用進行交互,才能完成最終請求。此種方式能很好的遏制 csrf,可是用戶體驗比較差。
二、Referer check;請求來源限制,此種方法成本最低,可是並不能保證 100% 有效,由於服務器並非何時都能取到 Referer,並且低版本的瀏覽器存在僞造 Referer 的風險。
8、Object.assign 模擬實現
if( typeof Object.assign2 !== 'function' ){
Object.defineProperty(Object, 'assign2', {
value: function(target){
if(!target){
throw new Error('cannot convert undefined or null to object')
}
var to = Object(target)
for(var index = 1; index < arguments.length;index++){
var nextSource = arguments[index]
if(nextSource){
for( var nextKey in nextSource ){
if(Object.prototype.hasOwnProperty.call(nextSource, nextKey)){
to[nextKey] = nextSource[nextKey]
}
}
}
}
return to;
},
writable: true,
configurable: true
})
}複製代碼
// 測試用例
let a = {
name: "advanced",
age: 18
}
let b = {
name: "muyiy",
book: {
title: "You Don't Know JS",
price: "45"
}
}
let c = Object.assign2(a, b);
console.log(c);
// {
// name: "muyiy",
// age: 18,
// book: {title: "You Don't Know JS", price: "45"}
// }
console.log(a === c);
// true複製代碼
9、vue 記錄
通常來講,vue 組件分紅三類:
一、 由vue-router 產生的每一個頁面,它本質上也是一個組件(.vue),主要承載當前頁面的html 結構,會包含數據獲取、數據整理、數據展現等業務操做,在實際項目開發中,咱們寫的大部分代碼都是這類組件,在協同開發時,每人維護本身的路由頁面,不多有交集。這類相對也是最好寫的,能完成需求就行。
二、 不包含業務,是個獨立、具體的功能基礎組件,好比模態框、日期選擇器。獨立組件的開發難度要高於第一類組件,它側重點是API的設計、兼容性、性能、以及複雜的功能,也會包含很是多的技巧,好比在不依賴vuex 的狀況下,各組件間的通訊。一個具備數據校驗功能的輸入框。
三、 業務組件,在業務中被多個頁面複用,會包含頁面元素,通用性要差一些,(依託於項目,可使用項目中的技術棧,如vuex、axios等)。通用彈層
一個再複雜的組件,都是由三部分組成:prop、event、slot 。 Props 最好用對象的寫法,這樣能夠針對每一個屬性設置類型、默認值或自定義校驗屬性值。
10、JavaScript模塊化方案
在es6以前,js 並無原生的模塊。模塊化方案的三個階段過程:
一、全局變量+命名空間 (window.XX ,以及自執行函數等操做)
二、AMD&commonjs 各種規範帶到前端
AMD模塊相似:
define(function(require){
const bar = require('./bar')
return function(){}
})複製代碼
commonJs 規範,它本不適合瀏覽器環境,但依賴現代打包工具進行轉換以後就能夠在瀏覽器中執行。commonjs 規範格式更加簡潔,(nodejs 模塊正在使用的就是commonjs 規範)
const bar = require('./bar')
module.exports = function(){
// ....
}複製代碼
三、es6模塊
模塊化方案
import bar from './bar'
export default function(){
// ...
}複製代碼
11、webpack 與gulp 有什麼本質區別
gulp 是工具鏈,構建工具,能夠配合各類插件作js 壓縮,css 壓縮,less 壓縮,替代手工實現自動化工做。 一、 構建工具 二、自動化、三、提升效率
webpack 是文件打包工具,把項目的各類js ,css 打包合併成一個或多個文件,主要用於模塊化打包。一、打包工具 二、模塊化識別 三、編譯模塊代碼 四、代碼拆分五、模塊熱更新。
12、經常使用es6 以及es6 規範
到時候移到掘金
https://blog.csdn.net/u010427666/article/details/54944986
十3、seo 相關知識以及如何優化
文檔&文章連接
十4、內部原型繼承原理
需從新整理
https://blog.csdn.net/u010427666/article/details/53244698
十5、你須要知道的css
css 動畫、flex 佈局等
https://juejin.im/post/5c7646e2f265da2d8e70f681
十5、性能優化點
代碼層面、網絡層面、打包依賴等
https://segmentfault.com/a/1190000008273435
十6、瀏覽器緩存機制(強緩存&協商緩存)
是否過時根據header中的Cache-Control和Expires來判斷,(緩存過時後Etag 與last-modify 是由服務器來判斷)
nginx 開啓強緩存
location ~ ^/static/.*(jpg|jpeg|png|gif|ico|js|css|ttf)$ {
root /home/service/www/web;
expires 12h;
add_header Cache-Control "public";
}
複製代碼
nginx 開啓gizp 壓縮(壓縮效率特高)
gzip on; #開啓gzip壓縮輸出
gzip_min_length 1k; #最小壓縮文件大小
gzip_buffers 4 16k; #壓縮緩衝區
# gzip_http_version 1.0; #壓縮版本(默認1.1,前端若是是squid2.5請使用1.0)
gzip_comp_level 3; #壓縮等級
gzip_types text/plain application/javascript application/x-javascript text/css application/xml;
gzip_vary on;
gzip_disable "MSIE [1-7]\.";
複製代碼
十7、數組亂序
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.sort(function () {
return Math.random() - 0.5;
});
複製代碼
洗牌算法:
function shuffle (arr) { var len = arr.length for (var i = 0;i < len - 1;i++) { var idx = Math.floor(Math.random() * (len - i)) var temp = arr[idx] arr[idx] = arr[len - i - 1] arr[len - i - 1] = temp } return arr}複製代碼
十8、BFC(塊級格式化上下文)
產生BFC:
BFC 做用:
一、 清除浮動,即在容器中建立BFC
二、致使外邊距摺疊塌陷
咱們必須記住的是外邊距摺疊(Margin collapsing)只會發生在屬於同一BFC的塊級元素之間。若是它們屬於不一樣的 BFC,它們之間的外邊距則不會摺疊。因此經過建立一個不一樣的 BFC ,就能夠避免外邊距摺疊。
https://segmentfault.com/a/1190000013647777
十9、單線程的JavaScript引擎是怎麼配合瀏覽器內核處理這些定時器和響應瀏覽器事件的呢?
一、單線程,多進程
答案:promise 、console、setTimeout
答案:1,7,6,8,2,4,3,5,9,11,10,12
https://www.cnblogs.com/joyco773/p/6038022.html
http://www.xuanfengge.com/js-realizes-precise-countdown.html
https://segmentfault.com/a/1190000014940904
二10、websocket 實時推送
相關連接: https://juejin.im/post/5c20e5766fb9a049b13e387b
二11、http2.0的新特性有哪些?(選項是多路複用、頭部壓縮、設置優先級、服務端推送、二進制傳輸)
相關連接: https://juejin.im/post/5c8f30606fb9a070ef60996d
http2.0 /http1.0 302 與304 的區別 206
二12、講解一下https 的工做原理(握手過程)
HTTPS在傳輸數據以前須要客戶端(瀏覽器)與服務端(網站)之間進行一次握手,在握手過程當中將確立雙方加密傳輸數據的密碼信息。TLS/SSL協議不只僅是一套加密傳輸的協議,更是一件通過藝術家精心設計的藝術品,TLS/SSL中使用了非對稱加密,對稱加密以及HASH算法。握手過程的簡單描述以下:
[copy連接](github.com/airuikun/We…)
[熱更新原理](zhuanlan.zhihu.com/p/30669007)
vue 3.0 新特性
目前,Vue 的反應系統是使用 Object.defineProperty
的 getter 和 setter。 Vue 3 將使用 ES2015 Proxy 做爲其觀察者機制。 這消除了之前存在的警告,使速度加倍,並節省了一半的內存開銷。
爲了繼續支持 IE11,Vue 3 將發佈一個支持舊觀察者機制和新 Proxy 版本的構建。
二十3、前端代碼日誌收集
思路:
參照:
別人優質彙總:
https://juejin.im/post/5c64d15d6fb9a049d37f9c20
**3-5年內部崗位(平安、樂信、500萬、vivo、oppo)推薦機會,歡迎發簡歷到: zgxie@126.com**