CSS盒模型
盒模型包含了content秋度,padding,border剖笙,margin
1.一個是標(biāo)準(zhǔn)模型:盒模型的寬高只是content的寬高
2.一個是IE模型(又叫怪異模型):盒模型的寬高是內(nèi)容(content)+填充(padding)+邊框(border)的總寬高阅酪。
如何統(tǒng)一模型:將模型的寬高都統(tǒng)一為內(nèi)容(content)+填充(padding)+邊框(border)的總寬高筐付。
div{
box-sizing: border-box;
}
DOM事件流
JS中事件分為三個階段: 事件捕獲 --> 事件目標(biāo) --> 事件冒泡
栗子:給目標(biāo)元素(text)綁定click事件,實際的(text)元素在捕獲階段不會接收到事件样眠,意味著在捕獲階段贬养,事件從document到<body>再到<div>后就停止了。下一個階段是“處于目標(biāo)階段”识虚,于是事件在(text)上發(fā)生肢扯,并在事件處理中被看成是冒泡階段的一部分。最后担锤,冒泡階段發(fā)生蔚晨,事件又傳播回文檔。
DOM層級越小妻献,事件傳播的消耗越小蛛株,在一定情況下也可以視為一種優(yōu)化性能的手段
比較常見的冒泡現(xiàn)象:
<a id='test'>sina</a></body>
<script>
document.onclick = function() {
alert('doc click');
return false;
}
var a = document.getElementById('test');
a.onclick = function() {
alert('a click');
}
</script>
正常執(zhí)行順序
1.從document慢慢找下去,判斷當(dāng)前元素是否是時間的觸發(fā)源
2.找到事件源育拨,執(zhí)行a元素上的onclick事件
2.事件進入冒泡階段谨履,包含a元素的document的onclick事件
3.事件完成,進入瀏覽器默認(rèn)行為熬丧,即跳轉(zhuǎn)笋粟。
PS:如果當(dāng)使用return false會打斷后續(xù)行為,所以這里不會跳轉(zhuǎn)析蝴。
使用event.preventDefault
取消瀏覽器默認(rèn)行為
使用event.stopPropagation
會取消冒泡害捕,但不取消瀏覽器默認(rèn)行為。
CSS層疊規(guī)則(視圖上的顯示層級)
元素居中
水平居中
行內(nèi)元素:text-align: center
塊級元素:margin: 0 auto
absolute + transform
flex + justify-content: center
垂直居中
line-height: height
absolute + transform
flex + align-items: center
table
水平垂直居中
absolute + transform
flex + justify-content + align-items
CSS選擇器問題
優(yōu)先級:!important > 行內(nèi)樣式 > #id > .class > tag > * > 繼承 > 默認(rèn)
css選擇器原理:采用遞歸方式闷畸,從右往左找尝盼,如body #box1 .box2 div span a
,
1.瀏覽器會先找所有的a
標(biāo)簽
2.從這些a
標(biāo)簽中找到父元素是span
的
3.從這些span
中找父元素是div
的
4.從這些div
中找父元素是.box2
的
........
優(yōu)化問題:
1.層級越多需要找的時間越久佑菩,耗時盾沫,盡量直接寫class或者id來找,層級頂多3層殿漠。
2.盡量不要直接寫div span a
赴精,因為頁面上可能有很多a
標(biāo)簽,span
和div
绞幌,會更耗時蕾哟。
清除浮動
只介紹以下兩種我用的,其他不贅述
1.(推薦)給浮動元素的父元素加上clearfix
類
.clearfix{*zoom:1;}
.clearfix:after{display:block; content:"clear"; height:0; clear:both; overflow:hidden; visibility:hidden;}
2.給浮動元素結(jié)尾處添加一個空的div
,并且clear:both;
link 與 @import 的區(qū)別
1.link功能較多,可以定義 RSS谭确,定義 Rel 等作用帘营,而@import只能用于加載 css
2.當(dāng)解析到link時,頁面會同步加載所引的 css琼富,而@import所引用的 css 會等到頁面加載完才被加載仪吧,從體驗來說,link要由于@import
3.@import需要 IE5 以上才能使用
4.link可以使用 js 動態(tài)引入鞠眉,@import不行
javascript數(shù)據(jù)類型
值類型(基本類型):字符串(String)薯鼠、數(shù)字(Number)、布爾(Boolean)械蹋、對空(Null)出皇、未定義(Undefined)、Symbol哗戈。
引用數(shù)據(jù)類型:對象(Object)郊艘、數(shù)組(Array)、函數(shù)(Function)唯咬。
區(qū)別:
1.值類型變量是存放在棧區(qū)的(棧區(qū)指內(nèi)存里的棧內(nèi)存)
2.引用類型顧名思義只是引用纱注,數(shù)據(jù)是存在堆內(nèi)存中,如果內(nèi)存中的值變化胆胰,那么引用它的變量也會變化
看下面栗子
var a = [1,2,3];
var b = a;
a.push(4);
console.log(b); // [1,2,3,4]
關(guān)于變量提升問題
JavaScript 中狞贱,函數(shù)及變量的聲明都將被提升到函數(shù)的最頂部。
函數(shù)提升的優(yōu)先級大于變量提升的優(yōu)先級蜀涨,即函數(shù)提升在變量提升之上
來看這一段代碼
console.log(a,fun); // undefiend undefiend
var a = 1;
function fun(){}
那么瞎嬉,JS執(zhí)行以上代碼時,實際執(zhí)行順序是這樣的
function fun(){}
var a;
console.log(a,fun);
a = 1;
函數(shù)聲明和函數(shù)表達式的區(qū)別
- 函數(shù)聲明
fn() //不會報錯
function fn(){}
// 實際執(zhí)行順序為
function fn(){}
fn()
- 函數(shù)表達式 會將變量和函數(shù)拆分開來執(zhí)行厚柳,存在變量提升問題
fn() //Uncaught TypeError:fn is not a function
var a = function(){}
// 實際執(zhí)行順序為
var a;
a();
a = function(){};
閉包
script標(biāo)簽
1.<script defer>
: 異步加載氧枣,元素解析完成后執(zhí)行
2.<script async>
: 異步加載,與元素渲染并行執(zhí)行
對于大多情況來說别垮,script標(biāo)簽盡量放在html最底部引入進來便监,防止影響html以及css的加載,影響頁面呈現(xiàn)的速度碳想。
對象的深拷貝淺拷貝問題
講一下簡單實現(xiàn)原理
1.淺拷貝:便利對象source
的屬性烧董,然后賦值到新對象target
上,如果source
的某一個子屬性是引用類型
的移袍,那么target
復(fù)制的屬性的內(nèi)存地址與source
的的子屬性指向同一內(nèi)存地址。會出現(xiàn)如下問題:
//淺拷貝
function shallow(target, source) {
for (let i in source) {
target[i] = source[i];
}
return target;
}
var obj1 = {
name: 'obj1',
arr: [1, 2, 3]
},
obj2 = {};
//淺拷貝一次
shallow(obj2, obj1);
obj1.arr.push(4);
console.log(obj2.arr); // [1,2,3,4]
一些簡單的淺拷貝方式:
// Object.assign
let a = {
age: 1
}
let b = Object.assign({}, a)
// ...運算符
let a = {
age: 1
}
let b = {...a}
2.深拷貝:在淺拷貝基礎(chǔ)上老充,遇到引用類型的值需要再次執(zhí)行淺拷貝葡盗,也就是遞歸執(zhí)行淺拷貝
,就不會出現(xiàn)淺拷貝的問題
function deep(target, source) {
for (var i in source) {
// 含有引用類型
if (typeof source[i] === 'object') {
// 這里可能是數(shù)組或者對象
if (source[i].constructor == Array) {
target[i] = [];
} else {
target[i] = {};
}
//需要遞歸執(zhí)行deep拷貝
deep(target[i], source[i]);
} else {
target[i] = source[i];
}
}
}
var obj1 = {
name: 'obj1',
arr: [1, 2, 3]
},
obj2 = {};
//淺拷貝一次
deep(obj2, obj1);
obj1.arr.push(4);
console.log(obj1.arr,obj2.arr); // [1,2,3,4] [1,2,3]
最簡單的實現(xiàn)深拷貝
var obj1 = {
name: 'jsonObj',
arr: [1, 2, 3]
}
//先把對象序列化成一個字符串,再轉(zhuǎn)成JSON對象,就新建了一份內(nèi)存
//IE7不兼容
var obj2 = JSON.parse(JSON.stringify(obj1));
obj1.arr.push(4);
console.log(obj1.arr, obj2.arr); // [1,2,3,4] [1,2,3]
對于更多出現(xiàn)的情況請參考lodash拷貝
new到底干了什么
1.新生成一個對象obj
2.鏈接到原型: obj.__proto__ = 對應(yīng)的構(gòu)造函數(shù).prototype
3.修改this執(zhí)行: apply
4.返回新對象
function p(age){
alert(123123);
this.age = age;
this.getAge = function(){
alert(this.age);
}
}
// 實現(xiàn)一個new
function create() {
// 創(chuàng)建一個空的對象
let obj = new Object();
// 獲得構(gòu)造函數(shù)
let Con = [].shift.call(arguments);
// 鏈接到原型
obj.__proto__ = Con.prototype;
// 執(zhí)行構(gòu)造函數(shù),修改this指向
let result = Con.apply(obj, arguments)
// 確保 new 出來的是個對象
return typeof result === 'object' ? result : obj
}
var aa = create(p);
類型判斷
最簡單的typeof
觅够,但有時并不能準(zhǔn)確的判斷出數(shù)據(jù)的類型typeof [1,2]得到object
胶背,列出我自己常用的一套方法吧:Object.prototype.toString.call(要檢查的數(shù)據(jù))
,根本原理是利用借用object
的prototype.toString
方法
// 以下是11種:
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {
a: 1
} // [object Object]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a() {}; // [object Function]
console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(JSON)); // [object JSON]
//查看參數(shù)的類型
//console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
//封裝一下
function checkType(obj){
return Object.prototype.toString.call(obj);
}
console.log(checkType([1, 2, 3])) // [object Array]
防抖與節(jié)流
我的另一篇文章有簡述這些原理簡單的聊聊節(jié)流和防抖
this指向問題
this
說簡單點就是:誰調(diào)用了函數(shù)喘先,this
就指向誰钳吟,在箭頭函數(shù)中會稍有區(qū)別。
箭頭函數(shù)中的this指向:箭頭函數(shù)不綁定this窘拯, 它會捕獲其所在(即定義的位置)上下文的this值红且, 作為自己的this值,看下面的栗子:
function Person() {
this.age = 111;
setTimeout(() => {
// 回調(diào)里面的 `this` 變量就指向了期望的那個對象了
console.log(this)
}, 1000);
}
Person() // Window 因為Person方法掛載到Window上了,上下文中的this也指向Window
var p = new Person() //Person {age: 111} 構(gòu)造函數(shù)新生成的對象涤姊,上下文中的this指向p
修改this指向 call和apply和bind的區(qū)別
原方法fn(1,2)
暇番,修改后fn
中的this指向了target
,修改this指向
的方法如下思喊,三種方式作用相同壁酬,只是調(diào)用方式不同:
call: fn.call(target, 1, 2)
apply: fn.apply(target, [1, 2])
bind: fn.bind(target)(1,2)
function a(){
console.log(this.myName)
}
a() //undefined
var b = {
myName:"我是b"
}
a.call(b) // 我是b
a.apply(b) // 我是b
a.bind(b)() // 我是b
函數(shù)柯里化
在一個函數(shù)中,首先填充幾個參數(shù)恨课,然后再返回一個新的函數(shù)的技術(shù)舆乔,稱為函數(shù)的柯里化。通臣凉可用于在不侵入函數(shù)的前提下希俩,為函數(shù)預(yù)置通用參數(shù),供多次重復(fù)調(diào)用诬留。
const curry = function add(x) {
return function (y) {
return x - y
}
}
// 通用參數(shù)1
const reduce = curry(1)
add1(2) === 1
add1(20) === 19
跨域問題
JavaScript 執(zhí)行機制
從輸入 url 到展示的過程
- DNS 解析
- TCP 三次握手
- 發(fā)送請求盒刚,分析 url,設(shè)置請求報文(頭因块,主體),協(xié)商緩存問題
- 服務(wù)器返回請求的文件 (html)
- 瀏覽器渲染
1.HTML parser --> DOM Tree涡上。html解析,dom數(shù)構(gòu)建
2.CSS parser --> Style Tree拒名。解析 css 代碼吩愧,生成樣式樹
3.attachment --> Render Tree。結(jié)合 dom樹 與 style樹增显,生成渲染樹
4.layout: 布局
5.GPU painting: 像素繪制頁面
重繪和重排(回流)
重繪(repaint): 當(dāng)元素樣式的改變不影響布局時雁佳,瀏覽器將使用重繪對元素進行更新,此時由于只需要UI層面的重新像素繪制,因此 損耗較少
-
重排(回流)(reflow): 當(dāng)元素的尺寸糖权、結(jié)構(gòu)或觸發(fā)某些屬性時堵腹,瀏覽器會重新渲染頁面,稱為重排(回流)星澳。此時疚顷,瀏覽器需要重新經(jīng)過計算,計算后還需要重新頁面布局禁偎,因此是較重的操作腿堤。會觸發(fā)重排(回流)的操作:
1.頁面初次渲染
2.瀏覽器窗口大小改變
3.元素尺寸、位置届垫、內(nèi)容發(fā)生改變
4.元素字體大小變化
5.添加或者刪除可見的 dom 元素
6.激活 CSS 偽類(例如::hover)
7.查詢某些屬性或者使用某些方法clientWidth释液、clientHeight、clientTop装处、clientLeft offsetWidth误债、offsetHeight、offsetTop妄迁、offsetLeft scrollWidth寝蹈、scrollHeight、scrollTop登淘、scrollLeft getComputedStyle() getBoundingClientRect() scrollTo()
重繪的開銷較小箫老,重排(回流)的開銷較高。
一些優(yōu)化的操作:
- 避免使用table布局黔州,可能很小的一個小改動會造成整個 table 的重新布局
- 將CSS動畫效果(transform)應(yīng)用到position屬性為absolute或fixed的元素上(定位元素修改不影響頁面結(jié)構(gòu))
- JS中避免頻繁操作樣式,可匯總后統(tǒng)一 一次修改
- JS中盡量使用class進行樣式修改牲蜀,盡可能在DOM樹的最末端改變class绅这,回流是不可避免的,但可以減少其影響度苔。盡可能在DOM樹的最末端改變class寇窑,可以限制了回流的范圍甩骏,使其影響盡可能少的節(jié)點。
- 減少dom的增刪次數(shù),可使用拼接好的字符串
append
或者documentFragment
一次性插入 - 使用 visibility 替換 display: none 缎浇,因為前者只會引起重繪赴肚,后者會引發(fā)回流
- 避免設(shè)置多層內(nèi)聯(lián)樣式,CSS 選擇符從右往左匹配查找誉券,避免節(jié)點層級過多踊跟。
前端存儲
-
cookie
: 通常用于存儲用戶身份商玫,登錄狀態(tài)等,http 中自動攜帶袭异, 體積上限為 4K御铃, 可自行設(shè)置過期時間 -
localStorage / sessionStorage
: 長久儲存/窗口關(guān)閉刪除上真, 體積限制為 4~5M indexDB
js內(nèi)存問題
內(nèi)存泄漏:不再用到的內(nèi)存谷羞,沒有及時釋放湃缎,就叫做內(nèi)存泄漏(memory leak)嗓违。
V8垃圾回收機制:將內(nèi)存中不再使用的數(shù)據(jù)進行清理蹂季,釋放出內(nèi)存空間偿洁。
常見內(nèi)存泄漏的原因以及解決辦法(讓垃圾回收機制認(rèn)為其不會再被使用):
1.全局變量涕滋,不會被回收宾肺。解決:用完需要手動賦值為null
2.定時器:沒有被清理锨用。解決:用完需要clear
2.閉包常駐內(nèi)存引起
3.dom元素被清空或刪除時增拥,其綁定的事件未清除 被清空或刪除的元素棵帽。解決:手動解綁事件removeEventListener
常見狀態(tài)碼
- 1xx: 接受渣玲,繼續(xù)處理
- 200: 成功逾苫,并返回數(shù)據(jù)
- 201: 已創(chuàng)建請求
- 202: 服務(wù)端已接受請求
- 203: 成為铅搓,未授權(quán)
- 204: 成功星掰,無內(nèi)容
- 205: 成功氢烘,重置內(nèi)容
- 206: 成功播玖,部分內(nèi)容
- 301: 永久移動蜀踏,重定向
- 302: 臨時移動果覆,可使用原有URI
- 304: 資源未修改局待,可使用緩存
- 305: 需代理訪問
- 400: 請求語法錯誤
- 401: 要求身份認(rèn)證
- 403: 拒絕請求
- 404: 資源不存在
- 500: 服務(wù)器錯誤
get / post區(qū)別和相同
GET在瀏覽器回退時是無害的燎猛,而POST會再次提交請求重绷。
GET產(chǎn)生的URL地址可以存書簽昭卓,而POST不可以候醒。
GET請求會被瀏覽器主動cache倒淫,而POST不會敌土,除非手動設(shè)置。
GET請求只能進行url編碼矩欠,而POST支持多種編碼方式悠夯。
GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里该默,而POST中的參數(shù)不會被保留栓袖。因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息赠叼,POST比GET安全
GET請求在URL中傳送的參數(shù)是有長度限制的嘴办,而POST么有涧郊。GET參數(shù)通過URL傳遞,POST放在Request body中
對參數(shù)的數(shù)據(jù)類型批旺,GET只接受ASCII字符诵姜,而POST沒有限制棚唆。
GET產(chǎn)生一個TCP數(shù)據(jù)包翎卓;POST產(chǎn)生兩個TCP數(shù)據(jù)包失暴。
對于GET方式的請求,瀏覽器會把http header和data一并發(fā)送出去微饥,服務(wù)器響應(yīng)200(返回數(shù)據(jù))逗扒;
而對于POST,瀏覽器先發(fā)送header欠橘,服務(wù)器響應(yīng)100 continue矩肩,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回數(shù)據(jù))肃续。也就是說黍檩,GET只需要跑一趟就把貨送到了叉袍,而POST得跑兩趟棵里,第一趟,先去和服務(wù)器打個招呼“嗨,我等下要送一批貨來款侵,你們打開門迎接我”妹笆,然后再回頭把貨送過去。在網(wǎng)速快時,多跑一趟消耗的時間可以忽略不計的徙菠。并不是所有瀏覽器都會在POST中發(fā)送兩次包,F(xiàn)irefox就只發(fā)送一次蝴乔。GET/POST最底層都是TCP鏈接,底層相同
HTTP定義了好幾個不同的請求方式名:GET, POST, PUT, DELETE等等都有其獨特的意義猴仑。但HTTP只是個行為準(zhǔn)則,而TCP才是GET和POST怎么實現(xiàn)的基本朱浴。就像校規(guī)規(guī)定了不能抽煙梁沧,但我依然可以偷偷的抽酥泞。要給GET加上request body悯姊,給POST帶上url參數(shù),技術(shù)上是完全行的通的垃僚。
前端安全問題
-
XSS攻擊: 注入惡意代碼
- cookie 設(shè)置 httpOnly
- 轉(zhuǎn)義頁面上的輸入內(nèi)容和輸出內(nèi)容 如
<>
轉(zhuǎn)義為< >
-
CSRF: 跨站請求偽造碍岔,防護:
- get 不修改數(shù)據(jù)
- 不被第三方網(wǎng)站訪問到用戶的 cookie
- 設(shè)置白名單询吴,不被第三方網(wǎng)站請求 如服務(wù)端CORS設(shè)置請求頭
Access-Control-Allow-Origin: 域名白名單
- 請求校驗,如
token
雙向綁定之Proxy
目前煮甥,Vue 的反應(yīng)系統(tǒng)是使用數(shù)據(jù)劫持 Object.defineProperty
的 getter
和 setter
。 但是,Vue 3 將使用 ES2015 Proxy
作為其觀察者機制。兩者的區(qū)別 深纲。這消除了以前存在的警告囤萤,使速度加倍,并節(jié)省了一半的內(nèi)存開銷。理解Proxy
AMD和CMD的區(qū)別
- AMD 是 RequireJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)出没佑。
- CMD 是 SeaJS 在推廣過程中對模塊定義的規(guī)范化產(chǎn)出啤贩。
關(guān)于vue或者react組件中需要寫key的必要性
vue和react都是采用diff算法來對比新舊虛擬節(jié)點暖庄,從而更新節(jié)點。
<ul>
<li v-for="i in 10" :key="i">{{i}}</li>
</ul>
沒有key:當(dāng)其中一個li
發(fā)生變化時廉沮,會便利所有li
,找出其中變化的項
有key:會通過對應(yīng)的key
值去映射豫尽,不用便利所有節(jié)
JS運算符優(yōu)先級問題篙梢,以及函數(shù)聲明優(yōu)先級問題
function Foo () {
getName = function () { alert(1) }
return this
}
Foo.getName = function () { alert(2) }
Foo.prototype.getName = function () { alert(3) }
var getName = function () { alert(4) }
function getName () { alert(5) }
//輸入的值
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
// 結(jié)果
Foo.getName(); //2
getName(); //4
Foo().getName(); //1
getName();//1
new Foo.getName(); //2
new Foo().getName(); //3
new new Foo().getName(); //3
上題主要測試了JS運算符優(yōu)先級問題,以及函數(shù)聲明優(yōu)先級問題美旧,參考文章:一道被前端忽略的基礎(chǔ)題
var和let和const的區(qū)別
- var存在變量提升問題,可以重復(fù)聲明
- const不能被修改渤滞,不能被重復(fù)聲明
- let以下
// 同一作用域下,已經(jīng)被聲明的變量不能再被聲明
let a = 0;
let a = 1; //Identifier 'a' has already been declared
// 暫時性死區(qū)問題榴嗅,即不存在變量提升問題
b = 111;
let b; // b is not defined
// 經(jīng)典面試題
for ( var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
// 使用let之后
for ( let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
// 相當(dāng)于
{ // 形成塊級作用域
let i = 0
{
let ii = i
setTimeout( function timer() {
console.log( ii );
}, i*1000 );
}
i++
{
let ii = i
}
i++
{
let ii = i
}
...
}
同步和異步的區(qū)別是什么
js單線程語言(不能同時干兩件事)妄呕,異步:定時器,ajax
以下代碼录肯,從上往下執(zhí)行:
1.同步隊列---打印1
2.發(fā)現(xiàn)定時器趴腋,把2加入到異步隊列
3.同步隊列---打印3
4.發(fā)現(xiàn)定時器吊说,把3加入到異步隊列论咏,發(fā)現(xiàn)3等待的時間比2短,3插隊颁井,排在2之前
5.同步隊列---打印5
6.同步任務(wù)全部執(zhí)行完成厅贪,開始執(zhí)行異步隊列
7.按照隊列 ----- 3 ----- 2
console.log(1)
setTimeout(function(){
console.log(2)
},1000)
console.log(3)
setTimeout(function(){
console.log(4)
},0)
console.log(5)
Date的方法
Date.now() //獲取當(dāng)前時間毫秒數(shù)
var dt = new Date()
dt.getTime() //獲取毫秒數(shù)
dt.getFullYear() //年
dt.getMonth() //月(0-11)
dt.getDate() //日(0-31)
dt.getHours() //小時(0-23)
dt.getMinutes() //分鐘(0-59)
dt.getSeconds() //秒(0-59)
獲取2016-06-10格式的日期
function formatDate(dt){
if(!dt){
dt = new Date()
}
var year = dt.getFullYear()
var month = dt.getMonth() + 1
var date = dt.getDate()
if(month < 10){
//強制類型轉(zhuǎn)換
month = '0' + month
}
if(date < 10){
//強制類型轉(zhuǎn)換
date = '0' + date
}
//強制類型轉(zhuǎn)換
return year + '-' + month + '-' + date
}
Array的方法
var arr = [1,2,3,4,5];
// forEach不會對空數(shù)組進行檢測。
arr.forEach( function(item,index){
// 無法break
console.log(index,item);
});
// every不會對空數(shù)組進行檢測雅宾。
// every不會改變原始數(shù)組养涮。
var result = arr.every(function(index,item){
//所有成員都滿足一個條件才為true
if(item<6)
return true
});
// some不會對空數(shù)組進行檢測。
// some不會改變原始數(shù)組。
var result = arr.some(function(index,item){
//一個滿足條件就為true
if(item<5)
return true;
});
console.log(result);
// 返回一個數(shù)組贯吓,原數(shù)組會被改變
var arr2 = arr.sort(function(a,b){
//從小到大排序 return a-b;
//從大到小排序 return b-a;
})
// map不會對空數(shù)組進行檢測懈凹。
// map 不會改變原始數(shù)組。
arr.map(function(item,index){
// 每位數(shù)都X2
return item*2
});
// filter不會對空數(shù)組進行檢測
// filter不會改變原始數(shù)組
var arr2 = arr.filter(function (item,index){
//通過某一個條件過濾數(shù)組悄谐,返回新數(shù)組
return item > 3
})
join: 通過指定連接符生成字符串
push / pop: 末尾推入和彈出介评,改變原數(shù)組, 返回推入/彈出項
unshift / shift: 頭部推入和彈出爬舰,改變原數(shù)組们陆,返回操作項
sort(fn) / reverse: 排序與反轉(zhuǎn),改變原數(shù)組
concat: 連接數(shù)組情屹,不影響原數(shù)組坪仇, 淺拷貝
slice(start, end): 返回截斷后的新數(shù)組,不改變原數(shù)組
splice(start, number, value...): 返回刪除元素組成的數(shù)組垃你,value 為插入項椅文,改變原數(shù)組
indexOf / lastIndexOf(value, fromIndex): 查找數(shù)組項,返回對應(yīng)的下標(biāo)
事件代理
需求:點擊li時惜颇,得到對應(yīng)的數(shù)字
為每個li綁定事件(綁定多次事件)是沒必要的雾袱,使用代理:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
document.querySelector('ul').onclick = function(event){
// 通過event.target得到對應(yīng)的li
alert(event.target.innerTxt);
}
</script>
關(guān)于0.1 + 0.2 != 0.3的解決辦法
parseFloat((0.1 + 0.2).toFixed(10))
關(guān)于['1','2','3'].map(parseInt)
console.log(['1','2','3'].map(parseInt)); // 1 NaN NaN
基于map方法,默認(rèn)回傳數(shù)組的(item,index,Arrar)官还。相當(dāng)于執(zhí)行了以下函數(shù):
parseInt('1',0,['1','2','3'])
parseInt('2',1,['1','2','3'])
parseInt('3',2,['1','2','3'])
來看parsInt:
第一次芹橡,當(dāng)我我們第一次調(diào)用的時候 是這樣的:parseInt('1',0) 這個是沒問題的 轉(zhuǎn)十進制的 看我紅框的圖片返回 1
第二次,調(diào)用第二個index參數(shù)是1,也是說1作為數(shù)值的基礎(chǔ)望伦。規(guī)范里說的很清楚了林说,如果基礎(chǔ)是非0或者小于2,函數(shù)都不會查詢字符串直接返回NaN屯伞。
- 第三次腿箩,2作為基數(shù)。這就意味著字符串將被解析成字節(jié)數(shù)劣摇,也就是僅僅包含數(shù)值0和1珠移。parseInt的規(guī)范第十一步指出,它僅嘗試分析第一個字符的左側(cè)末融,這個字符還不是要求基數(shù)的有效數(shù)字钧惧。這個字符串的第一個字符是“3”,它并不是基礎(chǔ)基數(shù)2的一個有效數(shù)字勾习。所以這個子字符串將被解析為空浓瞪。函數(shù)將返回為NaN。
cookies與session有什么區(qū)別
由于http請求是無狀態(tài)的巧婶,需要cookie來做身份驗證
1.cookies由服務(wù)端創(chuàng)建乾颁,發(fā)送給瀏覽器端涂乌,當(dāng)用戶發(fā)出請求后,帶上cookie發(fā)送給服務(wù)端做驗證英岭。
2.來回傳遞過程中湾盒,占用帶寬,消耗網(wǎng)絡(luò)資源,并且容易被中間人獲取或瀏覽器端用戶篡改十分不安全
3.cookies大小只有4k
1.session主要存在于服務(wù)端诅妹,不會被發(fā)送到瀏覽器所以很安全
2.如果沒有設(shè)置過期時間历涝,在會話結(jié)束后session會自動消失
3.session主要用于服務(wù)端保存請求信息的機制