Js流水賬知識(shí)點(diǎn)

在學(xué)js的過(guò)程中,記錄一些零碎的小知識(shí),以便以后翻看。持續(xù)更新……
學(xué)習(xí)資料:JavaScript教程 以及 《你不知道的JavaScript》系列叢書

  1. localstorage:保存用戶更改,可用于覆蓋當(dāng)前頁(yè)面已修改的hash,避免瀏覽器刷新后更改信息丟失。(以后補(bǔ)充和cookie的區(qū)別)
  2. example.com/favicon.ico,favicon.ico用于獲取當(dāng)前網(wǎng)站的title圖標(biāo)
  3. 變量提升:JavaScript 引擎的工作方式是,先解析代碼,獲取所有被聲明的變量,然后再一行一行地運(yùn)行。這造成的結(jié)果,就是所有的變量的聲明語(yǔ)句,都會(huì)被提升到代碼的頭部,這就叫做變量提升(hoisting)。
console.log(a)      // undefined
var a = 1
  1. JavaScript 使用大括號(hào),將多個(gè)相關(guān)的語(yǔ)句組合在一起,稱為“區(qū)塊”(block),對(duì)于var命令來(lái)說(shuō),JavaScript 的區(qū)塊不構(gòu)成單獨(dú)的作用域(scope)。
{
  var a = 1;
}

a // 1

在區(qū)塊外部,變量a依然有效,ES6為了改變這種現(xiàn)狀,引入了let:

{
  let a = 1;
}

a // undefined
  1. 關(guān)于是否添加分號(hào):尤雨溪的回答
    總結(jié)下來(lái)就是一句話:一行開(kāi)頭是括號(hào)或者方括號(hào)的時(shí)候加上分號(hào)就可以了,其他時(shí)候全部不需要。
  2. 如果存在多重循環(huán),不帶參數(shù)的break語(yǔ)句和continue語(yǔ)句都只針對(duì)最內(nèi)層循環(huán)。
  3. 語(yǔ)句的前面有標(biāo)簽(label),用于跳轉(zhuǎn)到程序的任意位置,通常與break語(yǔ)句和continue語(yǔ)句配合使用,跳出特定的循環(huán)或者代碼塊。
  4. 七大數(shù)據(jù)類型:
  • number
  • string
  • boolean
  • undefined
  • null
  • symbol
  • object
    object細(xì)分為:object(狹義),array,function
  1. 三種類型準(zhǔn)換的方法:typeof,instanceof,Object.prototype.toString
var obj = { }, arr = [ ] 
typeof obj        // object
typeof arr        // object
arr instanceof Array        // true
obj instanceof Array        // false
typeof NaN        // number
typeof Ifinity        // number
typeof null        // object
function f(){}
typeof f        // function
  1. 隱式轉(zhuǎn)換

數(shù)組或?qū)ο髸?huì)先調(diào)用valueOf()獲取原始值,然后調(diào)用toString()轉(zhuǎn)化成字符串,然后調(diào)用Number()轉(zhuǎn)成數(shù)字,Boolean類型也是調(diào)用Number()轉(zhuǎn)化成數(shù)字。
參考:js面試題大坑——隱式類型轉(zhuǎn)換

Number(null) // 0
5 + null // 5
Number(undefined) // NaN
5 + undefined // NaN

神代碼:

(!(~+[])+{})[--[~+""][+[]]*[~+[]]+~~!+[]]+({}+[])[[~!+[]*~+[]]] = sb
  1. 如果 JavaScript 預(yù)期某個(gè)位置應(yīng)該是布爾值,會(huì)將該位置上現(xiàn)有的值自動(dòng)轉(zhuǎn)為布爾值。轉(zhuǎn)換規(guī)則是除了下面六個(gè)值被轉(zhuǎn)為false,其他值都視為true。
  • undefined
  • null
  • false
  • 0
  • NaN
  • " " 或 ' '
  1. event.target 和 event.currentTaget的區(qū)別,以后整理為博客,先參考這篇

  2. typeof valueOf instanceof的用法,區(qū)別,輸出結(jié)果博客總結(jié)

  3. js現(xiàn)階段主要掌握用法:改變?cè)氐腸lass,比如添加和取消"active",具體的樣式交給CSS

  4. 盡量不要用瀏覽器提供的API,容易出bug

  5. nextSibling找兄弟的時(shí)候:記住nodeType的1,3狀態(tài)。1是元素,3是文字以及各種空格回車制表符。不過(guò)更常用nextElementSibling

  6. 記住常用DOM操作的API,出博客

  7. setInterval() clearInterval() setTimeout()

  8. 如果忘了使用new命令,直接調(diào)用構(gòu)造函數(shù)會(huì)發(fā)生什么事?

