Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 精品一区二区三区电影,国产国产成人精品久久,久久免费观看国产精品

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          2022最新前端 JS 筆試100道題

          2022最新前端 JS 筆試100道題

          S基礎

          js概念與類型檢測

          1. 以下不屬于 typeof 運算符返回值的是?
          A. "string"
          B. "function"
          C. "object"
          D. "null"
          
          1. 執行以下代碼,錯誤的輸出結果是
          A. 輸入:typeof {"x":1} 輸出:"object" 
          B. 輸入:typeof 1 輸出:"number" 
          C. 輸入:typeof [{x:1}] 輸出:"array" 
          D. 輸入:typeof NaN 輸出:"number"
          
          1. 可以用typeof來判斷的基本類型有
          A. undefined
          B. null
          C. array
          D. object
          
          1. 以下不屬于JavaScript基本數據類型的是:
          A. Boolean
          B. undefined
          C. Symbol
          D. Array
          
          1. 以下關于JavaScript中數據類型的說法錯誤的是()
          A. 數據類型分為基本數據類型和引用數據類型
          B. JavaScript一共有8種數據類型
          C. Object是引用數據類型,且只存儲于堆(heap)中
          D. BigInt是可以表示任意精度整數的基本數據類型,存儲于棧(stack)中
          

          答案

          DCADC
          

          邏輯判斷

          1. 請選擇結果為ture的表達式?
          A. null instanceof Object
          B. null===undefined
          C. null==undefined
          D. NaN==NaN
          
          1. 下列代碼結果為 true 的是?
          A. Symbol.for('a')===Symbol.for('a')
          B. Symbol('a')===Symbol('a')
          C. NaN===NaN
          D. {}==={}
          
          1. 根據如下變量,下列表達式中返回值為true的是
          var a=1;
          var b=[];
          var c='';
          var d=true;
          
          A. (a || b)===true
          B. (b && c)===true
          C. (c && d)===true
          D. (d || a)===true
          
          1. 1==true的返回值是true,這句話是否正確?
          A. T
          B. F
          
          1. 下面代碼輸出為true的是?
          A. console.log([]===[]);
          B. console.log(undefined==0);
          C. console.log(undefined==false);
          D. console.log(false=='');
          
          1. 瀏覽器環境下,以下打印結果為true的是
          A. console.log("12"===12)
          B. console.log (NaN===NaN)
          C. console.log (typeof(null)===typeof(window))
          D. console.log ([1,2,3]===[1,2,3])
          

          注意瀏覽器環境與node環境的差別,比如C選項

          1. 以下表達式,正確的是
          A. Number('a')==Number('a')
          B. -1==true
          C. 3 + '2'===5
          D. ![]==''
          

          答案

          CADADCD
          

          Math

          1. 如何把 7.25 四舍五入為最接近的整數
          A. Math.round(7.25)
          B. Math.ceil(7.25)
          C. round(7.25)
          D. Math.rnd(7.25)
          
          1. 下面哪個選項可以產生0<=num<=10的隨機整數
          A. Math.floor(Math.random()*6)
          B. Math.floor(Math.random()*10)
          C. Math.floor(Math.random()*11)
          D. Math.ceil(Math.random()*10)
          
          1. 以下( )表達式產生一個0~7之間(含0,7)的隨機整數
          A. Math.floor(Math.random()*6)
          B. Math.floor(Math.random()*7)
          C. Math. floor(Math.random()*8)
          

          答案

          A CD(注意D) C
          

          字符串

          1. split() 方法用于把一個字符串分割成字符串數組。
          A. T
          B. F
          
          1. String對象的哪個方法可以尋找子字符串并返回該子字符串位置
          A. match()
          B. indexOf()
          C. search()
          D. concat()
          

          答案

          A BC
          

          JSON

          1. 下面哪一個是JSON數據?
          A. {name:"xiaoming",age,"student"}
          B. {"name":"xiaoming","age":"student"}
          C. {"xiaoming","student"}
          D. ["xiaoming","student"]
          
          1. 下面分別使用 JSON.stringify 方法,返回值 res 分別是
          const fn=function(){}
          const res=JSON.stringify(fn)
          const num=123
          const res=JSON.stringify(num)
          const res=JSON.stringify(NaN)
          const b=true
          const res=JSON.stringify(b)
          
          A. 'function'、'123'、'NaN'、'true'
          B. undefined、'123'、undefined、'true'
          C. undefined、'123'、'null'、'true'
          D. undefined、'123'、'null'、undefined
          

          答案

          BC
          

          數組

          1. js數組中不會改變原有數組的方法是()
          A. push
          B. concat
          C. sort
          D. shift
          
          1. 下列哪種數組的方法不會修改數組本身
          A. slice
          B. splice
          C. sort
          D. unshift
          
          1. JavaScript中需要往數組末尾處添加一個元素,應該使用以下哪個方法:
          A. push
          B. pop
          C. shift
          D. unshift
          
          1. 以下js操作Array的方法中不能添加元素的是:
          A. push
          B. pop
          C. unshift
          D. splice
          
          1. 數組以下哪個方法會影響原數組?
          A. concat
          B. splice
          C. slice
          D. join
          
          1. JavaScript中,下列哪一個Array的方法的返回值類型和其他不同
          A. concat
          B. shift
          C. filter
          D. map
          
          1. 如下的Array.prototype上的方法中,那個方法不會改變原有的數組?
          A. push
          B. slice
          C. splice
          D. sort
          
          1. 對于一個數字組成的數組 nums,現在需要執行在不改動 nums 的基礎上去重操作,返回一個新的無重復元素的數組,以下幾段代碼能完成這一操作的是()
          // (1)
          const newNums=Array.from(new Set(nums))
          
          // (2)
          const newNums=nums.filter((n, i)=> {
              return nums.indexOf(n)===i
          })
          
          // (3)
          const newNums=nums.forEach((n, i)=> {
              return nums.indexOf(n)===i
          })
          
          // (4)
          const newNums=nums.reduce((acc, n, i)=> {
              return [].concat(acc, nums.indexOf(n)===i ? n : []
          )
          })
          
          A. (1)、(2)、(3)、(4)
          B. (1)、(3)、(4)
          C. (1)、(2)、(4)
          D. (1)、(4)
          

          答案

          BAABB
          BBC
          

          正則

          1. 正則表達式 ^d+[^d]+ 能匹配下列哪個字符串?
          A. 123
          B. 123a
          C. d123
          D. 123def
          
          1. 下面哪個不是RegExp對象的方法
          A. test
          B. match
          C. exec
          D. compile
          
          1. 以下哪項可以去除變量str中的所有空格
          A. str.replace(`/\s*/g,""`)
          B. str.replace(`/^\s|\s$/g,""`)
          C. str.replace(`/^\s*/, ""`)
          D. str.replace(`/(\s*$)/g, ""`)
          

          答案

          CBA
          

          其他

          1. 下列函數哪個不是JavaScript的全局函數
          A. encodeURI
          B. parseFloat
          C. round
          D. eval
          
          1. 編寫高性能JavaScript,以下描述錯誤的是
          A. 遵循嚴格模式:"use strict"
          B. 將js腳本放在頁面頂部,加快渲染頁面
          C. 將js腳本成組打包,減少請求,盡量減少使用閉包
          D. 使用非阻塞方式下載js腳本,最小化重繪(repaint)和回流(reflow)
          
          1. 有關JavaScript中系統方法的描述,錯誤的是?
          A. parseFloat方法:該方法將一個字符串轉換成對應的小數
          B. isNaN方法:該方法用于檢測參數是否為數值型,如果是,返回true,否則,返回false。
          C. escape方法: 該方法返回對一個字符串編碼后的結果字符串
          D. eval方法:該方法將某個參數字符串作為一個JavaScript執行題
          
          1. 下面列出的瀏覽器,無webkit內核的是()
          A. chrome
          B. Safari
          C. 搜狗瀏覽器
          D. Firefox
          
          1. 下列代碼哪個能夠實現獲取形式為 2017-08-01 形式的日期( )?
          // A
          var formatDate=getDate()
          // B
          var formatDate=new Date()
          // C
          var formatDate=function (date) {
              var y=date.getFullYear();
              var m=date.getMonth() + 1;
              
              var d=date.getDate();
              return y + '-' + m + '-' + d;
          };
          // D
          var formatDate=function (date) {
              var y=date.getFullYear();
              var m=date.getMonth() + 1;
              m=m < 10 ? '0' + m : m;
              var d=date.getDate();
              d=d < 10 ? ('0' + d) : d;
              return y + '-' + m + '-' + d;
          };
          
          1. 下面哪一項不能最小化重繪(repaint)和回流(reflow)
          A. 需要對元素進行復雜的操作時,可以先隱藏(display:"none"),操作完成后再顯示
          B. 需要創建多個DOM節點時,使用DocumentFragment創建完后一次性的加入document
          C. 盡量避免用table布局(table元素一旦觸發回流就會導致table里所有的其它元素回流)
          D. 盡量不要使用 css 屬性簡寫,如:用border-width, border-style, border-color代替border
          

          答案

          CBBDDD
          

          JS深入

          this

          1. 下列哪種方法不能改變this指向()
          A. eval
          B. apply
          C. bind
          D. call
          
          1. 在JavaScript中下面選項關于this描述正確的是
          A. 在使用new實例化對象時, this指向這個實例對象
          B. 將對象的方法賦值給變量A。執行A()時 該方法中的this指向這個對象。 
          C. 在函數定義時,this指向全局變量
          D. 在瀏覽器下的全局范圍內,this指向全局對象
          
          1. 下面有關JavaScript中call和apply方法的描述,錯誤的是?
          A. call與apply都屬于Function.prototype的一個方法,所以每個function實例都有call、apply屬性
          B. 兩者傳遞的參數不同,call函數第一個參數都是要傳入給當前對象的對象,apply不是
          C. apply傳入的是一個參數數組,也就是將多個參數組合成為一個數組傳入
          D. call傳入的則是直接的參數列表。call 方法可將一個函數的對象上下文從初始的上下文改變為由 thisObj 指定的新對象。
          

          答案

          AAB
          

          作用域(閉包)

          1. 內存泄漏是 javascript 代碼中必須盡量避免的,以下幾段代碼可能會引起內存泄漏的有()
          // (1)
          function getName() {
              name='javascript'
          }
          getName()
          
          // (2)
          const elements={
              button: document.getElementById('button')
          };
          function removeButton() {
              document.body.removeChild(elements.button);
          }
          removeButton()
          
          // (3)
          let timer=setInterval(()=> {
              const node=document.querySelector('#node') 
              if(node) {
                  clearInterval(timer)
              }
          }, 1000);
          
          A. (1)、(2)、(3)
          B. (2)、(3)
          C. (1)、(3)
          D. (1)、(2)
          
          1. 那個操作不會造成內存泄露
          A. 沒有清理的DOM元素引用
          B. 被遺忘的定時器
          C. 事件偵聽沒有移除
          D. 局部變量不用時,沒有設為null
          
          1. 下列關于閉包理解錯誤的是
          A. 增加一定的內存消耗
          B. 使用不當可能會導致內存泄漏
          C. 可以使用閉包模擬私有方法
          D. 閉包會改動對象的原型鏈
          

          答案

          DDD
          

          原型與繼承

          1. JavaScript實現繼承的方式,不正確的是:
          A. 原型鏈繼承
          B. 構造函數繼承
          C. 組合繼承
          D. 關聯繼承
          
          1. 所有對象都有原型
          A. T
          B. F
          
          1. 以下關于原型鏈的描述正確的是:
          A. 通過原型鏈繼承的屬性和對象自己定義的屬性等效
          B. 通過原型鏈可以模擬對象的私有屬性
          C. 在對象上訪問不存在的屬性時,會依次遍歷整條原型鏈
          D. 所有 JavaScript 中的對象都是位于原型鏈頂端的 `Object` 的實例
          

          答案

          DBC
          

          其他

          1. 以下不屬于前端數據存儲方式的是?
          A. jsonp
          B. cookie
          C. localStorage
          D. sessionStorage
          

          答案

          A
          

          DOM題

          事件流

          1. 將A元素拖拽并放置到B元素中,B元素需要做哪項操作()?
          A. event.preventDefault()
          B. event.prevent()
          C. event.drag()
          D. event.drop()
          
          1. 以下不支持冒泡的鼠標事件為( )?
          A. mouseover
          B. click
          C. mouseleave
          D. mousemove
          
          1. 在javascript中,用于阻止默認事件的默認操作的方法是
          A. stopDeafault()
          B. stopPropagation()
          C. preventDefault()
          D. preventDefaultEven()
          
          1. 事件傳播的三個階段是什么
          目標 -> 捕獲 -> 冒泡
          冒泡 -> 目標 -> 捕獲
          目標 -> 冒泡 -> 捕獲
          捕獲 -> 目標 -> 冒泡
          
          1. 下面有關 javascript 常見事件的觸發情況,描述錯誤的是?
          A. onchange:用戶改變域的內容
          B. onkeypress:某個鍵盤的鍵被按下或按住
          C. onmousedown:某個鼠標按鍵被按下
          D. onblur:元素獲得焦點
          

          答案

          ACCDD
          

          DOM遍歷

          1. 下列哪項不屬于DOM查找節點的屬性()?
          A. parentObj.firstChild
          B. parentObj.children
          C. neborNode.previousSibling
          D. neborNode.siblings
          
          1. DOM中,給父節點添加子節點的正確方法為()?
          A. appendChild(parentNode,newNode);
          B. append(parentNode,newNode);
          C. parentNode.append(newNode);
          D. parentNode.appendChild(newNode);
          
          1. JavaScript中document.getElementById()返回值的類型為?
          A. Array
          B. Object
          C. String
          D. Function
          
          1. DOM中,給父節點添加子節點的正確方法為()?
          A. appendChild(parentNode,newNode);
          B. append(parentNode,newNode);
          C. parentNode.append(newNode);
          D. parentNode.appendChild(newNode);
          

          答案

          DDBD
          

          其他

          1. DOM元素的以下屬性改變會導致重排(reflows)的是
          outline
          visiblity
          font-size
          background-color
          

          答案

          C
          

          BOM題

          1. setInterval(updateClock,60)的含義是( )?
          A. 每隔60秒調用一次updateClock()
          B. 每隔60毫秒調用一次updateClock()
          C. 每隔60分鐘調用一次updateClock()
          D. 每分鐘調用60次updateClock()
          
          1. 使用方法( )可以獲取到地理位置所在的經緯度?
          A. Geolocation.watchPosition()
          B. Geolocation.getCurrentPosition()
          C. Geolocation.getPosition()
          D. Geolocation.Position()
          
          1. setInterval("alert('welcome');",1000);這段代碼的意思是
          A. 等待1000秒后,再彈出一個對話框
          B. 等待1秒鐘后彈出一個對話框
          C. 每隔一秒鐘彈出一個對話框
          D. 語句報錯,語法有問題
          

          答案

          BBC
          

          ES6題

          箭頭函數

          1. 下列對js箭頭函數描述錯誤的是()
          A. 箭頭函數沒有原型屬性
          B. 箭頭函數不綁定this,會捕獲其所在的上下文的this值,作為自己的this值
          C. 箭頭函數可以作為構造函數,使用new
          D. 箭頭函數不綁定arguments,取而代之用rest參數解決
          
          1. 關于箭頭函數下列說法錯誤的一項是:
          A. 函數體內this的指向是定義時所在的對象,而不是使用時所在的對象
          B. 箭頭函數內不能使用arguments對象
          C. 箭頭函數不能使用yield命令
          D. 可以使用new創建一個箭頭函數的實例
          

          答案

          CD
          

          promise

          1. 關于將 Promise.all 和 Promise.race 傳入空數組的兩段代碼的輸出結果說法正確的是:
          Promise.all([]).then((res)=> {
              console.log('all');
          });
          Promise.race([]).then((res)=> {
              console.log('race');
          });
          
          A. all 和 race 都會被輸出
          B. all 和 race 都不會被輸出
          C. all 會被輸出,而 race 不會被輸出
          D. all 不會被輸出,race 會被輸出
          
          1. 以下方案中,不是用于解決回調陷阱的的是:
          A. Promise
          B. Generator
          C. async
          D. Proxy
          
          1. 在 ECMAScript6 中,不屬于promise的狀態是:
          A. Pending
          B. Pause
          C. Fulfilled
          D. Rejected
          

          答案

          CDB
          

          解構賦值

          1. 關于ES6解構表達式,描述正確的是()
          let [a,b, c,d, e]="hello"; 
          
          A. e="hello";
          B. 其它都為undefined
          C. 當中 a="h", b="e";
          D. 語法報錯
          

          答案

          C
          

          多選題

          JS基礎

          1. 下面哪些數組方法會改變原數組
          A. push 
          B. concat 
          C. splice 
          D. map
          
          1. 下面可以聲明數字的js代碼是
          A. const a=0xa1
          B. const a=076
          C. const a=0b21
          D. const a=7e2
          
          1. 以下屬于操作符 typeof 的返回值的是:
          (1)function
          (2) object
          (3) null
          (4) array
          (5) NaN
          (6) bigint
          (7) regexp
          (8) undefined
          
          A. (1)、(2)、(3)、(4)、(5)、(6)、(7)、(8)
          B. (1)、(2)、(3)、(8)
          C. (1)、(2)、(8)
          D. (1)、(2)、(6)、(8)
          
          1. 以下()結果等于字符串string
          A. typeof 'string'
          B. String('string').toString()
          C. 'string'.split('').sort().join('')
          D. (function(string){return string})('string')
          E. JSON.parse('{"string":"string"}').string
          
          1. 下面的等式成立的是?
          A. parseInt(46.8) `==` parseFloat(46.8)
          B. NaN `!==` NaN
          C. isNaN('abc') `==` NaN
          D. typeof NaN `===` 'number'
          
          1. 以下哪些選項可以將集合A轉化為數組?
          A. Array.from(A)
          B. [].slice.apply(A)
          C. [...A]
          D. [].map.call(A, o=> o)
          
          1. 下列結果返回 true 的是
          A. null==undefined
          B. null===undefined
          C. null===null
          D. NaN==null
          E. NaN===NaN
          F. Infinity + 1 !==Infinity
          

          答案

          AC ABD D ABDE BD ABCD AC
          

          JS深入

          1. 關于以下代碼,說法正確的有哪些?

          function Person() { } var person=new Person();

          A. 每一個原型都有一個constructor屬性指向關聯的構造函數。
          B. 每一個對象都有一個prototype屬性。
          C. Object.getPrototypeOf(person)===Person.prototype
          D. person.constructor===Person
          
          1. 下列在 JS 時間循環機制中屬于微任務(microTask)的是?
          A. process.nextTick
          B. promise
          C. setTimeout
          D. setInterval
          

          答案

          ACD AB
          

          ES6

          1. 以下關于let和const的說法中正確的是:
          A. let聲明的變量值和類型都可以改變
          B. const聲明的常量不可以改變
          C. 兩者都不存在變量提升,同時存在暫時性死區,只能在聲明的位置后面使用
          D. const可以先聲明再初始化,可以后賦值
          
          1. 下面關于Promise說法正確的是(注意“返回結果”的意思包含成功或者失敗)
          A. Promise.all在所有給定的promise都fulfilled后才返回結果
          B. Promise.race在給定的promise中,某個fulfilled后才返回結果
          C. promise.then的回調函數中,可以返回一個新的promise
          D. 對于一個向后臺獲取數據已經產生結果的promise:p1,再次調用p1.then,不會去重新發起請求獲取數據
          

          答案

          ABC CD
          

          DOM

          1. 下列關于使用 JS 修改元素樣式的代碼,正確的有哪些?
          document.body.style.['background-color']='#fff'
          document.body.style.setProperty('background-color', '#fff')
          document.body.style='background-color': #fff'
          document.body.style.fontSize='14px'
          
          1. 下列方法可用于阻止事件冒泡的有
          A. event.cancelBubble=true;
          B. event.stopPropagation();
          C. event.preventDefault();
          D. return false;
          

          答案

          BCD ABD
          

          填空題

          類型檢測

          1. 在JavaScript中,有var arr=[]; typeof arr的結果為
          2. 以下使用 typeof 操作符的代碼的輸出結果為
          var x=typeof x
          var res=typeof typeof x;
          console.log(x, res)
          
          1. [typeof null, null instanceof Object]的結果是什么
          2. typeof typeof 0
          3. JavaScript的typeof運算符的可能結果為array?解釋為什么
          4. 下面代碼的輸出結果是多少?
          var arr=[];
          console.log(typeof arr, Object.prototype.toString.call(arr));
          
          1. console.log(Object.prototype.toString.call(undefined))

          類型轉換

          1. 表達式 "2"+3+4 的值為
          2. console.log('5' + 3, 5 + '3')
          3. var a=parseInt(“111辦公室”);alert(a);
          4. ["0x1", "0x2", "0x3"].map(parseInt) 的結果
          5. 在js中執行 1+'1'的結果是?
          6. 在js中執行 parseInt('77',40)的結果是?

          邏輯判斷

          1. 請給出 [5<6<3,3<2<4] 代碼的運行結果
          2. (2<3)||(3<2) 表達式將返回值為
          3. console.log(true||false&&false, true&&false||true)的輸出結果是?

          其他

          1. 1 + - + + + - + 1 的結果是
          2. [ 'a', ,'b', ,].length 的結果是

          程序題

          JS基礎

          1. 下面兩個程序的輸出結果分別是?
          // case 1
          function showCase(value) {
              switch(value) {
              case 'A':
                  console.log('Case A');
                  break;
              case 'B':
                  console.log('Case B');
                  break;
              case undefined:
                  console.log('Case undefined');
                  break;
              default:
                  console.log('Case default');
              }
          }
          showCase(new String('A'));
          
          // case 2
          function showCase(value) {
              switch(value) {
              case 'A':
                  console.log('Case A');
                  break;
              case 'B':
                  console.log('Case B');
                  break;
              case undefined:
                  console.log('Case undefined');
                  break;
              default:
                  console.log('Case default');
              }
          }
          showCase(String('A'));
          
          1. p標簽的的內容會顯示什么?
          <html>
              <body>
                  <p id="demo"></p>
                  <script type="text/javascript">
                      var x=10;
                      var y="10";
                      document.getElementById("demo").innerHTML=Boolean(x==y);
                  </script>
              </body>
          </html>
          
          1. document.write的結果會是什么?
          function funcA(x){
              var temp=4;
          
              function funcB(y){
                  document.write( ++x + y + (temp--));
              }
          
              funcB(5);
          }
          
          funcA(6)
          
          1. alert的結果會是多少
          var varArr=function(i,j,str) {  
              return j==0 ? str : varArr(i,--j,(str+=" " + i[j]));
          }
          var arr=new Array('apple','orange','peach','lime');
          var str=varArr(arr,arr.length,"");
          alert(str);
          
          1. 下面程序的輸出結果是多少?
          function greetingMaker(greeting) { 
              function addName(name) {    
                  greeting=greeting.split(' ').reverse().join("-");
                  return greeting + " " + name;
              }
              
              return addName;
          }
          
          var daytimeGreeting=greetingMaker("Good Day to you");
          alert(daytimeGreeting(name)); 
          
          1. 下面程序的輸出結果是多少?
          String.prototype.GetNum=function() { 
              var regEx=/[^\d]/g; 
              return this.replace(regEx, ''); 
          };
          
          var str="a1b2c3";
          str=str.GetNum();
          alert(str);
          
          1. 下面程序的輸出結果是多少?
          function sum(a, b) {
            return a + b;
          }
          sum(1, "2");
          
          1. 下面程序的輸出結果是多少?
          var str="我非常喜歡編程";
          str.length=3;
          console.log(str);
          
          1. 下面程序的輸出結果是多少?
          let number=0;
          console.log(number++);
          console.log(++number);
          console.log(number);
          
          1. 下面程序的輸出結果是多少?
          function nums(a, b) {
              if (a > b)
                  console.log('a is bigger')
              else 
                  console.log('b is bigger')
              return a + b
          }
          console.log(nums(4, 2))
          console.log(nums(1, 2))
          
          1. 下面程序輸出結果是多少?
          function side(arr) {
              arr[0]=arr[2];
          }
          function func1(a, b, c=3) {
              c=10;
              side(arguments);
              console.log(a + b + c);
          }
          function func2(a, b, c) {
              c=10;
              side(arguments);
              console.log(a + b + c);
          }
          func1(1, 1, 1);
          func2(1, 1, 1);
          
          1. 下面代碼的輸出結果是什么?
          var a=3;
          var b=new Number(3);
          var c=3;
          
          console.log(a==b);
          console.log(a===b);
          console.log(b===c);
          
          
          1. 執行下列語句后,a.length的值為?
          var a=[];
          a.push(1, 2);
          a.shift(3, 4);
          a.concat([5, 6]);
          a.splice(0, 1, 2);
          
          1. 下面這幾段代碼分別輸出結果是多少?為什么?
          var a={}, b='123', c=123;
          a[b]='b';
          a[c]='c';
          console.log(a[b]);
          // example 2
          var a={}, b=Symbol('123'), c=Symbol('123');
          a[b]='b';
          a[c]='c';
          console.log(a[b]);
          // example 3
          var a={}, b={key:'123'}, c={key:'456'};
          a[b]='b';
          a[c]='c';
          console.log(a[b]);
          
          1. 下面每項的返回值是什么?為什么?
          null==undefined
          0.1 + 0.2==0.3
          typeof NaN
          typeof Function
          typeof Object
          typeof {}
          'a' + 1
          'a' - 1
          Function instanceof Object
          Object instanceof Function
          
          1. 下面程序的輸出結果是多少?
          var array=[]
          for(var i=0; i < 3; i++) {
              array.push(()=> i)
          }
          var newArray=array.map(el=> el())
          console.log(newArray)
          
          1. 下面程序的輸出結果是多少?
           function a(m, n) {
                  var b=function (l) {
                      return l <=m ? l * b(l + 1) : 1;
                  }
          
                  return b(m - n + 1);
              }
          
          console.log(a(4, 2));
          
          1. 下面程序的輸出結果是多少?
          console.log(typeof undefined==typeof NULL);
          console.log(typeof function () {}==typeof class {});
          
          1. 執行后a和b.age的值分別為
          var a=10
          var b={
              age: 11
          }
          function fn(x,y) {
              --y.age;
              return --x;
          }
          fn(a,b)
          
          1. 下面程序的執行結果是:
          var number=4;
          var numberFactorial=(function (number){
              return (number===0)? 1: number* factorial(number-1)
          })(number)
          console.log(numberFactorial)
          
          1. 下面程序的輸出結果是:
          var array=[]
          for(var i=0; i < 3; i++) {
              array.push(()=> i)
          }
          var newArray=array.map(el=> el())
          console.log(newArray)
          
          1. 下面程序的輸出結果是:
          function addToList(item, list) {
              return list.push(item)
          }
          const result=addToList("nowcoder", ["hello"])
          console.log(result)
          
          
          1. 下面程序的輸出結果是:
          const first=()=> { console.log('first'); return false; }
          const second=()=> { console.log('second'); return true; }
          console.log( first() && second() );
          console.log( second() || first() );
          
          1. 下面代碼的輸出結果是:
          var s='12ab3cd', arr=s.split(/\d/);
          console.log(arr[3],arr[4])
          
          1. 下面程序的輸出結果是:
          function getAge(...args) {
            console.log(typeof args);
          }
          
          getAge(21);
          
          1. 下面程序的輸出結果是:
          var arr=[1,2,3];
          arr.push(arr.shift())
          console.log(arr[1],arr[2])
          

          JS深入

          this指向

          題目解析:this指向題目解析及擴展[3]

          關于this還可以看看:可能是最好的 this 解析了...

          1. 下列程序的輸出結果是多少?為什么?
          var x=1;
          
          var obj={
              x: 3,
              fun:function () {
                  var x=5;
                  return this.x;
              }
          };
          
          var fun=obj.fun;
          console.log( obj.fun(), fun() );
          
          
          1. 下列程序的輸出結果是多少?你能理清楚test函數的this指向嗎?
          var a=5;
           function test() { 
              a=0; 
              alert(a); 
              alert(this.a); 
              var a;
              alert(a); 
          }
          new test();
          
          
          1. 下列程序的輸出結果是多少?為什么?
          function fun () {
              return ()=> {
                  return ()=> {
                      return ()=> {
                          console.log(this.name)
                      }
                  }
              }
          }
          var f=fun.call({name: 'foo'})
          var t1=f.call({name: 'bar'})()()
          var t2=f().call({name: 'baz'})()
          var t3=f()().call({name: 'qux'})
          
          
          1. 執行以下代碼,輸出結果分別是多少?
          let obj1={
              a: 1,
              foo: ()=> {
                  console.log(this.a)
              }
          }
          // log1
          obj1.foo()
          const obj2=obj1.foo
          // log2
          obj2()
          
          1. 下面程序的輸出結果是什么?為什么?
          const Person=(name="wang",age=10)=> {
          this.name=name;
          this.age=age;
          return this.name +' is '+ this.age + 'years old'
          }
          let result=new Person('zhang',11)
          console.log(result)
          
          1. 請表述以下代碼的執行結果和原因
          var person={
            age: 18,
            getAge: function() {
              return this.age;
            }
          };
          var getAge=person.getAge
          getAge()
          
          1. 請按順序寫出打印結果,并說明原因。
          var name='global';
          var obj={
              name: 'local',
              foo: function(){
                  this.name='foo';
              }.bind(window)
          };
          var bar=new obj.foo();
          setTimeout(function() {
              console.log(window.name);
          }, 0);
          console.log(bar.name);
           
          var bar3=bar2=bar;
          bar2.name='foo2';
          console.log(bar3.name);
          
          
          1. 下面程序的執行結果是:
          var obj={
              name:"zhangsan",
              sayName:function(){
                  console.info(this.name);
              }
          }
          
          var wfunc=obj.sayName;
          obj.sayName();
          wfunc();
          var name="lisi";
          obj.sayName();
          wfunc();
          
          1. 下面程序的輸出結果是:
          var name='test' 
          var a={    
              name: 'ass',    
              getName: function() {    
                  return this.name;   
              } 
          } 
          var b=a.getName; 
          b();
          

          事件循環

          1. 下列程序的輸出結果分別是多少?為什么?
          const promiseA=Promise.resolve('a')
          promiseA. then((res)=> {
              console.log(res)
          }).then((res)=> {
              console.log(res)
          })
          const promiseB=Promise.resolve('b')
          promiseB. then((res)=> {
              console.log(res)
          })
          promiseB. then((res)=> {
              console.log(res)
          })
          
          
          1. 下面程序的輸出結果依次是多少?
          setTimeout(()=> {
              console.log(1)
          }, 0)
          
          const P=new Promise((resolve, reject)=> {
              console.log(2)
              setTimeout(()=> {
                  resolve()
                  console.log(3)
              }, 0)
          })
          
          P.then(()=> {
              console.log(4)
          })
          console.log(5)
          
          1. 下面程序的輸出結果是
          setTimeout(function(){
              console.log(1);
          }, 0)
          new Promise(function(resolve){
              console.log(2);
              resolve();
              console.log(3);
          }).then(function(){
              console.log(4);
          })
          console.log(5);
          
          
          1. 下面程序的輸出結果是?
          (async ()=> {
              console.log(1);
              setTimeout(()=> {
                  console.log(2);
          }, 0);
          await new Promise((resolve, reject)=> {
              console.log(3);
          }).then(()=> {
              console.log(4);
          });
              console.log(5);
          })();
          
          
          1. 下面程序的輸出結果是:
          new Promise((resolve)=> {
              console.log('1')
              resolve()
              console.log('2')
          }).then(()=> {
              console.log('3')
          })
          setTimeout(()=> {
              console.log('4')
          })
          console.log('5')
          
          1. 下面程序的輸出結果是:
          var p1=new Promise(function(resolve, reject){
              resolve("2")
          })
          setTimeout(function(){
              console.log("1")
          },10)
          p1.then(function(value){
              console.log(value)
          })
          setTimeout(function(){
              console.log("3")
          },0)
          
          
          1. 下面程序的輸出結果是:
          setTimeout(function() {
            console.log('setTimeout');
          }, 0);
          Promise.resolve().then(function() {
            console.log('promise1');
          }).then(function() {
            console.log('promise2');
          });
          
          1. 請表述以下代碼的執行結果和原因
          setTimeout(function() {
              console.log(1)
          },0)
          new Promise(function executor(resolve){
              console.log(2)
              for (var i=0; i<10000; i++) {
                  i - 9999 && resolve()
              }
              console.log(3)
          }).then(function() {
              console.log(4)
          })
          console.log(5)
          
          1. 在網頁中有兩個div塊,html代碼如下
          <div class="outer">
           <div class="inner"></div>
          </div>
          

          對應的js代碼如下:

          var outer=document.querySelector('.outer');
          var inner=document.querySelector('.inner');
          
          function onClick() {
              console.log('click');
          
              setTimeout(function() {
                  console.log('timeout');
              }, 0);
          
              Promise.resolve().then(function() {
                  console.log('promise');
              });
          
              outer.setAttribute('data-random', Math.random());
          }
          
          inner.addEventListener('click', onClick);
          outer.addEventListener('click', onClick);
          

          當點擊class為inner的div塊時,控制臺依次輸出結果是什么?10. 下面程序的輸出結果是?

          (async ()=> {
              console.log(1);
              setTimeout(()=> {
                  console.log(2);
          }, 0);
          await new Promise((resolve, reject)=> {
              console.log(3);
          }).then(()=> {
              console.log(4);
          });
              console.log(5);
          })();
          
          1. 下面程序的輸出結果是:
          setTimeout(()=> console.log('a'));
          Promise.resolve().then(
             ()=> console.log('b’);
           ).then(
             ()=> Promise.resolve('c').then(
               (data)=> {
                 setTimeout(()=> console.log('d'));
                 console.log('f');
                 return data;
               }
             )
           ).then(data=> console.log(data));
          
          
          1. 下面程序的輸出結果是:
          console.log('one'); 
          setTimeout(function() { console.log('two'); }, 0); 
          Promise.resolve()
                 .then(function() { console.log('three'); })
           console.log('four');
          
          
          1. 下面程序的執行結果是:
          setTimeout(function () {
              console.log(C)
          },0)
          console.log('D')
          new Promise(function(resolve){
              console.log('E')
              resolve()
              console.log('F')
          }).then(function() {
              console.log('G')
          })
          console.log('H')
          
          1. 有一個輸出函數定義如下:
          function log(msg, time) {
            return new Promise((resolve)=> {
              setTimeout(()=> {
                console.log(msg);
                resolve();
              }, time);
            });
          }
          

          則下面三段代碼輸出的結果是:

          // 第一段代碼:
          (async ()=> {
            for (let i=0; i < 5; i++) {
              await log(i, 1000);
            }
          })();
          
          // 第二段代碼:
          (async ()=> {
            [ 1, 2, 3, 4 ].forEach(async (i)=> {
              await log(i, 1000);
            });
          })();
          
          // 第三段代碼:
          (async ()=> {
            for (const i of [ 1, 2, 3, 4 ]) {
              await log(i, 1000);
            }
          })();
          

          原型與原型鏈

          關于原型JS:看完這篇文章,徹底了解 “原型” & “this”

          傳送門: 原型與原型鏈題目解析[4]

          1. 下面程序的輸出結果依次是?
          function Fn1(name) {
              if(name){
              this.name=name;
              }
          }
          Fn1.prototype.name="jack"
          let a=new Fn1();
          console.log('a:', a.name);
          
          function Fn2(name) {
              this.name=name;
          }
          Fn2.prototype.name="jack"
          let b=new Fn2();
          console.log('b:', b.name);
          
          1. 下面程序的輸出結果是?
          var Foo=(function() {
              var x=0;
              function Foo() {}
              Foo.prototype.increment=function() {
                  ++x;
                  console.log(x);
              };
              return Foo;
          })();
           
          var a=new Foo();
          a.increment();
          a.increment();
          var b=new Foo();
          a.increment();
          
          1. 下面程序的輸出結果是?
          var name='Jay'
          function Person(name){
              this.name=name;
              console.log(this.name)
          }
          var a=Person('Tom')
          console.log(name)
          console.log(a)
          var b=new Person('Michael')
          console.log(b)
          
          1. 請表述以下代碼的執行結果和原因
          class A{}
          class B extends A{}
          const a=new A()
          const b=new B()
          a.__proto__
          b.__proto__
          B. __proto__
          B. prototype.__proto__
          b.__proto__.__proto__
          
          1. 請表述以下代碼的執行結果和原因
          function test() {           
              getName=function() { 
                  Promise.resolve().then(()=> console.log(0)); 
                  console.log(1);               
              };
          
              return this; 
          }
          test.getName=function() { 
               setTimeout(()=> console.log(2), 0); 
               console.log(3);               
          };
          test.prototype.getName=function() {    
          
               console.log(4); 
          };       
          var getName=function() { 
               console.log(5);             
          };
          function getName() {
          
               console.log(6); 
          }      
                
          test.getName(); 
          getName(); 
          test().getName(); 
          getName();  
          new test.getName();
          new test().getName();
          new new test().getName();
          
          
          1. 請表述以下代碼的執行結果和原因
          var tmp={};
          var A=function() {};
          A. prototype=tmp;
          
          var a=new A();
          A. prototype={};
          
          var b=Object.create(tmp);
          b.constructor=A. constructor;
          
          console.log(a instanceof A);
          console.log(b instanceof A);
          
          
          1. 下面程序的執行結果是:
          function Foo(){}
          Foo.prototype.z=3;
          var obj=new Foo();
          console.info(obj.z)
          obj.z=10;
          console.info(obj.z);
          delete obj.z;
          console.info(obj.z);
          
          1. 下面程序的執行結果是:
          const Book={
            price: 32
          }
          const book=Object.create(Book);
          book.type='Math';
          delete book.price;
          delete book.type;
          console.log(book.price);
          console.log(book.type);
          

          作用域與預編譯

          1. 下面的程序會報錯嗎?如果不會,輸出結果分別是多少?
          function sayHello() {
              console.log(name);
              console.log(age);
              var name="Tom";
              let age=18;
          } 
          sayHello();
          
          1. 下面的程序i的打印結果分別是多少?
          for (var i=0; i < 3; i++) {
              setTimeout(_=> {
                  console.log(i)
              })
          }
          
          for (let i=0; i < 3; i++) {
              setTimeout(_=> {
                  console.log(i)
              })
          }
          
          1. 下面程序的輸出結果是:
          console.log(a);
          var a='a';
          console.log(b);
          let b='b';
          
          1. 下面程序的輸出結果是:
          var foo="Hello";
          (function(){
              var bar=" World";
              alert(foo + bar);
          })();
          alert(foo + bar);
          
          1. 下面程序的輸出結果是:
          var a=10;
          (function () {
              console.log(a)
              a=5
              console.log(window.a)
              var a=20;
              console.log(a)
          })()
          
          1. 下面代碼的輸出結果是:
          const a=10
          function runFunction() {
              const a=20
              console.log('inside', a)
          }
          runFunction()
          console.log('outside', a)
          
          1. 請描述打印結果并說明原因
          "use strict"
          var name='Jay'
          var person={
              name: 'Wang',
              pro: {
                  name: 'Michael',
                  getName: function () {
                      return this.name
                  }
              }
          }
          console.log(person.pro.getName)
          var people=person.pro.getName
          console.log(people())
          
          1. 下面程序的結果是:
          <ul>
              <li>1</li>
              <li>2</li>
              <li>3</li>
              <li>4</li>
          </ul>
          <script>
          var elements=document.getElementsByTagName("li");
          for (var i=0;i<elements.length;i++){
              elements[i].onclick=function( ){
              alert(i); 
              };
          }
          
          1. 下面程序的輸出結果是
          compute(10,100);
          var compute=function(A,B) {
              console.info(A * B) ;
          };
          function compute(A,B){
              console.info(A + B);
          }
          function compute(A,B){
              console.info((A + B)*2);
          }
          compute(2,10);
          
          
          1. 下面程序的執行結果是:
          meili()
          function meili() {
              console.log("meili")
          }
          mogu()
          var mogu=function() {
              console.log("mogu")
          }
          
          1. 下面兩個代碼片段輸出結果有什么區別?為什么?
          // 片段1
          check('first');
          function check(ars){
              console.log(ars);
          }
          // 片段2
          check('second');
          var check=function(ars){
              console.log(ars);
          }
          

          ES6

          對象

          1. 下面代碼的輸出結果是?
          const student={name: 'ZhangSan'}
          Object.defineProperty(student, 'age', {value: 22})
          console.log(student)
          console.log(Object.keys(student))
          

          generator

          1. 下列程序的輸出結果是多少?為什么?
          function * cb(x, y) {
              for(let i=Math.ceil(x); i <=y; i++) {
                  yield i;
              }
          }
          
          var a=cb(6, 9);
          console.log(a.next());
          console.log(a.next());
          

          擴展運算符

          1. 下面程序的輸出結果是:
          function fn(...args) {
            console.log(typeof args);
          }
          fn(21);
          

          promise

          Promise.reject(0)
                 .catch(e=> e)
                 .catch(e=> console.log(e))
          

          class

          1. 請寫出下面ES6代碼編譯后所生成的ES5代碼
          class Person {
               constructor (name) {
                    this.name=name;
               }
               greet () {
                    console.log(`Hi, my name is ${this.name}`);
               }
               greetDelay (time) {
                    setTimeout(()=> {
                         console.log(`Hi, my name is ${this.name}`);
                    }, time);
               }
          }
          
          

          標簽模板

          1. 下面程序的輸出結果是多少?
          function getPersonInfo (one, two, three) {
              console.log(one)
              console.log(two)
              console.log(three)
          }
          const person='Lydia'
          const age=21
          getPersonInfo `${person} is ${age} years old`
          

          module

          1. 請寫出index里面的輸出結果
          // module.js
          export default ()=> "Hello world"
          export const name="nowcoder"
          // index.js
          import * as data from "./module"
          console.log(data)
          
          
          1. 有a.js和b.js兩個文件,請寫出b文件中代碼的輸出
          // a.js
          let a=1
          let b={}
          setTimeout(()=> {    
          a=2    
          b.b=2
          }, 100)
          module.exports={ a, b }
          
          // b.js
          const a=require('./a')
          console.log(a.a)
          console.log(a.b)
          setTimeout(()=> {    
              console.log(a.a)    
              console.log(a.b)
          }, 500)
          
          

          其他

          1. 輸出結果是:
          <div id="box1">
              <div id="box2">
                  content
              </div>
          </div>
          <script>
          const $=document.querySelector.bind(document);
          const box1=$('#box1');
          const box2=$('#box2');
          
          box1.addEventListener('click', ()=>{
              console.log('box1 true');
          }, true);
          
          box1.addEventListener('click', ()=>{
              console.log('box1 false');
          }, false);
          
          box2.addEventListener('click', ()=>{
              console.log('box2 true');
          }, true);
          
          box2.addEventListener('click', ()=>{
              console.log('box2 false');
          }, false);
          </script>
          
          1. 輸出結果是:
          $(function () { 
              function fn1( value ) {
                  alert( value );
              }
              function fn2( value ) {
                  fn1("A");
                  return false;
              }
              var callbacks=$.Callbacks();
              callbacks.add( fn1 ); 
              callbacks.fire( "B" );
              callbacks.add( fn2 ); 
              callbacks.fire( "C" );
          })
          
          1. 實現在p元素后添加“Hello World!”,則橫線處應使用的方法為( )?
          
          <html>
              <head>
                  <script type="text/javascript" src="/jquery/jquery.js"></script>
                  <script type="text/javascript">
                      $(document).ready(function(){
                          $("button").click(function(){
                              $("<b>Hello World!</b>").______("p");
                          });
                      });
                  </script>
              </head>
              <body>
                  <p>This is a paragraph.</p>
                  <p>This is another paragraph.</p>
                  <button>在每個p元素的結尾添加內容</button>
              </body>
          </html>
          
          1. 輸出結果是:
          <div id="box1">
            <div id="box2">
              content
            </div>
          </div>
          <script>
          const $=document.querySelector.bind(document);
          const box1=$('#box1');
          const box2=$('#box2');
          box1.addEventListener('click', ()=> {
            console.log('box1 true');
          }, true);
          box1.addEventListener('click', ()=> {
            console.log('box1 false');
          }, false);
          box2.addEventListener('click', ()=> {
            console.log('box2 true');
          }, true);
          box2.addEventListener('click', ()=> {
            console.log('box2 false');
          }, false);
          </script>
          
          1. 請選擇下面代碼輸出1的次數

          小夕:https://juejin.im/post/5cab0c45f265da2513734390

          1. 基本類型有哪幾種?null 是對象嗎?基本數據類型和復雜數據類型存儲有什么區別?

          • 基本類型有6種,分別是undefined,null,bool,string,number,symbol(ES6新增)。
          • 雖然 typeof null 返回的值是 object,但是null不是對象,而是基本數據類型的一種。
          • 基本數據類型存儲在棧內存,存儲的是值。
          • 復雜數據類型的值存儲在堆內存,地址(指向堆中的值)存儲在棧內存。當我們把對象賦值給另外一個變量的時候,復制的是地址,指向同一塊內存空間,當其中一個對象改變時,另一個對象也會變化。

          2. typeof 是否正確判斷類型? instanceof呢? instanceof 的實現原理是什么?

          首先 typeof 能夠正確的判斷基本數據類型,但是除了 null, typeof null輸出的是對象。

          但是對象來說,typeof 不能正確的判斷其類型, typeof 一個函數可以輸出 'function',而除此之外,輸出的全是 object,這種情況下,我們無法準確的知道對象的類型。

          instanceof可以準確的判斷復雜數據類型,但是不能正確判斷基本數據類型。

          instanceof 是通過原型鏈判斷的,A instanceof B, 在A的原型鏈中層層查找,是否有原型等于B.prototype,如果一直找到A的原型鏈的頂端(null;即Object.__proto__.__proto__),仍然不等于B.prototype,那么返回false,否則返回true.

          instanceof的實現代碼:

          // L instanceof R
          function instance_of(L, R) {//L 表示左表達式,R 表示右表達式
           var O=R.prototype;// 取 R 的顯式原型
           L=L.__proto__; // 取 L 的隱式原型
           while (true) { 
           if (L===null) //已經找到頂層
           return false; 
           if (O===L) //當 O 嚴格等于 L 時,返回 true
           return true; 
           L=L.__proto__; //繼續向上一層原型鏈查找
           } 
          }
          

          3. for of , for in 和 forEach,map 的區別。

          • for...of循環:具有 iterator 接口,就可以用for...of循環遍歷它的成員(屬性值)。for...of循環可以使用的范圍包括數組、Set 和 Map 結構、某些類似數組的對象、Generator 對象,以及字符串。for...of循環調用遍歷器接口,數組的遍歷器接口只返回具有數字索引的屬性。對于普通的對象,for...of結構不能直接使用,會報錯,必須部署了 Iterator 接口后才能使用。可以中斷循環。
          • for...in循環:遍歷對象自身的和繼承的可枚舉的屬性, 不能直接獲取屬性值。可以中斷循環。
          • forEach: 只能遍歷數組,不能中斷,沒有返回值(或認為返回值是undefined)。
          • map: 只能遍歷數組,不能中斷,返回值是修改后的數組。

          PS: Object.keys():返回給定對象所有可枚舉屬性的字符串數組。

          關于forEach是否會改變原數組的問題,有些小伙伴提出了異議,為此我寫了代碼測試了下(注意數組項是復雜數據類型的情況)。 除了forEach之外,map等API,也有同樣的問題。

          let arry=[1, 2, 3, 4];
          arry.forEach((item)=> {
           item *=10;
          });
          console.log(arry); //[1, 2, 3, 4]
          arry.forEach((item)=> {
           arry[1]=10; //直接操作數組
          });
          console.log(arry); //[ 1, 10, 3, 4 ]
          let arry2=[
           { name: "Yve" },
           { age: 20 }
          ];
          arry2.forEach((item)=> {
           item.name=10;
          });
          console.log(arry2);//[ { name: 10 }, { age: 20, name: 10 } ]
          

          如還不了解 iterator 接口或 for...of, 請先閱讀ES6文檔: Iterator 和 for...of 循環

          更多細節請戳: github.com/YvetteLau/B…


          4. 如何判斷一個變量是不是數組?

          • 使用 Array.isArray 判斷,如果返回 true, 說明是數組
          • 使用 instanceof Array 判斷,如果返回true, 說明是數組
          • 使用 Object.prototype.toString.call 判斷,如果值是 [object Array], 說明是數組
          • 通過 constructor 來判斷,如果是數組,那么 arr.constructor===Array. (不準確,因為我們可以指定 obj.constructor=Array)
          function fn() {
           console.log(Array.isArray(arguments)); //false; 因為arguments是類數組,但不是數組
           console.log(Array.isArray([1,2,3,4])); //true
           console.log(arguments instanceof Array); //fasle
           console.log([1,2,3,4] instanceof Array); //true
           console.log(Object.prototype.toString.call(arguments)); //[object Arguments]
           console.log(Object.prototype.toString.call([1,2,3,4])); //[object Array]
           console.log(arguments.constructor===Array); //false
           arguments.constructor=Array;
           console.log(arguments.constructor===Array); //true
           console.log(Array.isArray(arguments)); //false
          }
          fn(1,2,3,4);
          

          5. 類數組和數組的區別是什么?

          類數組:

          1)擁有length屬性,其它屬性(索引)為非負整數(對象中的索引會被當做字符串來處理);

          2)不具有數組所具有的方法;

          類數組是一個普通對象,而真實的數組是Array類型。

          常見的類數組有: 函數的參數 arguments, DOM 對象列表(比如通過 document.querySelectorAll 得到的列表), jQuery 對象 (比如 $("div")).

          類數組可以轉換為數組:

          //第一種方法
          Array.prototype.slice.call(arrayLike, start);
          //第二種方法
          [...arrayLike];
          //第三種方法:
          Array.from(arrayLike);
          

          PS: 任何定義了遍歷器(Iterator)接口的對象,都可以用擴展運算符轉為真正的數組。

          Array.from方法用于將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象。


          6.==和===有什么區別?

          ===不需要進行類型轉換,只有類型相同并且值相等時,才返回 true.

          ==如果兩者類型不同,首先需要進行類型轉換。具體流程如下:

          1. 首先判斷兩者類型是否相同,如果相等,判斷值是否相等.
          2. 如果類型不同,進行類型轉換
          3. 判斷比較的是否是 null 或者是 undefined, 如果是, 返回 true .
          4. 判斷兩者類型是否為 string 和 number, 如果是, 將字符串轉換成 number
          5. 判斷其中一方是否為 boolean, 如果是, 將 boolean 轉為 number 再進行判斷
          6. 判斷其中一方是否為 object 且另一方為 string、number 或者 symbol , 如果是, 將 object 轉為原始類型再進行判斷
          let person1={
           age: 25
          }
          let person2=person1;
          person2.gae=20;
          console.log(person1===person2); //true,注意復雜數據類型,比較的是引用地址
          

          思考: []==![]

          我們來分析一下: []==![] 是true還是false?

          1. 首先,我們需要知道 ! 優先級是高于==(更多運算符優先級可查看: 運算符優先級)
          2. ![] 引用類型轉換成布爾值都是true,因此![]的是false
          3. 根據上面的比較步驟中的第五條,其中一方是 boolean,將 boolean 轉為 number 再進行判斷,false轉換成 number,對應的值是 0.
          4. 根據上面比較步驟中的第六條,有一方是 number,那么將object也轉換成Number,空數組轉換成數字,對應的值是0.(空數組轉換成數字,對應的值是0,如果數組中只有一個數字,那么轉成number就是這個數字,其它情況,均為NaN)
          5. 0==0; 為true

          7. ES6中的class和ES5的類有什么區別?

          1. ES6 class 內部所有定義的方法都是不可枚舉的;
          2. ES6 class 必須使用 new 調用;
          3. ES6 class 不存在變量提升;
          4. ES6 class 默認即是嚴格模式;
          5. ES6 class 子類必須在父類的構造函數中調用super(),這樣才有this對象;ES5中類繼承的關系是相反的,先有子類的this,然后用父類的方法應用在this上。

          8. 數組的哪些API會改變原數組?

          修改 原數組的API有:

          splice/reverse/fill/copyWithin/sort/push/pop/unshift/shift

          不修改 原數組的API有:

          slice/map/forEach/every/filter/reduce/entries/find

          注: 數組的每一項是簡單數據類型,且未直接操作數組的情況下(稍后會對此題重新作答)。


          9. let、const 以及 var 的區別是什么?

          • let 和 const 定義的變量不會出現變量提升,而 var 定義的變量會提升。
          • let 和 const 是JS中的塊級作用域
          • let 和 const 不允許重復聲明(會拋出錯誤)
          • let 和 const 定義的變量在定義語句之前,如果使用會拋出錯誤(形成了暫時性死區),而 var 不會。
          • const 聲明一個只讀的常量。一旦聲明,常量的值就不能改變(如果聲明是一個對象,那么不能改變的是對象的引用地址)

          10. 在JS中什么是變量提升?什么是暫時性死區?

          變量提升就是變量在聲明之前就可以使用,值為undefined。

          在代碼塊內,使用 let/const 命令聲明變量之前,該變量都是不可用的(會拋出錯誤)。這在語法上,稱為“暫時性死區”。暫時性死區也意味著 typeof 不再是一個百分百安全的操作。

          typeof x; // ReferenceError(暫時性死區,拋錯)
          let x;
          復制代碼
          typeof y; // 值是undefined,不會報錯
          

          暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量。


          11. 如何正確的判斷this? 箭頭函數的this是什么?

          this的綁定規則有四種:默認綁定,隱式綁定,顯式綁定,new綁定.

          1. 函數是否在 new 中調用(new綁定),如果是,那么 this 綁定的是新創建的對象【前提是構造函數中沒有返回對象或者是function,否則this指向返回的對象/function】。
          2. 函數是否通過 call,apply 調用,或者使用了 bind (即硬綁定),如果是,那么this綁定的就是指定的對象。
          3. 函數是否在某個上下文對象中調用(隱式綁定),如果是的話,this 綁定的是那個上下文對象。一般是 obj.foo()
          4. 如果以上都不是,那么使用默認綁定。如果在嚴格模式下,則綁定到 undefined,否則綁定到全局對象。
          5. 如果把 null 或者 undefined 作為 this 的綁定對象傳入 call、apply 或者 bind, 這些值在調用時會被忽略,實際應用的是默認綁定規則。
          6. 箭頭函數沒有自己的 this, 它的this繼承于上一層代碼塊的this。

          測試下是否已經成功Get了此知識點(瀏覽器執行環境):

          var number=5;
          var obj={
           number: 3,
           fn1: (function () {
           var number;
           this.number *=2;
           number=number * 2;
           number=3;
           return function () {
           var num=this.number;
           this.number *=2;
           console.log(num);
           number *=3;
           console.log(number);
           }
           })()
          }
          var fn1=obj.fn1;
          fn1.call(null);
          obj.fn1();
          console.log(window.number);
          


          12. 詞法作用域和this的區別。

          • 詞法作用域是由你在寫代碼時將變量和塊作用域寫在哪里來決定的
          • this 是在調用時被綁定的,this 指向什么,完全取決于函數的調用位置.

          13. 談談你對JS執行上下文棧和作用域鏈的理解。

          執行上下文就是當前 JavaScript 代碼被解析和執行時所在環境, JS執行上下文棧可以認為是一個存儲函數調用的棧結構,遵循先進后出的原則。

          • JavaScript執行在單線程上,所有的代碼都是排隊執行。
          • 一開始瀏覽器執行全局的代碼時,首先創建全局的執行上下文,壓入執行棧的頂部。
          • 每當進入一個函數的執行就會創建函數的執行上下文,并且把它壓入執行棧的頂部。當前函數執行-完成后,當前函數的執行上下文出棧,并等待垃圾回收。
          • 瀏覽器的JS執行引擎總是訪問棧頂的執行上下文。
          • 全局上下文只有唯一的一個,它在瀏覽器關閉時出棧。

          作用域鏈: 無論是 LHS 還是 RHS 查詢,都會在當前的作用域開始查找,如果沒有找到,就會向上級作用域繼續查找目標標識符,每次上升一個作用域,一直到全局作用域為止。


          14. 什么是閉包?閉包的作用是什么?閉包有哪些使用場景?

          閉包是指有權訪問另一個函數作用域中的變量的函數,創建閉包最常用的方式就是在一個函數內部創建另一個函數。

          閉包的作用有:

          1. 封裝私有變量
          2. 模仿塊級作用域(ES5中沒有塊級作用域)
          3. 實現JS的模塊

          15. call、apply有什么區別?call,aplly和bind的內部是如何實現的?

          call 和 apply 的功能相同,區別在于傳參的方式不一樣:

          • fn.call(obj, arg1, arg2, ...),調用一個函數, 具有一個指定的this值和分別地提供的參數(參數的列表)。
          • fn.apply(obj, [argsArray]),調用一個函數,具有一個指定的this值,以及作為一個數組(或類數組對象)提供的參數。

          call核心:

          • 將函數設為傳入參數的屬性
          • 指定this到函數并傳入給定參數執行函數
          • 如果不傳入參數或者參數為null,默認指向為 window / global
          • 刪除參數上的函數
          Function.prototype.call=function (context) {
           /** 如果第一個參數傳入的是 null 或者是 undefined, 那么指向this指向 window/global */
           /** 如果第一個參數傳入的不是null或者是undefined, 那么必須是一個對象 */
           if (!context) {
           //context為null或者是undefined
           context=typeof window==='undefined' ? global : window;
           }
           context.fn=this; //this指向的是當前的函數(Function的實例)
           let rest=[...arguments].slice(1);//獲取除了this指向對象以外的參數, 空數組slice后返回的仍然是空數組
           let result=context.fn(...rest); //隱式綁定,當前函數的this指向了context.
           delete context.fn;
           return result;
          }
          //測試代碼
          var foo={
           name: 'Selina'
          }
          var name='Chirs';
          function bar(job, age) {
           console.log(this.name);
           console.log(job, age);
          }
          bar.call(foo, 'programmer', 20);
          // Selina programmer 20
          bar.call(null, 'teacher', 25);
          // 瀏覽器環境: Chirs teacher 25; node 環境: undefined teacher 25
          

          apply:

          apply的實現和call很類似,但是需要注意他們的參數是不一樣的,apply的第二個參數是數組或類數組.

          Function.prototype.apply=function (context, rest) {
           if (!context) {
           //context為null或者是undefined時,設置默認值
           context=typeof window==='undefined' ? global : window;
           }
           context.fn=this;
           let result;
           if(rest===undefined || rest===null) {
           //undefined 或者 是 null 不是 Iterator 對象,不能被 ...
           result=context.fn(rest);
           }else if(typeof rest==='object') {
           result=context.fn(...rest);
           }
           delete context.fn;
           return result;
          }
          var foo={
           name: 'Selina'
          }
          var name='Chirs';
          function bar(job, age) {
           console.log(this.name);
           console.log(job, age);
          }
          bar.apply(foo, ['programmer', 20]);
          // Selina programmer 20
          bar.apply(null, ['teacher', 25]);
          // 瀏覽器環境: Chirs programmer 20; node 環境: undefined teacher 25
          

          bind

          bind 和 call/apply 有一個很重要的區別,一個函數被 call/apply 的時候,會直接調用,但是 bind 會創建一個新函數。當這個新函數被調用時,bind() 的第一個參數將作為它運行時的 this,之后的一序列參數將會在傳遞的實參前傳入作為它的參數。

          Function.prototype.bind=function(context) {
           if(typeof this !=="function"){
           throw new TypeError("not a function");
           }
           let self=this;
           let args=[...arguments].slice(1);
           function Fn() {};
           Fn.prototype=this.prototype;
           let bound=function() {
           let res=[...args, ...arguments]; //bind傳遞的參數和函數調用時傳遞的參數拼接
           context=this instanceof Fn ? this : context || this;
           return self.apply(context, res);
           }
           //原型鏈
           bound.prototype=new Fn();
           return bound;
          }
          var name='Jack';
          function person(age, job, gender){
           console.log(this.name , age, job, gender);
          }
          var Yve={name : 'Yvette'};
          let result=person.bind(Yve, 22, 'enginner')('female');	
          


          16. new的原理是什么?通過new的方式創建對象和通過字面量創建有什么區別?

          new:

          1. 創建一個新對象。
          2. 這個新對象會被執行[[原型]]連接。
          3. 屬性和方法被加入到 this 引用的對象中。并執行了構造函數中的方法.
          4. 如果函數沒有返回其他對象,那么this指向這個新對象,否則this指向構造函數中返回的對象。
          function new(func) {
           let target={};
           target.__proto__=func.prototype;
           let res=func.call(target);
           if (res && typeof(res)=="object" || typeof(res)=="function") {
           	return res;
           }
           return target;
          }
          

          字面量創建對象,不會調用 Object構造函數, 簡潔且性能更好;

          new Object() 方式創建對象本質上是方法調用,涉及到在proto鏈中遍歷該方法,當找到該方法后,又會生產方法調用必須的 堆棧信息,方法調用結束后,還要釋放該堆棧,性能不如字面量的方式。

          通過對象字面量定義對象時,不會調用Object構造函數。


          17. 談談你對原型的理解?

          在 JavaScript 中,每當定義一個對象(函數也是對象)時候,對象中都會包含一些預定義的屬性。其中每個函數對象都有一個prototype 屬性,這個屬性指向函數的原型對象。使用原型對象的好處是所有對象實例共享它所包含的屬性和方法。


          18. 什么是原型鏈?【原型鏈解決的是什么問題?】

          原型鏈解決的主要是繼承問題。

          每個對象擁有一個原型對象,通過 proto (讀音: dunder proto) 指針指向其原型對象,并從中繼承方法和屬性,同時原型對象也可能擁有原型,這樣一層一層,最終指向 null(Object.proptotype.__proto__ 指向的是null)。這種關系被稱為原型鏈 (prototype chain),通過原型鏈一個對象可以擁有定義在其他對象中的屬性和方法。

          構造函數 Parent、Parent.prototype 和 實例 p 的關系如下:(p.__proto__===Parent.prototype)

          19. prototype 和 __proto__ 區別是什么?

          prototype是構造函數的屬性。

          __proto__ 是每個實例都有的屬性,可以訪問 [[prototype]] 屬性。

          實例的__proto__ 與其構造函數的prototype指向的是同一個對象。

          function Student(name) {
           this.name=name;
          }
          Student.prototype.setAge=function(){
           this.age=20;
          }
          let Jack=new Student('jack');
          console.log(Jack.__proto__);
          //console.log(Object.getPrototypeOf(Jack));;
          console.log(Student.prototype);
          console.log(Jack.__proto__===Student.prototype);//true
          

          20. 使用ES5實現一個繼承?

          組合繼承(最常用的繼承方式)

          function SuperType(name) {
           this.name=name;
           this.colors=['red', 'blue', 'green'];
          }
          SuperType.prototype.sayName=function() {
           console.log(this.name);
          }
          function SubType(name, age) {
           SuperType.call(this, name);
           this.age=age;
          }
          SubType.prototype=new SuperType();
          SubType.prototype.constructor=SubType;
          SubType.prototype.sayAge=function() {
           console.log(this.age);
          }
          
          

          其它繼承方式實現,可以參考《JavaScript高級程序設計》


          21. 什么是深拷貝?深拷貝和淺拷貝有什么區別?

          淺拷貝是指只復制第一層對象,但是當對象的屬性是引用類型時,實質復制的是其引用,當引用指向的值改變時也會跟著變化。

          深拷貝復制變量值,對于非基本類型的變量,則遞歸至基本類型變量后,再復制。深拷貝后的對象與原來的對象是完全隔離的,互不影響,對一個對象的修改并不會影響另一個對象。

          實現一個深拷貝:

          function deepClone(obj) { //遞歸拷貝
           if(obj===null) return null; //null 的情況
           if(obj instanceof RegExp) return new RegExp(obj);
           if(obj instanceof Date) return new Date(obj);
           if(typeof obj !=='object') {
           //如果不是復雜數據類型,直接返回
           return obj;
           }
           /**
           * 如果obj是數組,那么 obj.constructor 是 [Function: Array]
           * 如果obj是對象,那么 obj.constructor 是 [Function: Object]
           */
           let t=new obj.constructor();
           for(let key in obj) {
           //如果 obj[key] 是復雜數據類型,遞歸
           t[key]=deepClone(obj[key]);
           }
           return t;
          }
          


          22. 防抖和節流的區別是什么?防抖和節流的實現。

          防抖和節流的作用都是防止函數多次調用。區別在于,假設一個用戶一直觸發這個函數,且每次觸發函數的間隔小于設置的時間,防抖的情況下只會調用一次,而節流的情況會每隔一定時間調用一次函數。

          防抖(debounce): n秒內函數只會執行一次,如果n秒內高頻事件再次被觸發,則重新計算時間

          function debounce(func, wait, immediate=true) {
           let timer;
           // 延遲執行函數
           const later=(context, args)=> setTimeout(()=> {
           timer=null;// 倒計時結束
           if (!immediate) {
           func.apply(context, args);
           //執行回調
           context=args=null;
           }
           }, wait);
           let debounced=function (...params) {
           let context=this;
           let args=params;
           if (!timer) {
           timer=later(context, args);
           if (immediate) {
           //立即執行
           func.apply(context, args);
           }
           } else {
           clearTimeout(timer);
           //函數在每個等待時延的結束被調用
           timer=later(context, args);
           }
           }
           debounced.cancel=function () {
           clearTimeout(timer);
           timer=null;
           };
           return debounced;
          };
          

          防抖的應用場景:

          • 每次 resize/scroll 觸發統計事件
          • 文本輸入的驗證(連續輸入文字后發送 AJAX 請求進行驗證,驗證一次就好)

          節流(throttle): 高頻事件在規定時間內只會執行一次,執行一次后,只有大于設定的執行周期后才會執行第二次。

          //underscore.js
          function throttle(func, wait, options) {
           var timeout, context, args, result;
           var previous=0;
           if (!options) options={};
           var later=function () {
           previous=options.leading===false ? 0 : Date.now() || new Date().getTime();
           timeout=null;
           result=func.apply(context, args);
           if (!timeout) context=args=null;
           };
           var throttled=function () {
           var now=Date.now() || new Date().getTime();
           if (!previous && options.leading===false) previous=now;
           var remaining=wait - (now - previous);
           context=this;
           args=arguments;
           if (remaining <=0 || remaining > wait) {
           if (timeout) {
           clearTimeout(timeout);
           timeout=null;
           }
           previous=now;
           result=func.apply(context, args);
           if (!timeout) context=args=null;
           } else if (!timeout && options.trailing !==false) {
           // 判斷是否設置了定時器和 trailing
           timeout=setTimeout(later, remaining);
           }
           return result;
           };
           throttled.cancel=function () {
           clearTimeout(timeout);
           previous=0;
           timeout=context=args=null;
           };
           return throttled;
          };
          

          函數節流的應用場景有:

          • DOM 元素的拖拽功能實現(mousemove)
          • 射擊游戲的 mousedown/keydown 事件(單位時間只能發射一顆子彈)
          • 計算鼠標移動的距離(mousemove)
          • Canvas 模擬畫板功能(mousemove)
          • 搜索聯想(keyup)
          • 監聽滾動事件判斷是否到頁面底部自動加載更多:給 scroll 加了 debounce 后,只有用戶停止滾動后,才會判斷是否到了頁面底部;如果是 throttle 的話,只要頁面滾動就會間隔一段時間判斷一次

          23. 取數組的最大值(ES5、ES6)

          // ES5 的寫法
          Math.max.apply(null, [14, 3, 77, 30]);
          // ES6 的寫法
          Math.max(...[14, 3, 77, 30]);
          // reduce
          [14,3,77,30].reduce((accumulator, currentValue)=>{
           return accumulator=accumulator > currentValue ? accumulator : currentValue
          });
          

          24. ES6新的特性有哪些?

          1. 新增了塊級作用域(let,const)
          2. 提供了定義類的語法糖(class)
          3. 新增了一種基本數據類型(Symbol)
          4. 新增了變量的解構賦值
          5. 函數參數允許設置默認值,引入了rest參數,新增了箭頭函數
          6. 數組新增了一些API,如 isArray / from / of 方法;數組實例新增了 entries(),keys() 和 values() 等方法
          7. 對象和數組新增了擴展運算符
          8. ES6 新增了模塊化(import/export)
          9. ES6 新增了 Set 和 Map 數據結構
          10. ES6 原生提供 Proxy 構造函數,用來生成 Proxy 實例
          11. ES6 新增了生成器(Generator)和遍歷器(Iterator)

          25. setTimeout倒計時為什么會出現誤差?

          setTimeout() 只是將事件插入了“任務隊列”,必須等當前代碼(執行棧)執行完,主線程才會去執行它指定的回調函數。要是當前代碼消耗時間很長,也有可能要等很久,所以并沒辦法保證回調函數一定會在 setTimeout() 指定的時間執行。所以, setTimeout() 的第二個參數表示的是最少時間,并非是確切時間。

          HTML5標準規定了 setTimeout() 的第二個參數的最小值不得小于4毫秒,如果低于這個值,則默認是4毫秒。在此之前。老版本的瀏覽器都將最短時間設為10毫秒。另外,對于那些DOM的變動(尤其是涉及頁面重新渲染的部分),通常是間隔16毫秒執行。這時使用 requestAnimationFrame() 的效果要好于 setTimeout();


          26. 為什么 0.1 + 0.2 !=0.3 ?

          0.1 + 0.2 !=0.3 是因為在進制轉換和進階運算的過程中出現精度損失。

          下面是詳細解釋:

          JavaScript使用 Number 類型表示數字(整數和浮點數),使用64位表示一個數字。

          圖片說明:

          • 第0位:符號位,0表示正數,1表示負數(s)
          • 第1位到第11位:儲存指數部分(e)
          • 第12位到第63位:儲存小數部分(即有效數字)f

          計算機無法直接對十進制的數字進行運算, 需要先對照 IEEE 754 規范轉換成二進制,然后對階運算。

          1.進制轉換

          0.1和0.2轉換成二進制后會無限循環

          0.1 -> 0.0001100110011001...(無限循環)
          0.2 -> 0.0011001100110011...(無限循環)
          

          但是由于IEEE 754尾數位數限制,需要將后面多余的位截掉,這樣在進制之間的轉換中精度已經損失。

          2.對階運算

          由于指數位數不相同,運算時需要對階運算 這部分也可能產生精度損失。

          按照上面兩步運算(包括兩步的精度損失),最后的結果是

          0.0100110011001100110011001100110011001100110011001100

          結果轉換成十進制之后就是 0.30000000000000004。

          27. promise 有幾種狀態, Promise 有什么優缺點 ?

          promise有三種狀態: fulfilled, rejected, pending.

          Promise 的優點:

          1. 一旦狀態改變,就不會再變,任何時候都可以得到這個結果
          2. 可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數

          Promise 的缺點:

          1. 無法取消 Promise
          2. 當處于pending狀態時,無法得知目前進展到哪一個階段

          28. Promise構造函數是同步還是異步執行,then中的方法呢 ?promise如何實現then處理 ?

          Promise的構造函數是同步執行的。then 中的方法是異步執行的。


          29. Promise和setTimeout的區別 ?

          Promise 是微任務,setTimeout 是宏任務,同一個事件循環中,promise.then總是先于 setTimeout 執行。


          30. 如何實現 Promise.all ?

          要實現 Promise.all,首先我們需要知道 Promise.all 的功能:

          1. 如果傳入的參數是一個空的可迭代對象,那么此promise對象回調完成(resolve),只有此情況,是同步執行的,其它都是異步返回的。
          2. 如果傳入的參數不包含任何 promise,則返回一個異步完成. promises 中所有的promise都“完成”時或參數中不包含 promise 時回調完成。
          3. 如果參數中有一個promise失敗,那么Promise.all返回的promise對象失敗
          4. 在任何情況下,Promise.all 返回的 promise 的完成狀態的結果都是一個數組
          Promise.all=function (promises) {
           return new Promise((resolve, reject)=> {
           let index=0;
           let result=[];
           if (promises.length===0) {
           resolve(result);
           } else {
           function processValue(i, data) {
           result[i]=data;
           if (++index===promises.length) {
           resolve(result);
           }
           }
           for (let i=0; i < promises.length; i++) {
           //promises[i] 可能是普通值
           Promise.resolve(promises[i]).then((data)=> {
           processValue(i, data);
           }, (err)=> {
           reject(err);
           return;
           });
           }
           }
           });
          }
          


          31.如何實現 Promise.finally ?

          不管成功還是失敗,都會走到finally中,并且finally之后,還可以繼續then。并且會將值原封不動的傳遞給后面的then.

          Promise.prototype.finally=function (callback) {
           return this.then((value)=> {
           return Promise.resolve(callback()).then(()=> {
           return value;
           });
           }, (err)=> {
           return Promise.resolve(callback()).then(()=> {
           throw err;
           });
           });
          }
          

          32. 什么是函數柯里化?實現 sum(1)(2)(3) 返回結果是1,2,3之和。

          函數柯里化是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數而且返回結果的新函數的技術。

          function sum(a) {
           return function(b) {
           return function(c) {
           return a+b+c;
           }
           }
          }
          console.log(sum(1)(2)(3)); // 6
          

          引申:實現一個curry函數,將普通函數進行柯里化:

          .Doctype作用?標準模式與兼容模式各有什么區別

          <!DOCTYPE>聲明位于位于HTML文檔中的第一行,處于 <html>標簽之前。告知瀏覽器的解析器,用什么文檔標準解析這個文檔。DOCTYPE不存在或格式不正確會導致文檔以兼容模式呈現。
          標準模式的排版 和JS運作模式都是以該瀏覽器支持的最高標準運行。在兼容模式中,頁面以寬松的向后兼容的方式顯示,模擬老式瀏覽器的行為以防止站點無法工作。

          2.HTML5 為什么只需要寫 <!DOCTYPE HTML>?

          HTML5 不基于 SGML,因此不需要對DTD進行引用,但是需要doctype來規范瀏覽器的行為(讓瀏覽器按照它們應該的方式來運行);
          而HTML4.01基于SGML,所以需要對DTD進行引用,才能告知瀏覽器文檔所使用的文檔類型。**

          3.行內元素有哪些?塊級元素有哪些? 空(void)元素有那些?

          首先:CSS規范規定,每個元素都有display屬性,確定該元素的類型,每個元素都有默認的display值,如div的display默認值為“block”,則為“塊級”元素;span默認display屬性值為“inline”,是“行內”元素
          (1)行內元素有:a b span img input select strong(強調的語氣)
          (2)塊級元素有:div ul ol li dl dt dd h1 h2 h3 h4…p
          (3)常見的空元素:


          <img><input><link><meta>
          鮮為人知的是:
          <area><base><col><command><embed><keygen><param><source><track><wbr>
          4.頁面導入樣式時,使用link和@import有什么區別?
          link屬于XHTML標簽,除了加載CSS外,還能用于定義RSS, 定義rel連接屬性等作用;而@import是CSS提供的,只能用于加載CSS;
          頁面被加載的時,link會同時被加載,而@import引用的CSS會等到頁面被加載完再加載;
          import是CSS2.1 提出的,只在IE5以上才能被識別,而link是XHTML標簽,無兼容問題;

          5.介紹一下你對瀏覽器內核的理解?

          主要分成兩部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
          渲染引擎:負責取得網頁的內容(HTML、XML、圖像等等)、整理訊息(例如加入CSS等),以及計算網頁的顯示方式,然后會輸出至顯示器或打印機。瀏覽器的內核的不同對于網頁的語法解釋會有不同,所以渲染的效果也不相同。所有網頁瀏覽器、電子郵件客戶端以及其它需要編輯、顯示網絡內容的應用程序都需要內核。
          JS引擎則:解析和執行javascript來實現網頁的動態效果。
          最開始渲染引擎和JS引擎并沒有區分的很明確,后來JS引擎越來越獨立,內核就傾向于只指渲染引擎。

          6.常見的瀏覽器內核有哪些?

          Trident內核:IE,MaxThon,TT,The World,360,搜狗瀏覽器等。[又稱MSHTML]
          Gecko內核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
          Presto內核:Opera7及以上。 [Opera內核原為:Presto,現為:Blink;]
          Webkit內核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]

          7.html5有哪些新特性、移除了那些元素?如何處理HTML5新標簽的瀏覽器兼容問題?如何區分 HTML 和 HTML5?

          • HTML5 現在已經不是 SGML 的子集,主要是關于圖像,位置,存儲,多任務等功能的增加。繪畫 canvas;
            用于媒介回放的 video 和 audio 元素;
            本地離線存儲 localStorage 長期存儲數據,瀏覽器關閉后數據不丟失;
            sessionStorage 的數據在瀏覽器關閉后自動刪除;
            語意化更好的內容元素,比如 article、footer、header、nav、section;
            表單控件,calendar、date、time、email、url、search;
            新的技術webworker, websocket, Geolocation;


          移除的元素:
          純表現的元素:basefont,big,center,font, s,strike,tt,u;
          對可用性產生負面影響的元素:frame,frameset,noframes;

          • 支持HTML5新標簽:IE8/IE7/IE6支持通過document.createElement方法產生的標簽,
            可以利用這一特性讓這些瀏覽器支持HTML5新標簽,
            瀏覽器支持新標簽后,還需要添加標簽默認的樣式。
            當然也可以直接使用成熟的框架、比如html5shim;
            <!--[if lt IE 9]>
            <scriptsrc="http://html5shim.googlecode.com/svn/trunk/html5.js"> </script>
            <![endif]-->
          • 如何區分HTML5: DOCTYPE聲明新增的結構元素功能元素
            H5新特性
            表單 畫布 音視頻 地理定位 媒體查詢 css新特性 離線緩存 本地存儲 拖拽

          8.簡述一下你對HTML語義化的理解?

          用正確的標簽做正確的事情。
          html語義化讓頁面的內容結構化,結構更清晰,便于對瀏覽器、搜索引擎解析;
          即使在沒有樣式CSS情況下也以一種文檔格式顯示,并且是容易閱讀的;
          搜索引擎的爬蟲也依賴于HTML標記來確定上下文和各個關鍵字的權重,利于SEO;
          使閱讀源代碼的人對網站更容易將網站分塊,便于閱讀維護理解。

          9.HTML5的離線儲存怎么使用,工作原理能不能解釋一下?

          在用戶沒有連網時,可以正常訪問站點或應用,在用戶與網絡連接時更新用戶機器上的緩存文件。
          原理:HTML5的離線存儲是基于一個新建的.appcache文件的緩存機制(不是存儲技術),通過這個文件上的解析清單離線存儲資源,這些資源就會像cookie一樣被存儲了下來。之后當網絡在處于離線狀態下時,瀏覽器會通過被離線存儲的數據進行頁面展示。
          如何使用
          頁面頭部像下面一樣加入一個manifest的屬性;
          在cache.manifest文件的編寫離線存儲的資源;
          CACHE MANIFEST
          #v0.11
          CACHE:
          js/app.js
          css/style.css
          NETWORK:
          resourse/logo.png
          FALLBACK:
          / /offline.html
          在離線狀態時,操作window.applicationCache進行需求實現。

          10.瀏覽器是怎么對HTML5的離線儲存資源進行管理和加載的呢?

          在線的情況下,瀏覽器發現html頭部有manifest屬性,它會請求manifest文件,如果是第一次訪問app,那么瀏覽器就會根據manifest文件的內容下載相應的資源并且進行離線存儲。如果已經訪問過app并且資源已經離線存儲了,那么瀏覽器就會使用離線的資源加載頁面,然后瀏覽器會對比新的manifest文件與舊的manifest文件,如果文件沒有發生改變,就不做任何操作,如果文件改變了,那么就會重新下載文件中的資源并進行離線存儲。
          離線的情況下,瀏覽器就直接使用離線存儲的資源。

          11.iframe有那些缺點?

          iframe會阻塞主頁面的Onload事件;
          搜索引擎的檢索程序無法解讀這種頁面,不利于SEO;
          iframe和主頁面共享連接池,而瀏覽器對相同域的連接有限制,所以會影響頁面的并行加載。
          使用iframe之前需要考慮這兩個缺點。如果需要使用iframe,最好是通過javascript
          動態給iframe添加src屬性值,這樣可以繞開以上兩個問題。

          12.Label的作用是什么?是怎么用的?

          label標簽來定義表單控制間的關系,當用戶選擇該標簽時,瀏覽器會自動將焦點轉到和標簽相關的表單控件上。

          <label for="Name">Number:</label>
          <input type=“text“name="Name" id="Name"/>
          <label>Date:<input type="text" name="B"/></label>

          13.如何實現瀏覽器內多個標簽頁之間的通信?

          WebSocket、也可以調用localstorge、cookies等本地存儲方式,還可以使用頁面的路有參數傳遞
          localstorge另一個瀏覽上下文里被添加、修改或刪除時,它都會觸發一個事件,
          我們通過監聽事件,控制它的值來進行頁面信息通信;
          14.如何在頁面上實現一個圓形的可點擊區域?
          map+area或者svg
          border-radius
          純js實現 需要求一個點在不在圓上簡單算法、獲取鼠標坐標等等

          15.title與h1的區別、b與strong的區別、i與em的區別?

          title屬性沒有明確意義只表示是個標題,H1則表示層次明確的標題,對頁面信息的抓取也有很大的影響;
          strong是標明重點內容,有語氣加強的含義,使用閱讀設備閱讀網絡時:會重讀,而是展示強調內容。
          i內容展示為斜體,em表示強調的文本;

          16.data-屬性的作用是什么?

          h5新增的屬性
          可以通過ele.dataset獲取到標簽上的data-x的屬性
          返回一個對象

          17.常見兼容性問題?

          問題:png24位的圖片在iE6瀏覽器上出現背景,

          解決:解決方案是做成PNG8.

          問題:瀏覽器默認的margin和padding不同。

          解決:方案是加一個全局的*{margin:0;padding:0;}來統一。

          問題:IE6雙邊距bug:塊屬性標簽float后,又有橫行的margin情況下,在ie6顯示margin比設置的大。浮動ie產生的雙倍距離 #box{ float:left; width:10px; margin:0 0 0 100px;}這種情況之下IE會產生20px的距離**

          解決:解決方案是在float的標簽樣式控制中加入 ——_display:inline;將其轉化為行內屬性。(_這個符號只有ie6會識別)
          漸進識別的方式,從總體中逐漸排除局部。
          首先,巧妙的使用“9”這一標記,將IE游覽器從所有情況中分離出來。 接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經獨立識別。
          css

          .bb{ 
             background-color:#f1ee18;/*所有識別*/ 
            .background-color:#00deff\9; /*IE6、7、8識別*/ 
            +background-color:#a200ff;/*IE6、7識別*/ 
            _background-color:#1e0bd1;/*IE6識別*/ 
            } 
          

          問題:IE下,可以使用獲取常規屬性的方法來獲取自定義屬性,也可以使用getAttribute()獲取自定義屬性,Firefox下,只能使用getAttribute()獲取自定義屬性.

          解決:解決方法:統一通過getAttribute()獲取自定義屬性.

          問題:IE下,even對象有x,y屬性,但是沒有pageX,pageY屬性,Firefox下,event對象有pageX,pageY屬性,但是沒有x,y屬性.

          解決方法:(條件注釋)缺點是在IE瀏覽器下可能會增加額外的HTTP請求數。

          問題:Chrome 中文界面下默認會將小于 12px 的文本強制按照 12px 顯示,

          解決:可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.

          問題:超鏈接訪問過后hover樣式就不出現了 被點擊訪問過的超鏈接樣式不在具有hover和active了

          解決:方法是改變CSS屬性的排列順序:L-V-H-A : a:link {} a:visited {} a:hover {} a:active {}

          18.你知道多少種Doctype文檔類型?

          該標簽可聲明三種 DTD 類型,分別表示嚴格版本、過渡版本以及基于框架的 HTML 文檔。
          HTML 4.01 規定了三種文檔類型:Strict、Transitional 以及 Frameset。
          XHTML 1.0 規定了三種 XML 文檔類型:Strict、Transitional 以及 Frameset。
          Standards (標準)模式(也就是嚴格呈現模式)用于呈現遵循最新標準的網頁,而 Quirks(包容)模式(也就是松散呈現模式或者兼容模式)用于呈現為傳統瀏覽器而設計的網頁。

          19.HTML與XHTML——二者有什么區別?

          1)所有的標記都必須要有一個相應的結束標記
          2)所有標簽的元素和屬性的名字都必須使用小寫
          3)所有的XML標記都必須合理嵌套
          4)所有的屬性必須用引號""括起來
          5)把所有<和&特殊符號用編碼表示
          6)給所有屬性賦一個值
          7)不要在注釋內容中使“--”
          8)圖片必須有說明文字

          20.<img>的title和alt有什么區別?

          title是global attributes之一,用于為元素提供附加的advisory information。通常當鼠標滑動到元素上的時候顯示。
          alt是<img>的特有屬性,是圖片內容的等價描述,用于圖片無法加載時顯示、讀屏器閱讀圖片。可提圖片高可訪問性,除了純裝飾圖片外都必須設置有意義的值,搜索引擎會重點分析。

          21.div+css的布局較table布局有什么優點?

          改版的時候更方便 只要改css文件。
          頁面加載速度更快、結構化清晰、頁面顯示簡潔。
          表現與結構相分離。
          易于優化(seo)搜索引擎更友好,排名更容易靠前。

          22.CSS都有哪些選擇器?

          派生選擇器(用HTML標簽申明)
          id選擇器(用DOM的ID申明)
          類選擇器(用一個樣式類名申明)
          屬性選擇器(用DOM的屬性申明,屬于CSS2,IE6不支持,不常用,不知道就算了)
          除了前3種基本選擇器,還有一些擴展選擇器,包括
          后代選擇器(利用空格間隔,比如div .a{ })
          群組選擇器(利用逗號間隔,比如p,div,#a{ })
          那么問題來了,CSS選擇器的優先級是怎么樣定義的?

          基本原則:

          一般而言,選擇器越特殊,它的優先級越高。也就是選擇器指向的越準確,它的優先級就越高。
          復雜的計算方法:
          用1表示派生選擇器的優先級
          用10表示類選擇器的優先級
          用100標示ID選擇器的優先級
          div.test1 .span var 優先級 1+10 +10 +1
          span#xxx .songs li 優先級1+100 + 10 + 1
          xxx li 優先級 100 +1
          那么問題來了,看下列代碼,<p>標簽內的文字是什么顏色的?
          <style>
          .classA{ color:blue;}
          .classB{ color:red;}
          </style>
          <body>
          <p class='classB classA'> 123 </p>
          </body>
          答案:red。與樣式定義在文件中的先后順序有關,即是后面的覆蓋前面的,與在<p class=’classB classA’>中的先后關系無關。

          23.行內元素和塊級元素的具體區別是什么?行內元素的padding和margin可設置嗎?

          塊級元素(block)特性:
          總是獨占一行,表現為另起一行開始,而且其后的元素也必須另起一行顯示;
          寬度(width)、高度(height)、內邊距(padding)和外邊距(margin)都可控制;
          內聯元素(inline)特性:
          和相鄰的內聯元素在同一行;
          寬度(width)、高度(height)、內邊距的top/bottom(padding-top/padding-bottom)和外邊距的top/bottom(margin-top/margin-bottom)都不可改變(也就是padding和margin的left和right是可以設置的),就是里面文字或圖片的大小。
          那么問題來了,瀏覽器還有默認的天生inline-block元素(擁有內在尺寸,可設置高寬,但不會自動換行),有哪些?
          答案:<input> 、<img> 、<button> 、<texterea> 、<label>。

          24.什么是外邊距重疊?重疊的結果是什么?

          外邊距重疊就是margin-collapse。
          在CSS當中,相鄰的兩個盒子(可能是兄弟關系也可能是祖先關系)的外邊距可以結合成一個單獨的外邊距。這種合并外邊距的方式被稱為折疊,并且因而所結合成的外邊距稱為折疊外邊距。
          折疊結果遵循下列計算規則:
          兩個相鄰的外邊距都是正數時,折疊結果是它們兩者之間較大的值。
          兩個相鄰的外邊距都是負數時,折疊結果是兩者絕對值的較大值。
          兩個外邊距一正一負時,折疊結果是兩者的相加的和。

          25.rgba()和opacity的透明效果有什么不同?

          rgba()和opacity都能實現透明效果,但最大的不同是opacity作用于元素,以及元素內的所有內容的透明度,
          而rgba()只作用于元素的顏色或其背景色。(設置rgba透明的元素的子元素不會繼承透明效果!)

          26.CSS 選擇符有哪些?哪些屬性可以繼承?優先級算法如何計算? CSS3新增偽類有那些?

          *   1.id選擇器( # myid)
              2.類選擇器(.myclassname)
              3.標簽選擇器(div, h1, p)
              4.相鄰選擇器(h1 + p)
              5.子選擇器(ul < li)
              6.后代選擇器(li a)
              7.通配符選擇器( * )
              8.屬性選擇器(a[rel="external"])
              9.偽類選擇器(a: hover, li: nth - child)
          *   可繼承: font-size font-family color, UL LI DL DD DT;
          *   不可繼承 :border padding margin width height ;
          *   優先級就近原則,樣式定義最近者為準;
          *   載入樣式以最后載入的定位為準;

          優先級為:

             !important >  id > class > tag  
             important 比 內聯優先級高

          CSS3新增偽類舉例:

          p:first-of-type 選擇屬于其父元素的首個 <p> 元素的每個 <p> 元素。
          p:last-of-type  選擇屬于其父元素的最后 <p> 元素的每個 <p> 元素。
          p:only-of-type  選擇屬于其父元素唯一的 <p> 元素的每個 <p> 元素。
          p:only-child    選擇屬于其父元素的唯一子元素的每個 <p> 元素。
          p:nth-child(2)  選擇屬于其父元素的第二個子元素的每個 <p> 元素。
          :enabled、:disabled 控制表單控件的禁用狀態。
          :checked,單選框或復選框被選中。

          27.如何居中div,如何居中一個浮動元素?

          給div設置一個寬度,然后添加margin:0 auto屬性

          div{

          width:200px;
          margin:0 auto;

          }

          居中一個浮動元素

            確定容器的寬高 寬500 高 300 的層
            設置層的外邊距
          
          

          .div {
          Width:500px ; height:300px;//高度可以不設
          Margin: -150px 0 0 -250px;
          position:relative;相對定位
          background-color:pink;//方便看效果
          left:50%;
          top:50%;
          }

          28.瀏覽器的內核分別是什么?經常遇到的瀏覽器的兼容性有哪些?原因,解決方法是什么,常用hack的技巧 ?

          *  IE瀏覽器的內核Trident、 Mozilla的Gecko、google的WebKit、Opera內核Presto;
          *  png24為的圖片在iE6瀏覽器上出現背景,解決方案是做成PNG8.
          *  瀏覽器默認的margin和padding不同。解決方案是加一個全局的*{margin:0;padding:0;}來統一。
          *  IE6雙邊距bug:塊屬性標簽float后,又有橫行的margin情況下,在ie6顯示margin比設置的大。 
            浮動ie產生的雙倍距離 #box{ float:left; width:10px; margin:0 0 0 100px;} 
           這種情況之下IE會產生20px的距離,解決方案是在float的標簽樣式控制中加入 ——_display:inline;將其轉化為行內屬性。(_這個符號只有ie6會識別)
            漸進識別的方式,從總體中逐漸排除局部。 
            首先,巧妙的使用“\9”這一標記,將IE游覽器從所有情況中分離出來。 
            接著,再次使用“+”將IE8和IE7、IE6分離開來,這樣IE8已經獨立識別。
          
          

          css

            .bb{
             background-color:#f1ee18;/*所有識別*/
            .background-color:#00deff\9; /*IE6、7、8識別*/
            +background-color:#a200ff;/*IE6、7識別*/
            _background-color:#1e0bd1;/*IE6識別*/
            }
          
          
          *  IE下,可以使用獲取常規屬性的方法來獲取自定義屬性,
             也可以使用getAttribute()獲取自定義屬性;
             Firefox下,只能使用getAttribute()獲取自定義屬性. 
             解決方法:統一通過getAttribute()獲取自定義屬性.
          *  IE下,even對象有x,y屬性,但是沒有pageX,pageY屬性; 
            Firefox下,event對象有pageX,pageY屬性,但是沒有x,y屬性.
          * (條件注釋)缺點是在IE瀏覽器下可能會增加額外的HTTP請求數。
          *  Chrome 中文界面下默認會將小于 12px 的文本強制按照 12px 顯示, 可通過加入 CSS 屬性 -webkit-text-size-adjust: none; 解決.
          超鏈接訪問過后hover樣式就不出現了 被點擊訪問過的超鏈接樣式不在具有hover和active了解決方法是改變CSS屬性的排列順序:
          L-V-H-A :  a:link {} a:visited {} a:hover {} a:active {}
          

          29.css優先級算法如何計算?

          !important > id > class > 標簽
          !important 比 內聯優先級高

          • 優先級就近原則,樣式定義最近者為準;
          • 以最后載入的樣式為準;

          30.哪些css屬性可以繼承?

          可繼承: font-size font-family color, ul li dl dd dt;
          不可繼承 :border padding margin width height ;

          DOM

          講 DOM 先從 HTML 講起,講 HTML 先從 XML 講起。XML 是一種可擴展的標記語言,所謂可擴展就是它可以描述任何結構化的數據,它是一棵樹!

          1.documen.write和 innerHTML的區別

          document.write只能重繪整個頁面
          innerHTML可以重繪頁面的一部分

          2.DOM操作——怎樣添加、移除、移動、復制、創建和查找節點?

          1)創建新節點

          createDocumentFragment() //創建一個DOM片段
          createElement() //創建一個具體的元素
          createTextNode() //創建一個文本節點

          2)添加、移除、替換、插入

          appendChild()
          removeChild()
          replaceChild()
          insertBefore() //在已有的子節點前插入一個新的子節點

          3)查找

          getElementsByTagName() //通過標簽名稱
          getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等于name值的)
          getElementById() //通過元素Id,唯一性

          3.attribute和property的區別是什么?

          attribute是dom元素在文檔中作為html標簽擁有的屬性;
          property就是dom元素在js中作為對象擁有的屬性。
          所以:
          對于html的標準屬性來說,attribute和property是同步的,是會自動更新的,
          但是對于自定義的屬性來說,他們是不同步的,

          4.src和href的區別

          src用于替換當前元素,href用于在當前文檔和引用資源之間確立聯系。
          src是source的縮寫,指向外部資源的位置,指向的內容將會嵌入到文檔中當前標簽所在位置;在請求src資源時會將其指向的資源下載并應用到文檔內,當瀏覽器解析到該元素時,會暫停其他資源的下載和處理,直到將該資源加載、編譯、執行完畢,圖片和框架等元素也如此,類似于將所指向資源嵌入當前標簽內。這也是為什么將js腳本放在底部而不是頭部。
          Src source,指向外部資源的位置,如果我們添加<script src="js.js"></script>瀏覽器會暫停其他資源的下載和處理,直到該資源加載,編譯,執行完畢(圖片和框架也是如此),這也就是為什么js腳本要放在底部。
          src用于替換當前元素,href用于在當前文檔和引入資源之間建立聯系。

          存儲

          cookie

          cookie 本身不是用來做服務器端存儲的(計算機領域有很多這種“狗拿耗子”的例子,例如 CSS 中的 float),它是設計用來在服務器和客戶端進行信息傳遞的,因此我們的每個 HTTP 請求都帶著 cookie。但是 cookie 也具備瀏覽器端存儲的能力(例如記住用戶名和密碼),因此就被開發者用上了。
          使用起來也非常簡單,document.cookie=....即可。
          但是 cookie 有它致命的缺點:
          存儲量太小,只有 4KB
          所有 HTTP 請求都帶著,會影響獲取資源的效率
          API 簡單,需要封裝才能用

          locationStorage 和 sessionStorage

          后來,HTML5 標準就帶來了sessionStorage和localStorage,先拿localStorage來說,它是專門為了瀏覽器端緩存而設計的。

          其優點有:

          存儲量增大到 5MB
          不會帶到 HTTP 請求中
          API 適用于數據存儲 localStorage.setItem(key, value) localStorage.getItem(key)
          sessionStorage的區別就在于它是根據 session 過去時間而實現,而localStorage會永久有效,應用場景不同。例如,一些需要及時失效的重要信息放在sessionStorage中,一些不重要但是不經常設置的信息,放在localStorage中。

          對WEB標準以及W3C的理解與認識

          標簽閉合、標簽小寫、不亂嵌套、提高搜索機器人搜索幾率、使用外 鏈css和js腳本、結構行為表現的分離、文件下載與頁面速度更快、內容能被更多的用戶所訪問、內容能被更廣泛的設備所訪問、更少的代碼和組件,容易維 護、改版方便,不需要變動頁面內容、提供打印版本而不需要復制內容、提高網站易用性;


          主站蜘蛛池模板: 伊人色综合视频一区二区三区| 久久精品国产第一区二区三区| 午夜福利无码一区二区| 国产一区二区视频在线观看| 人妻无码一区二区三区AV| 中文字幕无码一区二区免费| 海角国精产品一区一区三区糖心 | 亚欧在线精品免费观看一区| 成人在线一区二区| 亚洲AV无码一区二区三区电影| 亚洲AV色香蕉一区二区| 中文字幕日韩一区二区三区不| 另类ts人妖一区二区三区| 亚洲av无码一区二区三区四区| 精品不卡一区二区| 国产精品久久一区二区三区| 亚洲视频一区网站| 亚洲午夜精品一区二区麻豆| 一区二区三区国产| 亚洲国产成人一区二区三区| 国产午夜精品一区二区三区嫩草| 岛国精品一区免费视频在线观看| 无码欧精品亚洲日韩一区夜夜嗨 | 中文字幕在线无码一区二区三区| 国产一区二区三区免费看| 国产伦精品一区二区三区四区 | 中文字幕色AV一区二区三区| 麻豆精品久久久一区二区| 无码精品人妻一区二区三区漫画 | 蜜臀AV在线播放一区二区三区| 一区二区三区观看免费中文视频在线播放 | 一区二区三区四区精品| 三上悠亚日韩精品一区在线| V一区无码内射国产| 国产一区二区视频在线观看| 国产一区三区三区| 国产一区二区三区免费观看在线 | 色屁屁一区二区三区视频国产 | 无码人妻啪啪一区二区| 国产一区二区三区国产精品| 狠狠色婷婷久久一区二区三区|