-
Js中使用typeof能得到的類型
typeof underfined //underfined typeof 'abc' //string typeof 123 //number typeof true //boolean typeof {} //object typeof [] //object typeof null //object typeof console.log //function
-
何時使用 === 和 ==
if (obj.a == null) { //判定對象obj的a屬性是否存在 //這里相當于 obj.a === null || obj.a === underfined ,的簡寫形式。 //這是jQuery源碼中的推薦寫法。除此之外其他時候都使用 ===。 }
-
Js中的內置函數
Boolean / Number / String / Object / Array / Function / Date / RegExp / Error
-
Js中按存儲方式區分變量類型
值類型 引用類型 var a = 100; var obj1 = {num:10}; var b = a; var obj2 = obj1; a = 111; obj1.num = 22; console.log (b); //100 console.log (obj2.num); //22 //把數值作為一個整塊存入內存中, //只是對對象的一個引用,把指針 //隨后每個值會變得獨立。 //指向對象,多個變量共用一個值。
-
如何理解JSON
JSON.stringify ({a:10, b:20})
——把JSON輸出成字符串
JSON.parse('{"a": 10, "b": 20}')
——把該字符串轉化成JSON
根據以上可知,JSON 就是一個JS對象。
但同時,JSON也是一種數據格式。
-
如何準確判斷一個變量是數組類型
var arr = []; arr instanceof Array; //true,通過識別arr的構造函數來判斷。 typeof arr //Object,typeof 并不能識別引用類型的詳細類型。
-
寫一個原型鏈繼承的例子
一個封裝DOM查詢的栗子(獲取一個DOM內容然后導入到事件)
div1的每一次鏈式操作都是一次繼承,div1本身并沒有 html 和 on的屬性,但是它繼承了它的構造函數Elem的顯式原型的屬性。//創建構造函數 function Elem (id) { this.elem = getElementById (id); } //創造鏈操作 Elem.prototype.html = function (val) { var elem = this.elem; if (val) { elem.innerHTML = val; return this; //鏈式操作 } else { return elem.innerHTML; } } //創造鏈操作 Elem.prototype.on = function (type, fn) { var elem = this.elem; elem.addEventListener (type, fn); return this; //鏈式操作 } //開始鏈式操作 var div1 = new Elem (' id1 '); div1.html('<p>鏈式1</p>').on ('click', function () { console.log('鏈式2'); }).html ('鏈式3');
-
描述new一個對象的過程
function Foo (name, age) { this.name = name; this.age = age; this.class = 'class-1'; return this; } var f1 = new Foo ('XX', 18); var f2 = new Foo ('BB', 18);
- 創建一個新對象。
- this 指向這個新對象。
- 給 this 賦值(添加屬性)。
- return this ,完成構造。
-
zepto(或其他框架)源碼中如何使用原型鏈
語法跟 jQuery 相似
更加輕量化,砍了一些 api
讀過一些源碼,關于原型鏈和閉包。
-
說一下對變量提升的理解
其實就是執行上下文的概念。
淺顯的可以理解成,
變量定義和函數聲明在作用域內被提前執行。
在函數作用域內還包括 this 和 arguments。console.log (a); //undefined var a = 100; fn ('AAA'); // 'AAA' 20 function fn(name) { age = 20; console.log (name, 20); var age; }
-
說明this的幾種不同使用場景
①作為構造函數執行
②作為對象屬性執行
③作為普通函數執行
④call apply bind方法var a = { name: 'AAA'; fn: function () { console.log (this.name); // 就是這個this }; }; //作為對象屬性執行 a.fn(); // AAA //call apply bind方法 a.fn.call ({name:"BBB"}); // BBB //作為普通函數執行 var fn1 = a.fn(); fn1(); // window 這個函數就是由window來運行的。
-
創建10個 <a>,點擊彈出各自對應的序號
為每一個 a 標簽構造一個函數作用域,var i; for ( i = 0; i < 10; i++ ) { ( function ( i ) { var a = document.createElement('a'); a.innerHTML = i + "<br/>"; a.addEventListener ('click', function (e) { e.preventDefault (); alert ( i ); }); document.body.appendChild (a); }) ( i ); }
這樣在for循環的時候,變化的 i 就不會影響到每一個作用域里的 i 。
-
如何理解作用域
回答要點:①自由變量 ②作用域鏈,即自由變量的查找 ③閉包的兩個場景
作用域可以理解為代碼執行的一個區域(環境),
每個作用域中的變量是相對獨立的,可以分別定義同一個變量而不沖突。
但如果作用域中,沒有定義某個變量,是可以到父作用域中去尋找的。
但父作用域中沒有的變量,不能去子作用域中尋找,這就是作用域鏈。
除非使用閉包,才能從外獲取作用域內的變量。
-
實際開發中的閉包應用
function isFirstLoad () { var _list = []; // 創建一個數組來裝id return function (id) { if ( _list.indexOf(id) >= 0 ) { //用indexOf[id]來判斷id在數組中的序號 console.log(false); return false; // 如果有序號,即已經存在,終止函數。 }; _list.push(id); // 若不存在則加入到數組中。 console.log(true); }; }; var isFirst = isFirstLoad(); //運行isFirstLoad()返回一個閉包賦到isFirst中。 isFirst (10); //true isFirst (10); //false isFirst (20); //true isFirst (20); //false
-
同步和異步的區別,各舉一個例子
- 同步會阻塞代碼執行,而異步不會。
- alert是同步,阻塞代碼,alert之后的代碼停止執行,知道確定alert。
setTimeout是異步,不阻塞,繼續執行后面的代碼,再執行setTimeout的內容。
-
關于 setTimeout 的筆試題
運行的結果是 1、3、5、2、4。console.log(1); setTimeout (function () { console.log(2); }, 0); console.log(3); setTimeout (function () { console.log(4); }, 1000); console.log(5);
即使setTimeout的事件為0,函數也被會掛起,等到最后再回頭執行,
但是因為其時間短,所以在掛起的隊列里排前面。
-
前端使用異步的場景有哪些
因為js是單線程,所以需要異步,避免阻塞。-
定時任務:setTimeout,setInterval
-
網絡請求:ajax 請求,動態 <img> 加載
-
事件綁定。
-
-
獲取 2017 - 01 - 12 格式的日期
此 demo,在 getDate 函數中,function getDate (da) { if ( !da ) { da = new Date(); }; var year = da.getFullYear(); var month = da.getMonth() + 1; var day = da.getDate(); if ( month < 10 ) { month = "0" + month; }; if ( day < 10 ) { day = "0" + day; }; return year + "-" + month + "-" + day; } var da = new Date(); var date = getDate(da); console.log(date);
第一塊代碼,if 是為了避免傳入的 da 出錯,重新獲取。
第二塊代碼為獲取年月日,月份要+1。
第三塊代碼是修復數字為一位數時不好看的情況。
第四塊代碼為返回結果。
其中第三四塊中,都用了強制類型轉化,通過與字符串拼接,把數字轉化為字符串。
-
獲取隨機數,轉化為長度一致的字符串格式
var random = Math.random(); var random = random + '0000000000'; // 強制類型轉換,并補長隨機數。 var random = random.slice(0, 10); // 截取前十位,截多少上面就補多少。 console.log(random);
-
寫一個能遍歷對象和數組的通用 forEach 函數
- function allEach (object, fn) { // 構建萬能遍歷,傳入object和方法。
- var key;
- if (object instanceof Array) { // 判定是否數組
- object.forEach ( function (item, index) {
+ fn (index, item);
// 在數組上使用forEach,用function接收item和index,然后在傳給fn
- });
- } else { // 不是數組的話那就是對象
- for (key in object) { // key是對象里的成員
- if (object.hasOwnProperty (key)) { // 判定key是否為對象的原生屬性
+ fn (key, object[key]); // 把該屬性和屬性的值傳給 fn
- };
- };
- };
- };
+
- var arr = [2, 4, 5]; // 定義一個數組
- allEach (arr, function (index, item) { // 使用allEach方法,傳入數組和要使用的方法
- console.log (index, item);
- });
+ var obj = {X:100, Y:200};
- allEach (obj, function (key, value) {
- console.log (key, value);
- });
-
DOM 是哪種基本數據結構
樹
-
DOM 操作的常用 API 有哪些
針對節點:獲取 DOM節點、獲取DOM節點的 property 和 Attribute 等
針對樹結構:獲取元素父節點、獲取元素子節點等
新增節點和刪除節點
-
DOM 節點的 Attribute 和 property 有什么區別
- property:Js 對象的屬性,獲取和修改都是針對這個對象的。
- Attribute:html 標簽的屬性,獲取和修改都是針對這個標簽的。
-
如何檢測瀏覽器的類型
navigator.userAgen - 返回一個字符串
通過字符串的內容,可以判斷出瀏覽器類型和一些基本特性。
但也一定完全準確,有可能會被修改。
-
拆解 url 的各部分
以 http://primerscern.xyz/demo-blog-site?99#mid=100 為例console.log(location.href) // http://primerscern.xyz/demo-blog-site?99#mid=100 console.log(location.protocaol) // http: console.log(location.host) // primerscern.xyz console.log(location.pathname) // /demo-blog-site/ console.log(location.search) // ?99 console.log(location.hash) // #mid=100 // 通過每一個屬性,可以獲取,也可以修改。
-
簡述事件冒泡流程
-
DOM樹形結構
冒泡的順序,根據DOM樹形結構,按小到大(內到外、子到父)冒。 -
事件冒泡
逐層冒,逐層觸發事件。 -
阻止冒泡
有需要時,可以再某層阻止冒泡,來停止繼續向上冒泡。 -
冒泡應用
多數應用在事件委托。
-
DOM樹形結構
-
什么時候用到事件委托,優點是什么
當需要大量綁定事件時,就會用到事件代理。
好處就是
① 代碼比較簡潔,綁定一次代替多次。
② 瀏覽器壓力較小。
③ 可以實現動態綁定。
-
編寫一個通用的事件監聽綁定
function bindEvent (ele, type, selector, fn) { // 加入選擇器應對更多情況 if (fn == null) { fn = selector selector = null }//當不使用selector時,把fn換到前面來 ele.addEventListener(type, function (e) { //綁定事件,綁定時執行判斷 var target if (selector) { //需要代理 target = e.target if (target.matches(selector)) { //判斷,是否匹配選擇器 fn.call (target, e) } //執行主體為e.target,所以要把函數給回它執行 } else { //不代理 fn(e) } }) }
-
編寫一個原生的 ajzx
- var xhr = new XMLHttpRequest()
- xhr.open("GET", "/api", false)
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
+ if (xhr..status == 200) {
- alert(xhr.responseText)
- }
- }
- }
+ xhr.send(null)
-
跨域的幾種實現方式
- 三個標簽:<img src=''><script src='' <link href=''>。
- JSONP
-
服務器設置 http header
-
描述 cookie、sessionStorage 和 localStorage 的區別
- 容量:cookie 只有4kb ,而 Storage 則有 5m
- ajax:每次都會攜帶 cookie,占用性能,Storage 則不帶,僅用于存儲。
-
API 易用性:cookie 使用需要自行封裝一些方法,而 Storage 不用。
document.cookie
,localStorage.setItem(key, value)
,localStorage.getItem(key)
-
從輸入 url 到得到 html 的詳細過程
- 瀏覽器把輸入的 url 發送到 DNS 服務器,然后返回該域名的 IP 地址
- 向這個 IP 的機器(服務器)發送 http 請求
- 服務器收到、處理并返回 http 請求
- 瀏覽器得到返回的內容,然后繼續執行。
-
window.onload 和 DOMContentLoaded 的區別
前者是頁面的資源全部加載完畢,包括圖片,視頻等。
后者是當 DOM 渲染完即可,不需要等待圖片視頻加載。
-
瀏覽器渲染頁面的過程
- 根據 HTML 結構生成 DOM Tree(文檔樹形結構)
- 根據 CSS 生成 CSSOM(與DOM對應)
- 將 DOM 和 CSSOM 整合形成 RenderTree
- 根據 RenderTree 開始渲染和展示
- 遇到 <script> 時,會執行并且會阻塞渲染
***
***
Wait me back