這種情況下,構(gòu)造函數(shù)就變成了普通函數(shù),并不會(huì)生成實(shí)例對(duì)象。而且由于后面會(huì)說(shuō)到的原因,this這時(shí)代表全局對(duì)象,將造成一些意想不到的結(jié)果。

  1. 運(yùn)算符:見(jiàn)博客

  2. 當(dāng)需要迅速先hide()再show()的時(shí)候,瀏覽器會(huì)自動(dòng)合并這個(gè)操作,也就是忽略掉hide(),此時(shí)可以在hide()之后調(diào)用offset()來(lái)打斷瀏覽器這一行為。因?yàn)閛ffset()會(huì)計(jì)算當(dāng)前CSS中涉及變量的偏移。

  3. 輪播圖時(shí),寬高在HTML寫死的原因:作為圖片站位符,防止圖片加載不均勻發(fā)生重排(re-layout),重排時(shí)圖片倒退,會(huì)降低效率,很耗內(nèi)存。

這個(gè)手段常用于頁(yè)面性能優(yōu)化。

  1. 狀態(tài)機(jī)的編程思想:

  2. 指導(dǎo)思想:HTML、CSS和JS:內(nèi)容、樣式和行為分離:

  • 不要用HTML控制樣式(<center>...</center>)
  • 不要用CSS控制行為(IE下的expression,效率低下)
  • 不要用js控制樣式(div.hide()、div.show(),會(huì)改變display;最好只用js更改class:$div.classList.add('disable'))
  1. .one():為元素添加一個(gè)事件處理,只執(zhí)行一次。

  2. transitionend事件會(huì)在CSS transition結(jié)束后觸發(fā),無(wú)縫輪播中有用到。

  3. “點(diǎn)擊別處消失”的實(shí)現(xiàn)方法:(遮蔽罩?)

(1)點(diǎn)擊元素自身處理

(2)用jq封裝好的

  1. dispatchEvent & fireEvent

  2. 如果是被點(diǎn)擊的節(jié)點(diǎn)同時(shí)擁有捕獲和冒泡,那么執(zhí)行順序和添加順序一致;其他情況都是優(yōu)先捕獲。

mouseenter:鼠標(biāo)進(jìn)入一個(gè)節(jié)點(diǎn)時(shí)觸發(fā),進(jìn)入子節(jié)點(diǎn)不會(huì)觸發(fā)這個(gè)事件
mouseover:鼠標(biāo)進(jìn)入一個(gè)節(jié)點(diǎn)時(shí)觸發(fā),進(jìn)入子節(jié)點(diǎn)會(huì)再一次觸發(fā)這個(gè)事件
mouseout:鼠標(biāo)離開(kāi)一個(gè)節(jié)點(diǎn)時(shí)觸發(fā),離開(kāi)父節(jié)點(diǎn)也會(huì)觸發(fā)這個(gè)事件
mouseleave:鼠標(biāo)離開(kāi)一個(gè)節(jié)點(diǎn)時(shí)觸發(fā),離開(kāi)父節(jié)點(diǎn)不會(huì)觸發(fā)這個(gè)事件

  1. click事件指的是,用戶在同一個(gè)位置先完成mousedown動(dòng)作,再完成mouseup動(dòng)作。因此,觸發(fā)順序是,mousedown首先觸發(fā),mouseup接著觸發(fā),click最后觸發(fā)。

dblclick事件則會(huì)在mousedown、mouseup、click之后觸發(fā)。

x, clientX, offsetX, pageX, screenX

(1)clientX、clientY
點(diǎn)擊位置距離當(dāng)前body可視區(qū)域的x,y坐標(biāo)
(2)pageX、pageY
對(duì)于整個(gè)頁(yè)面來(lái)說(shuō),包括了被卷去的body部分的長(zhǎng)度
(3)screenX、screenY
點(diǎn)擊位置距離當(dāng)前電腦屏幕的x,y坐標(biāo)
(4)offsetX、offsetY
相對(duì)于帶有定位的父盒子的x,y坐標(biāo)
MouseEvent.offsetX屬性返回鼠標(biāo)位置與目標(biāo)節(jié)點(diǎn)左側(cè)的padding邊緣的水平距離(單位像素)
(5)x、y
和screenX、screenY一樣

  1. 鍵盤事件由用戶擊打鍵盤觸發(fā),主要有keydown、keypress、keyup三個(gè)事件,它們都繼承了KeyboardEvent接口。
  • keydown:按下鍵盤時(shí)觸發(fā)。
  • keypress:按下有值的鍵時(shí)觸發(fā),即按下 Ctrl、Alt、Shift、Meta 這樣無(wú)值的鍵,這個(gè)事件不會(huì)觸發(fā)。對(duì)于有值的鍵,按下時(shí)先觸發(fā)keydown事件,再觸發(fā)這個(gè)事件。
  • keyup:松開(kāi)鍵盤時(shí)觸發(fā)該事件。

鼠標(biāo)的事件屬性。
onclick
ondblclick
onmousedown
onmouseenter
onmouseleave
onmousemove
onmouseout
onmouseover
onmouseup
onwheel

鍵盤的事件屬性。
onkeydown
onkeypress
onkeyup

焦點(diǎn)的事件屬性。
onblur
onfocus

