置身世外只爲暗中觀察!!!Hello你們好,我是魔王哪吒!javascript
你須要一些HTML和css的基礎知識,掌握JavaScript和ES6的基本語法,對事物的好奇心。css
typeof運算符:html
考點:JS變量類型前端
代碼:html5
// 判斷全部值的類型
let a; typeof a // 'undefined'
const str = 'abc'; typeof str // 'string'
const n = 10; typeof n // 'number'
const b = true; typeof b // 'boolean'
const s = Symbol('s'); typeof s // 'symbol'
// 可以判斷函數
typeof console.log // 'function'
typeof function(){} // 'function'
// 可以識別引用類型
typeof null // 'object'
typeof ['a','b'] // 'object'
typeof {x:10} // 'object'
複製代碼
考點:強制類型轉換java
字符串拼接的類型轉換node
const a = 10 + 1 // 11
const b = 10 + '10' // '1010'
const c = true + '1' // true1
複製代碼
解決方法:jquery
10 + parseInt('1') // 11
複製代碼
==
運算符的類型轉換linux
100 == '100' // true
0 == '' // true
0 == false // true
false == '' // true
null == undefined // true
複製代碼
類型轉換webpack
0
以外的全部數字,轉換爲布爾型都爲true
。「 」
以外的全部字符,轉換爲布爾型都爲true
。null
和undefined
轉換爲布爾型爲false
。何時使用===
,何時使用==
除了
==
null外,其餘地方用===
const obj = {a:1}
if(obj.b==null){}
// 至關於
//if(obj.b === null || obj.b === undefined){}
複製代碼
考點:頁面加載過程
考點:JS做用域
考點:性能,體驗優化
考點:JS異步
值類型的表示:
// 值類型
let a = 10
let b = a
a= 20
console.log(b); // 10
複製代碼
引用類型的表示:
// 引用類型
let a = { age:12 }
let b = a
b.age = 13
console.log(a.age) // 13
複製代碼
代碼:
// 淺拷貝
const obj1 = {
age: 12,
name: 'web',
address: {
city: 'beijing'
},
}
const obj2 = obj1
obj2.address.city = 'shanghai'
console.log(obj1.address.city)
複製代碼
結果:
shanghai
複製代碼
深拷貝:定義要拷貝的對象
const obj2 = deepClone(obj1)
obj2.address.city = 'shanghai'
console.log(obj1.address.city)
function deepClone(obj = {}){
if(typeof obj !== 'object' || obj == null){
// obj是null,或者不是對象和數組狀況,直接返回
return obj
}
// 初始化返回結果
let result
if(obj instanceof Array){
result = []
}else{
result = {}
}
for (let key in obj) {
// 保證Key不是原型的屬性
if(obj.hasOwnProperty(key)){
// 遞歸調用
result[key] = deepClone(obj[key])
}
}
// 返回結果
return result
}
複製代碼
深拷貝結果
beijing
複製代碼
a instanceof Array
jquery
,考慮插件和擴展性?代碼:
class jQuery {
constructor(selector){
const result = document.querySelectorAll(selector)
const length = result.length
for(let i=0; i<length; i++){
this[i] = result[i]
}
this.length = length
}
get(index){
return this[index]
}
each(fn){
for(let i=0;i<this.length;i++){
const elem = this[i]
fn(elem)
}
}
on(type,fn){
return this.each(elem=>{
elem.addEventListener(type,fn,false)
})
}
}
複製代碼
插件的擴展性
jQuery.prototype.dialog = function(info) {
alert(info)
}
複製代碼
複寫機制:
class myJQuery extends jQuery {
constructor(selector) {
super(selector)
}
// 擴展本身的方法
study(){
}
}
複製代碼
class
的原型本質,如何理解?constructor
代碼:
// 類
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
study() {
console.log('study')
}
}
// 經過類 new 對象,實例
const web = new Person('哪吒', 10)
複製代碼
class其實是函數,可見的語法糖
typeof Student
結果:
"function"
typeof People
結果:
"function"
複製代碼
extends
super
原型關係:
class
都有顯示原型prototype
__proto__
__proto__
指向對應class
的prototype
console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(People.prototype === Student.prototype.__proto__)
複製代碼
[] instanceof Array // true
[] instanceof Object // true
{} instanceof Object // true
複製代碼
this
的不一樣應用場景下,如何取值?bind
函數建立10個a標籤,點擊彈出對應序號
let i, a
for(i=0; i<10; i++) {
a=document.createElement('a')
a.innerHTML = i + '<br>'
a.addEventListener('click', function(e){
e.preventDefault()
alert(i)
})
document.body.appendChild(a)
}
複製代碼
做用域分:
代碼:
let a = 0
function fn1() {
let a1 = 100
function fn2() {
let a2 = 200
function fn3() {
let a3 = 300
return a+a1+a2+a3
}
fn3()
}
fn2()
}
fn1()
複製代碼
塊級做用域
if(true) {
let x=100
}
console.log(x) // 會報錯
複製代碼
若是一個變量在當前做用域沒有定義,但被使用了,向上級做用域去找,一層一層一次尋找,直到找到爲止,若是到了全局做用域都沒有找到,就會報錯xx is not defined
閉包的表現:
作一個簡單的
cache
工具
閉包隱藏數據
function createCache() {
const data={}
// 閉包中的數據,被隱藏,不被外界訪問
return {
set: function(key,val) {
data[key] = val
},
get: function(key){
return data[key]
}
}
}
const c = createCache()
c.set('a', 100)
console.log(c.get('a'))
複製代碼
函數做爲返回值
function create(){
let a = 100
return function(){
console.log(a)
}
}
let fn = create()
let a = 200
fn()
複製代碼
結果:
100
複製代碼
函數做爲參數
function print(fn) {
let a = 200
fn()
}
let a = 100
function fn(){
console.log(a)
}
print(fn)
複製代碼
結果:
100
複製代碼
全部自由變量的查找是在函數定義的地方,向上級做用域查找,不是執行的地方。
call,apply,bind
被調用class
方法中被調用this
取什麼值,是在函數執行的時候肯定的,不是函數定義的時候肯定的。
call
指向,bind
會返回新的函數
代碼:
function fn1(){
console.log(this)
}
fn1() // window
fn1.call({x:10}) // {x:10}
const fn2 = fn1.bind({x:20})
fn2() // {x:20}
複製代碼
代碼:
const Jeskson = {
name: 'web',
sayHi() {
// this是指當前對象
console.log(this)
},
wait(){
setTimeout(function(){
// this === window
console.log(this)
}
}
}
複製代碼
代碼:
const Jeskson = {
name: 'web',
sayHi() {
// this是指當前對象
console.log(this)
},
wait() {
setTimeout(()=>{
// this指當前對象
console.log(this)
})
}
}
複製代碼
代碼:
class People {
constructor(name){
this.name = name
this.age = 20
}
sayHi(){
console.log(this)
}
}
const Jeskson = new People('web')
Jeskson.sayHi() // Jeskson 對象
複製代碼
手寫bind
函數
Function.prototype.bind1 = function(){
// 將參數解析爲數組
const args = Array.prototype.slice.call(arguments)
// 獲取this
const t = args.shift()
const self = this // 當前函數
// 返回一個函數
return function() {
// 執行原函數,並返回結果
return self.apply(t, args)
}
}
複製代碼
代碼:
function fn1(a,b,c) {
console.log('this',this)
console.log(a,b,c)
return 'this is fn1'
}
const fn2 = fn1.bind ({x:100},10,20,30)
const res = fn2()
console.log(res)
複製代碼
Chrome
:
fn1.hasOwnProperty('bind')
//false
fn1.__proto__ == Function.prototype
// true
Function.prototype.apply/call/bind
複製代碼
Promise
加載一張圖片代碼:
// setTimeout筆試題
console.log(1)
setTimeout(function(){
console.log(2)
},1000)
console.log(3)
setTimeout(function(){
console.log(4)
},0)
console.log(5)
複製代碼
callback hell
和Promise
JS是單線程語言,同時只能作一件事 瀏覽器和
nodejs
支持js
啓動進程,如web worker
JS和dom渲染共用同一線程。
異步:
console.log(100)
setTimeout(function(){
console.log(200)
},1000)
console.log(300)
複製代碼
同步
console.log(100)
alert(200)
console.log(300)
複製代碼
異步和同步的區別
js
是單線程語言手寫用Promise
加載一張圖片
function loadImg(src) {
return new Promise(
(resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`圖片加載失敗 ${src}`)
reject(err)
}
img.src = src
}
)
}
const url = ''
loadImg(url).then(img => {
console.log(img.width)
return img
}).then(img => {
console.log(img.height)
}).catch(ex=>console.error(ex))
複製代碼
Promise
解決callback hell
異步,以回調callback
函數形式
第一網絡請求,如ajax
圖片加載,第二定時任務,如setTimeout
。
//ajax
console.log('start')
$.get('./data.json', function(data1){
console.log(data1)
})
console.log('end')
複製代碼
圖片的加載
console.log('start')
let img = document.createElement('img')
img.onload = function() {
console.log('loaded')
}
img.src="/xxx.png"
console.log('end')
複製代碼
代碼應用場景:
// setTimeout
console.log(100)
setTimeout(function(){
console.log(200)
},1000)
console.log(300)
// setInterval
console.log(100)
setInterval(function(){
console.log(200)
},1000)
console.log(300)
複製代碼
Promise
代碼:
function getData(url){
return new Promise((resolve, reject) => {
$.ajax({
url,
success(data) {
resolve(data)
},
error(err) {
reject(err)
}
})
}
}
複製代碼
Promise
const url1 = '/data1.json'
const url2 = '/data2.json'
const url3 = '/data3.json'
getData(url1).then(data1=>{
console.log(data1)
return getData(url2)
}).then(data2 => {
console.log(data2)
return getData(url3)
}).then(data3 => {
console.log(data3)
}).catch(err => console.error(err))
複製代碼
calback hell
,回調地獄
代碼:
// 獲取第一個數據
$.get(url1, (data1) => {
console.log(data1)
// 獲取第二個數據
$.get(url2, (data2) => {
console.log(data2)
// 獲取第三個數據
$.get(url3, (data3) => {
console.log(data3)
// 還可能獲取更多的數據
})
})
})
複製代碼
Dom操做,操做網頁上的Dom元素,瀏覽器上的文本,圖片
Bom操做,操做瀏覽器上的一些事情,瀏覽器的導航,地址等
事件綁定,ajax,存儲
DOM,Document Object Model
DOM
的本質,節點操做,結構操做,DOM
性能
xml
是一種可擴展的標記語言,能夠描述任何結構的數據,html
是一種特定的xml
。
DOM
的本質,它就是一顆樹。
Dom
節點attribute
property
獲取DOM
節點
const div1 = document.getElementById('div1') // 元素
const divList = document.getElementsByTagName('div') // 集合
console.log(divlist.length)
console.log(divList[0])
const containerList = document.getElementsByClassName('.container') // 集合
const pList = document.querySelectorAll('p') // 集合
複製代碼
DOM
節點的property
const pList = document.querySelectorAll('p');
const p = pList[0]
console.log(p.style.width) // 獲取樣式
p.style.width='100px' // 修改樣式
console.log(p.className) // 獲取class
p.className='p1' // 修改class
// 獲取nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)
複製代碼
property
和attribute
property
修改對象屬性,不會體現到html
結構中
attribute
修改html
屬性,會改變html
結構
兩種都有可能引發DOM
從新渲染
DOM
結構操做
新增,插入節點
const div1 = document.getElementById('div1')
// 添加新節點
const p1 = document.createElement('p')
p1.innerHTML = 'this is p1'
div1.appendChild(p1)
const p2 = document.getElementById('p2')
div1.appendChild(p2)
複製代碼
獲取子元素列表和獲取父元素
//獲取子元素列表
const div1 = document.getElementById('div1')
const child = div1.childNodes
//獲取父元素
const div1 = document.getElementById('div1')
const parent = div1.parentNode
複製代碼
刪除節點
const div1 = document.getElementById('div1')
const child = div1.childNodes
div1.removeChild(child[0])
複製代碼
DOM性能
DOM
操做會耗費cpu,避免頻繁,對DOM
查詢作緩存
DOM
查詢作緩存
// 不緩存DOM查詢結果
for(let=0; i<document.getElementsByTagName('p').length;i++) {
// 每次循環,都會計算length,頻繁進行dom查詢
}
// 緩存dom查詢結果
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i = 0; i<length; i++){
// 緩存length,只進行一次dom查詢
}
複製代碼
講頻繁的操做修改成一次性操做
const listNode = document.getElementById('list')
// 建立一個文檔片斷,此時沒有插入到dom樹中
const frag = document.createDocumentFragment();
// 執行插入
for(let x=0; x<10; x++) {
const li = document.createElement("li")
li.innerHTML="List item"+x
frag.appendChild(li)
}
// 都完成後,再插入到dom樹中
listNode.appendChild(frag)
複製代碼
問題:
dom
是哪一種數據結構dom
操做的經常使用api
attr
和property
的區別dom
節點,考慮性能問題property
和attribute
的區別
property
修改對象屬性,不會體現到html
結構中attribute
修改html
屬性,會改變html
結構二者都有可能引發dom
從新渲染
dom
本質dom
節點操做dom
結構操做dom
性能BOM
操做browser object model
問題:如何識別瀏覽器的類型
問題:分析拆解url
各個部分
代碼:
//navigator
const ua = navigator.userAgent
const isChrome = ua.indexOf('Chrome`)
console.log(isChrome)
複製代碼
代碼:
//screen
console.log(screen.width)
console.log(screen.height)
複製代碼
ajax
代碼:
//get請求
const xhr = new XMLHttpRequest()
xhr.open('GET','/api', true)
xhr.onreadystatechange = function() {
// 這裏的函數異步執行
if (xhr.readyState === 4){
if(xhr.state === 200) {
alert(xhr.responseText);
}
}
}
xhr.send(null)
複製代碼
xhr.readyState
send()
方法send()
方法,正在發送請求send()
方法執行完成,已經接收到所有響應內容xhr.status
同源策略-跨域
ajax
請求時,瀏覽器要求當前網頁和server
必須同源
同源就是:協議,域名,端口,一致
代碼
function ajax(url) {
const p = new Promise((resolve, reject)=>{
const xhr = new XMLHttpRequest()
xhr.open('GET',url,true)
xhr.onreadystatechange=function(){
if(xhr.readyState === 4){
if(xhr.status===2000) {
resolve(
JSON.parse(xhr.responseText)
)
}else if(xhr.status === 404) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
}
}
複製代碼
代碼:
const btn = document.getElementById('btn1')
btn.addEventListener('click',event=>{
console.log('clicked')
})
複製代碼
代碼:
//通用的綁定函數
function bindEvent(elem, type, fn)
elem.addEventListener(type,fn)
}
const a = document.getElementById('web')
bindEvent(a, 'click', e=>{
e.preventDefault()
alert('clicked')
})
複製代碼
代碼:
<body>
<div id="div1">
<p id="p1">web</p>
<p id="p2">it</p>
<p id="p3">it</p>
<p id="p4">it</p>
</div>
<div id="div2">
<P id="p5">it</p>
<p id="p6">it</p>
</div>
</body>
const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', e=>{
e.stopPropagation() // 阻止冒泡
alert('web')
})
bindEvent(body, 'click', e=>{
alert('it')
})
複製代碼
代碼:
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
</div>
<button>點擊
</button>
const div1 = document.getElementById('div1')
div1.addEventListener('click', e=>{
const target = e.target
if(e.nodeName === 'A') {
alert(target.innerHTML)
}
})
複製代碼
事件代理,能夠減小瀏覽器內存佔用
通用的事件綁定函數
const btn1 = document.geteElementById('btn1')
bindEvent(btn1,'click',event=>{
// console.log(event.target) // 獲取觸發的元素
event.preventDefault() // 阻止默認行爲
alert('clicked')
})
const div2 = document.getElementById('div2')
bindEvent(div2,'click',event=>{
event.preventDefault()
const target = event.target
if(target.nodeName === 'A') {
alert(target.innerHTML)
}
})
複製代碼
代碼:
function bindEvent(elem, type, selector, fn) {
if(fn==null) {
fn = selector
selector = null
}
elem.addEventListener(type, e=>{
let target
if(selector) {
// 須要代理
target = e.target
if(target.matches(selector)){
fn.call(target, e)
}
} else {
// 不須要代理
fn(e)
}
})
}
複製代碼
cookie
,localStorage
,sessionStorage
區別
localStorage
數據會永遠存儲,除非代碼回手動刪除sessionStorage
數據只存在於當前會話,瀏覽器關閉則清空通常用localStorage
會更多一些
http
請求時須要發送到服務器端,增長請求數據量html5
專門爲存儲而設計的,最大可爲5Mapi
簡單易用setItem
,getItem
不會隨着http
請求被髮送出去
代碼:
localStorage.setItem('a',100)
localStorage.getItem('a')
複製代碼
代碼:
sessionStorage.setItem('a',100)
sessionStorage.getItem('a')
複製代碼
代碼:經常使用git命令
git add .
git checkout xxx
git commit -m 'xxx'
git push origin master
git pull origin master
git branch
git checkout -b xxx / git checkout xx
git merge xxx
複製代碼
chrome調試工具
Elements
Network
Console
Application
debugger
移動端h5頁,查看網絡請求,須要用工具抓包
windows
通常用fiddler
代碼:
const path = require('path')
module.exports = {
mode: 'development',
entry: path.join(__dirname, 'src', 'index.js'),
output: {
filename: 'bundle.js',
path: path.join(__dirname,'dist')
}
}
複製代碼
線上機器通常都是linux
代碼:
ssh work
ls
rm -rf abc
cd dist
mv index.html index1.html
rm a1.js
touch d.js
rm -rf d.js
複製代碼
server
端有nodejs
url
到渲染出頁面的整個過程資源的形式:html
代碼,媒體文件,如圖片,視頻等,javascript
,css
。
加載過程:dns
解析,域名,ip
地址。瀏覽器根據ip
地址向服務器發起http
請求。
服務器處理http
請求,並返回給瀏覽器。
渲染過程,根據html
代碼生成dom tree
,根據css
代碼生成cssom
。講dom tree
和cssom
整合行程render tree
。
根據render tree
渲染頁面,遇到script
暫停渲染,優先加載並執行js
代碼,完成再繼續。
window.onLoad
和DOMContentLoaded
代碼:
window.addEventListener('load',function(){
// 頁面的所有資源加載完纔會執行,包括圖片,視頻等
})
document.addEventListener('DOMContentLoad',function(){
// dom渲染完既可執行,此時圖片,視頻還可能沒有加載完
})
複製代碼
window.onload
資源所有加載完才能執行,包括圖片DOMContentLoaded DOM
渲染完成便可,圖片可能還沒下載手寫防抖,節流
原則:
讓加載更快,渲染更快,減小資源體積。減小訪問次數,合併代碼,ssr
服務器端渲染,緩存。
對dom
查詢進行緩存,頻繁dom
操做,合併到一塊兒插入dom
結構,節流throttle
防抖debounce
。
ssr
服務器端渲染,講網頁和數據一塊兒加載,一塊兒渲染
非ssr,先加載網頁,再加載數據,再渲染數據
代碼:
<img id="img1" src="preview.png" data-realsrc="abc.png"/>
<script type="text/javascript">
var img1 = document.getElementById('img1')
img1.src = img1.getAttribute('data-realsrc')
</script>
複製代碼
防抖,用戶輸入結束或暫停時,纔會觸發change事件。
代碼:
const input1 = document.getElementById('input1')
input1.addEventListener('keyup', function(){
console.log(input1.value)
}}
複製代碼
代碼:
const input1 = document.getElementById('input1')
let timer = null
input1.addEventListener('keyup', function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
// 模擬觸發change事件
console.log(input1.value)
// 清空定時器
timer = null
},500)
})
複製代碼
debounce防抖代碼:
function debounce(fn, delay = 500) {
// timer 是閉包中的
let timer = null
return function() {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(()=>{
fn.apply(this, arguments)
timer = null
},delay)
}
}
input1.addEventListener('keyup', debounce(()=>{
console.log(input1.value)
}),600)
複製代碼
節流throttle
拖拽一個元素時,要隨時拿到該元素被拖拽的位置
代碼:
const div1 = document.getElementById('div1')
let timer = null
div1.addEventListener('drag',function(e){
if(timer){
return
}
timer = setTimeout(()=>{
console.log(e.offsetX, e.offsetY)
timer = null
},100)
})
複製代碼
節流代碼:
function throttle(fn, delay = 100) {
let timer = null
return function() {
if(timer) {
return
}
timer = setTimeout(()=>{
fn.applay(this,arguments)
timer = null
},delay)
}
}
div1.addEventListener('drag',throttle(function(e){
console.log(e.offsetX,e.offsetY)
},200))
複製代碼
前端web常見的攻擊方式有哪些?
xss跨站請求攻擊
xsrf跨站請求僞造
var是es5的語法,let const 是es6語法,var有變量提高
var和Let是變量,const是常量,不可修改
let const有塊級做用域,var沒有
object和function
強制類型轉換和隱式類型轉換
強制:parseInt,parseFloat,toString等
lodash.isEqual
//實現以下效果
const obj1 = {a:10, b:{x:100,y:200}}
const obj2 = {a:10, b:{x:100,y:200}}
isEqual(objq,obj2) === true
複製代碼
判斷是不是對象或數組
代碼:
function isObject(obj){
return typeof ojb === 'object' && obj !== null
}
// 全相等
function isEqual(obj1,obj2){
if(!isObject(obj1) || !isObject(obj2)) {
// 值類型
return obj1===obj2
}
if(obj1===obj2){
return true
}
// 兩個都是對象或數組,並且不相等
const obj1key = Object.keys(obj1)
const obj2key = Object.keys(obj2)
if(obj1key.length !== obj2key.length){
return false
}
for(let key in obj1){
const res = isEqual(obj1[key],obj2[key])
if(!res){
return false
}
}
return true
}
複製代碼
split()和join()的區別
'1-2-3'.split('-') // [1,2,3]
[1,2,3].join('-') // '1-2-3'
複製代碼
數組的pop,push,unshift,shift
功能分別是什麼,返回值是什麼,有什麼影響。
pop返回刪除的最後一個值
push返回追加後元素的長度
unshift插入到最前面,返回長度length
shift刪除最前面的,返回刪除的值
代碼:
fn.call(this, p1,p2,p3)
fn.apply(this, argument)
複製代碼
代碼:
const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', e=>{
e.stopProgation();
alert()
})
bindEvent(body, 'click', e=>{
alert()
})
複製代碼
自由變量的查找,要在函數定義的地方,不是執行的地方
閉包不要亂用,變量會常駐內容,不會釋放
閉包:
function create() {
let a=100
return function(){
console.log(a)
}
}
let fn = create()
let a=200
fn() // 100
複製代碼
event.stopPropagation()
event.preventDefault()
代碼:
// 新建節點
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
// 插入節點
div1.appendChild(newP)
// 移動節點
const p1 = document.getElementById('p1')
div2.appendChild(p1)
//獲取父元素
console.log(p1.parentNode)
複製代碼
代碼:
const list = document.getElementById('list')
const frag = document.createDocumentFragment()
for(let i=0; i<20; i++){
const li = document.createElement('li')
li.innerHTML = 'list'
frag.appendChild(li)
}
list.appendChild(frag)
複製代碼
jsonp的原理,爲何它不是真正的ajax
瀏覽器的同源策略和跨域
load:
頁面的區別資源加載完纔會執行
ready:
dom渲染完既可執行,圖片,視頻等尚未加載完
函數聲明
function fn(){...}
函數表達式:
const fn = function(){...}
函數聲明會預加載,而函數表達式不會
{}
等同new Object()
,原型Object.prototype代碼:
let i
for (i = 1; i <= 3; i++) {
setTimeout(function(){
console.log(i)
},0)
}
複製代碼
代碼:
let a = 100
function test() {
alert(a)
a = 10
alert(a)
}
test()
alert(a)
複製代碼
手寫字符串trim方法,保證瀏覽器兼容性
用Js實現繼承
代碼:
try {
// todo
}catch(error) {
console.error(error)
}finally{
}
複製代碼
json是一種數據格式,本質是一段字符串,json格式和js對象結構一致。
window.JSON
是一個全局對象,JSON。stringify
,JSON.parse
獲取當前頁面url參數
傳統方式,查找location.search
新api,URLSearchParams
代碼:
// 1
function queryToObj(){
const res={}
const search = location.search.substr(1)
search.split('&').forEach(res => {
const arr = res.split('=')
const key = arr[0]
const key = arr[1]
res[key] = val
})
}
複製代碼
使用URLSearchParams
function queryToObj() {
const res = {}
const pList = new URLSearchParams(location.search)
pList.forEach((val,key) => {
res[key] = val
})
return res
}
複製代碼
手寫數組flatern
代碼:
function flat(arr) {
const isDeep = arr.some(item=> item instanceof Array)
if(!isDeep) {
return arr
}
const res = Array.prototype.concat.apply([],arr)
return flat(res)
}
複製代碼
數組去重
代碼:
function unique(arr) {
const res=[]
arr.forEach(item => {
if(res.indexOf(item) < 0) {
res.push(item)
}
})
return res
}
複製代碼
使用Set
function unique(arr) {
const set = new Set(arr)
return [...set]
}
複製代碼
RAF requestAnimateFrame
代碼:
function deepClone(obj = {}) {
if(type of obj !== 'object' || obj == null){
return obj
}
let result
if(obj instanceof Array) {
result = []
}else{
result = {}
}
for(let key in obj){
if(obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key])
}
}
return result
}
複製代碼
Object.assign
不是深拷貝!
原則:多使用內存,緩存,減小計算,網絡請求
加載頁面,頁面渲染,頁面操做等多多思考問題。
歡迎加我微信Jeskson(xiaoda0423
),拉你進技術羣(掘金-前端高校),長期交流學習。