表單的事件屬性。
oninput
onchange
onsubmit
onreset
oninvalid
onselect

觸摸的事件屬性。
ontouchcancel
ontouchend
ontouchmove
ontouchstart

拖動(dòng)的事件屬性分成兩類:一類與被拖動(dòng)元素相關(guān),另一類與接收被拖動(dòng)元素的容器元素相關(guān)。
被拖動(dòng)元素的事件屬性。
ondragstart:拖動(dòng)開(kāi)始
ondrag:拖動(dòng)過(guò)程中,每隔幾百毫秒觸發(fā)一次
ondragend:拖動(dòng)結(jié)束

接收被拖動(dòng)元素的容器元素的事件屬性。
ondragenter:被拖動(dòng)元素進(jìn)入容器元素。
ondragleave:被拖動(dòng)元素離開(kāi)容器元素。
ondragover:被拖動(dòng)元素在容器元素上方,每隔幾百毫秒觸發(fā)一次。
ondrop:松開(kāi)鼠標(biāo)后,被拖動(dòng)元素放入容器元素。

<dialog>對(duì)話框元素的事件屬性。
oncancel
onclose

  1. 當(dāng)需要響應(yīng)式布局時(shí),不要用img標(biāo)簽,用 div 的 background 來(lái)設(shè)置圖片,而且還可以加個(gè)懶加載什么的
background: transparent url(...) no-repeat center;
background-size: cover;
  1. 固定比例div技巧:https://www.w3cplus.com/css/aspect-ratio.html

  2. display: flow-root; // 只有一個(gè)作用,觸發(fā)BFC

  3. 為什么 let 和 const 不存在變量提升呢?

這是因?yàn)樵诰幾g階段, 當(dāng)遇到變量聲明時(shí), 編譯器要么將它提升至作用域頂部(var 聲明), 要么將它放到 臨時(shí)死區(qū)(temporal dead zone, TDZ), 也就是用 let 或 const 聲明的變量. 訪問(wèn) TDZ 中的變量會(huì)觸發(fā)運(yùn)行時(shí)的錯(cuò)誤, 只有執(zhí)行過(guò)變量聲明語(yǔ)句后, 變量才會(huì)從 TDZ 中移出, 這時(shí)才可訪問(wèn).

下面這個(gè)例子你能不能全部答對(duì).

typeof null; // 'object'
typeof []; // 'object'
typeof someStr; // 'undefined'
typeof str; // Uncaught ReferenceError: str is not defined
const str = 'Yancey';

第一個(gè), 因?yàn)?null 根本上是一個(gè)指針, 所以會(huì)返回 'object'. 深層次一點(diǎn), 不同的對(duì)象在底層都表示為二進(jìn)制, 在 Javascript 中二進(jìn)制前三位都為 0 的會(huì)被判斷為 Object 類型, null 的二進(jìn)制全為 0, 自然前三位也是 0, 所以執(zhí)行 typeof 時(shí)會(huì)返回 'object'.

第二個(gè)想強(qiáng)調(diào)的是, typeof 判斷一個(gè)引用類型的變量, 拿到的都是 'object', 因此該操作符無(wú)法正確辨別具體的類型, 如 Array 還是 RegExp.

第三個(gè), 當(dāng) typeof 一個(gè) 未聲明 的變量, 不會(huì)報(bào)錯(cuò), 而是返回 'undefined'

第四個(gè), str 先是存在于 TDZ, 上面說(shuō)到訪問(wèn) TDZ 中的變量會(huì)觸發(fā)運(yùn)行時(shí)的錯(cuò)誤, 所以這段代碼直接報(bào)錯(cuò).

  1. javascript:void($={}) 使不能復(fù)制的頁(yè)面可以復(fù)制(原理??)

  2. 瀏覽器渲染機(jī)制(reflow && repaint)

  3. flex布局中,對(duì)需要右對(duì)齊的元素設(shè)置margin-left: auto即可

  4. 圖片居中HTML5:

  1. defer和async的區(qū)別

  2. Object.assign 方法可以很方便地一次向類添加多個(gè)方法。

  3. 類的內(nèi)部所有定義的方法,都是不可枚舉的(non-enumerable)。

class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
// []
Object.getOwnPropertyNames(Point.prototype)
// ["constructor","toString"]

上面代碼中,toString 方法是 Point 類內(nèi)部定義的方法,它是不可枚舉的。這一點(diǎn)與 ES5 的行為不一致。

ES6 規(guī)定,在子類普通方法中通過(guò)super調(diào)用父類的方法時(shí),方法內(nèi)部的this指向當(dāng)前的子類實(shí)例。

class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() {
    super.print();
  }
}

let b = new B();
b.m() // 2

上面代碼中,super.print()雖然調(diào)用的是A.prototype.print(),但是A.prototype.print()內(nèi)部的this指向子類B的實(shí)例,導(dǎo)致輸出的是2,而不是1。也就是說(shuō),實(shí)際上執(zhí)行的是super.print.call(this)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容