整合營銷服務商

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

          免費咨詢熱線:

          從jQuery轉向Vue

          從jQuery轉向Vue

          為一個使用了jQuery很多年 的人,最近,我成為了一個Vue的皈依者,我認為從一個框架到另一個框架的遷移過程將是一個值得討論的有趣的話題。

          在我開始之前,我想清楚地說明一點。我并沒有以任何方式告訴任何人去停止使用jQuery。jQuery最近相當流行,而且見鬼,我幾年前也寫過類似的東西(“我如何(不)使用jQuery”)。如果你使用jQuery完成了你的項目,并且你的最終用戶成功地使用了你的站點,那么你將獲得更多的動力去繼續使用對你有用的東西。

          本指南更適合那些可能具有多年jQuery經驗并希望了解如何使用Vue來完成工作的人。考慮到這一點,我將重點介紹我所認為的“核心”jQuery用例。我不會涵蓋每一個可能的特性,而是用“我經常使用jQuery來完成 [X]”的方式來代替,這種方式可能更適合那些考慮學習Vue的人。(順便提一句,請注意,我編寫示例的方式只是執行一個任務的一種方式。jQuery和Vue都提供了多種方法來實現相同的目標,這是一件很棒的事情!)

          記住了這一點,我們來思考一些可以使用jQuery完成的高級的東西:

          • 在DOM中找到某些東西(稍后再用它做一些事情)
          • 修改DOM中的某些東西(例如一個段落的文本或一個按鈕的類)
          • 讀取和設置表單值
          • 表單驗證(實際上是上面各項的一個組合)
          • ajax調用和處理結果
          • 事件處理(例如點擊按鈕,做某些事情)
          • 測量或改變元素的樣式

          當然,jQuery還有更多的功能,但是這些用途(至少在我看來)涵蓋了最常見的用例。還要注意,在上面的列表中有很多異花授粉現象。那么,我們應該從簡單的一一對應的比較開始嗎?不,沒那么快。我們先從介紹Vue應用程序中的主要差異開始。

          #定義Vue的使用場景

          當我們將jQuery加入到頁面上時,我們基本上是在JavaScript代碼中添加一把瑞士軍刀來處理常見的web開發任務。我們可以按照我們認為合適的順序來處理任何一個用例。例如,今天客戶可能會要求表單驗證,然后在一個月左右后,又要求在站點的頭部添加一個基于Ajax的搜索表單。

          Vue在這方面有一個顯著的不同。當使用Vue開始一個項目時,我們首先會在DOM中定義一個我們希望Vue專用的“區域”。因此,我們來考慮一個簡單的原型web頁面:

          在一個典型的jQuery應用程序中,我們可以編寫代碼來處理頭部、側邊欄和登錄表單等。這很簡單:

          而在一個Vue應用程序中,我們首先需要指定要處理的內容。假設我們的客戶首先要求我們向loginForm元素添加驗證,那么我們的Vue代碼就要指定這一點:

          這意味著,如果客戶后來決定讓我們在側邊欄中添加一些內容,那我們通常會添加第二個Vue應用程序:

          這是件壞事嗎?絕對不是。我們馬上就會得到封裝的好處。如果我們不小心使用了一個具有泛型名稱的變量(我們都這樣做過),我們不必擔心它與代碼的其他部分發生沖突。過后,當客戶端增加了另一個要求時,像這樣將我們獨特的、邏輯化的Vue代碼集區分開就會確保每一個Vue應用程序不會相互干擾。

          所以,是的,這是一件好事。但當我第一次開始使用Vue時,它絕對讓我停了下來。現在,進入我們的用例。

          #在DOM中查找東西

          你會發現另一個有趣或可怕的方面是如何“在DOM中查找東西”。這有點模糊,但我們來考慮一個強有力的例子。我們有一個按鈕,當它被點擊時,我們讓一些事情發生。下面是一個簡短的例子,展示了它是怎樣的:

          現在我們來將這個例子與用Vue的實現方式進行比較:

          這個Vue應用程序有點冗長,但是請注意標記是如何在操作(“click”)和將要調用的函數之間建立一個直接連接的。Vue的代碼并沒有與DOM進行向后綁定(我們在el部分之外定義了它需要運行的地方)。這是Vue最吸引我的地方之一——它能很容易地告訴你將要發生什么。此外,我不需要過多地擔心ID值和選擇器。如果我更改了按鈕的類或ID,我不需要返回代碼中去更新選擇器。

          我們來考慮另一個例子:在DOM中查找和更改文本。想象一下那個按鈕,單擊它,現在會更改DOM的另一部分的文本。

          我已經添加了一個新的span,現在,當按鈕被單擊時,我們使用另一個選擇器來查找它,并使用一個jQuery工具方法來更改其中的文本。現在我們來考慮一下Vue版本:

          在本例中,我們使用Vue的模板語言(突出顯示的行)來指定我們希望在span中呈現的一個變量,在本例中是resultText。現在,當按鈕被單擊時,我們更改該值,span的內部文本將會自動更改。

          順便說一句,Vue支持v-on屬性的簡寫,因此示例中的按鈕可以用@click=“ doSomething"代替。

          #讀寫表單變量

          處理表單可能是我們可以用JavaScript做的最常見也是最有用的事情之一。甚至在JavaScript之前,我早期的“web開發”大部分都是通過編寫Perl腳本來處理表單提交。作為接受用戶輸入的主要方式,表單對web來說一直都是很重要的,而且很可能會在相當長一段時間內保持不變。我們來考慮一個簡單的jQuery例子,它將讀取幾個表單字段并設置另一個:

          這段代碼演示了jQuery如何通過val( )方法讀寫表單。最后,我們從DOM中獲取四個項目(所有的三個表單字段和一個按鈕),并使用簡單的數學方法來生成一個結果。現在我們來考慮一下Vue版本:

          這里介紹了一些有趣的Vue快捷方法。首先,v-model是Vue如何在DOM和JavaScript中的值之間創建雙向數據綁定。data塊變量將自動與表單字段同步。更改數據,表單就會更新。更改表單,數據就會更新。.number是Vue的一個標志,用于將表單字段的繼承字符串值視為數字。如果我們不做這一步,按原樣做加法,我們會看到字符串加法,而不是算術。我已經使用JavaScript處理了將近一個世紀了,但還是搞砸了。

          另一個簡單的“技巧”是@click.prevent。首先,@click為按鈕定義了一個單擊處理程序,然后.prevent部分會阻止瀏覽器提交表單的默認行為(相當于event.preventDefault( ))。

          最后一個是綁定到該按鈕的doSum方法進行的相加操作。注意,它只處理數據變量(Vue在this作用域內允許對這些變量進行操作)。

          雖然這主要是我個人的感覺,但我非常喜歡在用Vue編寫腳本時,腳本中沒有查詢選擇器,以及HTML如何更清楚地顯示它在做什么。

          最后,我們甚至可以完全去掉按鈕:

          Vue的一個更酷的特性是computed properties(計算屬性)。它們是虛擬值,可以識別其派生值何時被更新。在上面的代碼中,只要兩個表單字段中的任何一個發生更改,總和就會更新。這也適用于表單字段之外。我們可以這樣渲染其總和:

          #使用Ajax

          值得稱贊的是,jQuery使Ajax的使用變得非常簡單。事實上,我可以說我已經以一種“普通”的方式完成了Ajax,可能總共只有一次(如果你對此很好奇,你可以查看XMLHttpRequest規范,并且你可能會為你已經避免了它而感到高興)。jQuery簡單的$.get(…)方法在很多情況下都能工作,并且當它需要在更復雜的東西中使用時,$.ajax()也能使它變得簡單。jQuery做得很好的另一件事是它處理JSONP請求的方式。雖然現在使用CORS基本上沒有必要,但JSONP是一種處理向不同域中的API發出請求的方法。

          那么,Vue如何讓Ajax變得更簡單呢?沒有什么!

          好吧,聽起來很嚇人,但其實并不可怕。有許多處理HTTP請求的選項,而Vue.js采用了一種更不可知的方式,讓我們開發人員決定如何處理它。所以,是的,這確實意味著更多的工作,但我們有一些不錯的選擇。

          首先應該考慮的是Axios,這是一個Promise-based庫,在Vue社區中非常流行。下面是一個使用它的簡單的例子(摘自它們的README文件):

          Axios支持POST請求,當然,它也允許我們在許多其他選項中指定頭文件。

          雖然Axios在Vue開發人員中非常流行,但我并不是真心喜歡它。(至少現在還沒有。)相反,我更喜歡Fetch。Fetch不是一個外部庫,而是執行HTTP請求的一種web標準方法。Fetch在大約90%的瀏覽器

          上都有很好的支持,雖然這意味著使用它并不完全安全,但是我們總是可以使用一個我們需要的polyfill。

          雖然這完全超出了我們在這里討論的范圍,但是Kingsley Silas寫了一本關于在React中使用Axios和Fetch的優秀指南。

          和Axios一樣,Fetch也是Promise-based的,并且有一個友好的API:

          Axios和Fetch都涵蓋了所有類型的HTTP請求,所以它們都能滿足任意數量的需求。讓我們看一個簡單的比較。下面是一個使用了星球大戰API的簡單jQuery演示。

          在上面的示例中,我使用$.get調用該API并返回一個電影列表。然后我用這些數據生成一個標題列表作為 li 標記元素,并將其全部插入到一個ul塊中。

          現在,讓我們考慮一個使用Vue的例子:

          其中最好的部分可能是使用v-for模板。注意Vue是如何做到與布局無關的(至少與JavaScript無關)。數據是從該API中獲取的。它被分配了一個變量。布局處理如何顯示它。我一直討厭在我的JavaScript中使用HTML,但是jQuery提供了解決方案,把它嵌入到Vue中看起來就很自然很合適。

          #一個完整的(在某種程度上有點瑣碎)例子

          為了更好地理解它,讓我們考慮一個更真實的例子。我們的客戶要求我們為一個產品API構建一個支持Ajax的前端搜索接口。功能列表包括:

          • 支持按名稱和產品類別進行過濾
          • 我們必須提供搜索項或類別的表單驗證
          • 當API被點擊時,向用戶顯示一條消息并禁用提交按鈕
          • 完成后,對未顯示產品進行報告或列出匹配項

          我們從jQuery版本開始。首先, HTML部分如下:

          有一個帶有兩個過濾器和兩個div的表單。一個用做搜索或報告錯誤時的臨時狀態,另一個用于呈現結果。現在,檢查代碼。

          代碼首先為要處理的每個DOM項(表單字段、按鈕和div)創建一組變量。代碼的邏輯核心在按鈕的點擊處理程序中。我們進行驗證,如果一切正常,就對該API執行一個POST請求。當請求返回時,我們要么呈現結果

          ,要么在沒有匹配的情況下顯示消息。

          你可以使用下面的CodePen來運行這個演示的完整版本。

          現在讓我們考慮Vue版本。同樣,我們先從布局開始:

          從頂部看,其中的變化包括:

          • 用一個div包裝布局,可以讓Vue知道在哪里運行。
          • 對表單字段使用v-model,以便它能輕松處理數據。
          • 使用@click.prevent處理執行主搜索操作。
          • 使用 :disabled 在這個Vue應用程序中將按鈕綁定到一個值,無論按鈕是否禁用 (我們稍后將看到它的實際操作)。
          • 狀態值與前面的示例稍有不同。jQuery有一個特定的方法來設置DOM項中的文本和HTML中的文本,而Vue在將HTML分配給要呈現的值時需要使用v-html。如果我們在HTML中直接編寫{{status}},標簽將被轉義。
          • 最后,使用v-if條件性地呈現結果列表,同時使用v-for來處理迭代。

          現在讓我們看看代碼。

          值得調用的第一個塊是data字段集。有些映射到表單字段,有些映射到結果、狀態消息等等。searchProducts方法處理的內容與jQuery版本大致相同,但通常直接綁定到DOM的代碼要少得多。例如,即使我們知道結果是以一個無序列表列出的,但代碼本身并不關心這一點。它只是進行賦值,標記才處理呈現值。總的來說,與jQuery代碼相比,JavaScript代碼更關心邏輯,jQuery代碼“感覺”是更好的分離了關注點。

          和以前一樣,這里有一個CodePen可以讓你自己試試:

          #jQuery將死! Vue萬歲!

          好吧,這有點過分了。正如我在開始時所說的,如果你喜歡使用jQuery并且它對你有用的話,那我覺得你完全沒必要更改任何東西。

          不過,我想說的是,對于習慣使用jQuery的人來說,Vue似乎是一個很好的“下一步”。Vue支持復雜的應用程序,并為搭建和構建項目提供了一個非常棒的命令行工具。但是對于更簡單的任務來說,Vue是一個很棒的“現代jQuery”的替代品,它已經成為我開發的可選工具!

          有關使用Vue替代jQuery的另一個觀點,請查看Sarah Drasner的“使用Vue.js替換jQuery:無需構建步驟”,因為它包含了其他一些超級有用的例子。

          英文原文:https://css-tricks.com/making-the-move-from-jquery-to-vue/

          譯者:浣熊君( ????? )

          、深淺拷貝的區別有哪些?

          要說 js 的深淺拷貝,就不得不提 js 的兩大數據類型:基本數據類型和引用類型。基本數據類型的變量名和值都存儲在棧中,對于引用類型的變量名存儲在棧中,而值存儲在堆中。由于存儲方式不同,所以導致了他們復制的時候方式不同。

          淺拷貝是創建一個新對象,這個對象有著原始對象屬性值的一份精準拷貝。如果屬性是基本類型,拷貝的就是基本類型的值,如果是引用類型,拷貝的就是內存地址,所以如果其中一個對象改變了這個地址,就會影響到另外一個對象。

          深拷貝是將一個對象從內存中完整的拷貝一份出來,從內存堆中存放一個新的對象。這是兩個對象,所以修改其中一個,另外一個不會受影響。

          深淺拷貝主要針對的是引用類型,簡單數據類型不受影響。

          相關筆試題

          var person={
           name:"前端人",
           hobby:['學習','敲代碼','潛水']
          }
          function copy(source){
           var newObj=new Object()
           for(var i in source){
            if(source.hasOwnProperty(i)){
             newObj[i]=source[i]
             }
            }
           return newObj
          }
          var p1=copy(person);
          p1.name="Web Person"
          console.log(person.name)
          console.log(p1.name)
          p1.hobby=["內卷"]
          console.info(person.hobby)
          console.info(p1.hobby)
          /*運行結果:
          前端人
           Web Person
          ["學習", "敲代碼", "潛水"]
          ["內卷"]
          */

          2、js 數據類型有哪些?

          js 數據類型一共有 8 種,分為兩大類:基本類型和引用類型。

          它們的數據類型分別為:

          基本類型:string、number、boolean、null、undefined、symbol、bigint

          引用類型:object

          相關面試題

          // 注意:其他類型與數值進行相加時,其他類型的轉為 number 類型
          console.log( true+1 ) // 2
          console.log( undefined +1 ) // NaN
          
          console.log( null ) //object
          console.log( undefined ) // undefined

          3、延遲加載 js 的方式有哪些?有什么區別呢?

          共有 6 種方式,分別為:

          • async
          • defer
          • js 最后加載
          • 利用 setTimeout
          • 動態創建 DOM 的方式
          • 使用 jQuery 的 getScript 方法

          它們的區別介紹:

          1、async:為 <script>標簽定義了 async 屬性。async 和 html 解析是同步的,不是順次執行 js 腳本,誰先加載完成先執行誰。

          <script  async type="text/javascript" src="demo1.js" ></script>
          <script  async type="text/javascript" src="demo2.js" ></script>

          2、defer 會等到 html 解析完成之后再執行 js 代碼,如果有多個腳本時,會按照順序依次執行腳本。

          <script  defer type="text/javascript" src="demo1.js" ></script>

          3、js 最后加載

          把 js 外部引入的文件放置在頁面的底部,讓 js 最后加載,從而加快頁面加載速度。

          4、利用 setTimeout

          5、動態創建 DOM 的方式

          var element=document.createElement("script");  
          element.src="box.js";  
          document.body.appendChild(element);

          這種方式通過操作動態加載 js 文件,不觸發的時候不加載,減少頁面文件大小,加快加載速度。

          6、使用 jQuery 的 getScript 方法

          $.getScript( "box.js",function(){//回調函數,成功獲取文件后執行的函數  
                console.log("腳本加載完成")  
          });

          相關面試題:

          <!doctype html>
          <html>
           <head>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <script type="text/javascript" src="box.js"></script>
           </head>
           <body>
            <div id="box"></div>
           </body>
          </html>
          
          //box.js 代碼如下
          console.log( document.getElementById('box') )  // null

          box.js 想正常獲取元素 box ,并進行一系列操作應該如何延遲加載 js 文件呢?

          4、你對作用域的認識有多少?

          作用域通俗地講,就是指一個變量的作用范圍。分為全局作用域和函數作用域。

          全局作用域

          • 頁面打開時被創建,頁面關閉時被銷毀。
          • 編寫在 script 標簽下的變量和函數,作用域為全局,頁面的任意位置都可以訪問
          • 有全局對象 window ,代表瀏覽器窗口,全局作用下的變量和函數作為 window 的屬性和方法

          函數作用域(局部)

          • 函數是被調用時創建的,執行完畢之后銷毀。
          • 函數每調用一次,變量和函數就會重新創建一次,它們之間是相互獨立的
          • 在函數作用域內可以訪問到全局變量或函數,但是在函數外無法訪問函數作用域內的變量
          • 函數作用域內訪問變量,會在自身作用域內尋找,若沒有則會向上一級作用域內查找,一直到全局作用域。

          函數在被調用的時候會先進行預編譯:

          全局作用域預編譯:

          • 創建上下文 GO 對象。
          • 找變量聲明,將變量名作為 GO 對象的屬性名,值為 undefined
          • 找函數式聲明,將值賦予函數體

          函數作用域預編譯:

          • 創建上下文 AO 對象
          • 將形參和實參作為 AO 對象的屬性,賦值為 undefined
          • 實參和形參相統一
          • 在函數體內找函數聲明,將值賦予函數體。

          相關面試題:

          <script type="text/javascript">
           function fn(a,c){
            console.log(a)
            var a=12
            console.log(a)
            console.log(c)
            function a(){ }
            if(false){
             var d=34
            }
            console.log(d)
            console.log(b)
            var b=function(){}
            console.log(b)
            function c(){}
            console.log(c)
           }
           fn(1,2)
          </script>
          // 運行結果:
          /*
          function a(){}
          12
          function c(){}
          undefined
          undefined
          function (){}
          function c(){}
          */

          5、null 和 undefined 的區別。

          null 和 undefined 兩個都表示無的值。

          作者設計 js 的時候,借鑒的 java 語言先設計的 null 。null 使用的時候會被隱式轉化成 0,不容易發現錯誤。

          console.log( number(null) ) //0

          undefined 是為了填補 null 的坑。所以后來又新增了 undefined 。

          console.log( number(undefined) ) //NaN

          6、new 操作符具體做了什么?

          • 創建了一個空對象。
          • 將空對象的原型指向于構造函數的原型。
          • 將空對象作為構造函數的上下文。
          • 對構造函數有返回值的處理判斷。

          實現 new 操作符的方法:

          function create( fn,...args ){
           var obj={}
           Object.setPrototypeOf( obj,fn.prototype )
           var resault=fn.apply(obj,args)
           return (resault instanceof Object) ? result : obj
          }

          7、為什么會有閉包?它解決了什么問題?

          7.1、什么是閉包?

          閉包就是函數嵌套函數,通過函數內的函數訪問變量的規則,實現外部訪問函數內的變量。

          7.2、閉包的特點:

          • 函數嵌套函數。
          • 函數內部可以引用函數外部的參數和變量。
          • 參數和變量不會被垃圾回收機制回收。

          實例3:閉包解決問題

          var liArr=document.getElementsByTagName('li')
          for(var i=0;i<liArr.length;i++){
           (function(i){
            liArr[i].onclick=function(){
             console.log('點擊元素',liArr[i])
            }
           })(i) 
          }

          7.3、閉包優點:

          • 保護變量安全,實現封裝,防止變量聲明沖突和全局污染。
          • 在內存當中維持一個變量,可以做緩存。
          • 匿名函數自執行函數可以減少內存消耗。

          防抖和節流就是閉包的經典應用。

          7.4、閉包缺點:

          • 變量會駐留在內存中,造成內存損耗問題。解決辦法:把閉包函數設置為 null 。
          • 內存泄漏

          8、防抖和節流,你了解多少?

          8.1、什么是防抖函數?

          當持續觸發事件,一定時間內沒有再觸發事件,事件處理函數才會執行一次,如果在設定的時間到來之前又觸發了事件,就會重新計時。

          防抖函數常見的實際應用:使用 echart 的時候,瀏覽器 resize 時,需要重新繪制圖表大小,還有典型的輸入框搜索應用。

          8.2、節流函數是什么?

          當持續觸發事件的時候,保證一段時間內只調用一次事件處理函數,一段時間內,只允許做一件事情。

          防抖和節流主要是用來限制觸發頻率較高的事件,再不影響效果的前提條件下,降低事件觸發頻率,減小瀏覽器或服務器的壓力,提升用戶體驗效果。

          9、數組去重有幾種方法?

          方法1: new set()

          return Array.from(new Set(arr))
          // 或
          return [...new Set(arr)]

          方法2:使用兩次循環

          for(var i=0,len=arr.length;i<len;i++){
           for(var j=i+1,len=arr.length;j<len;j++){
            if( arr[i]===arr[j] ){
             arr.splice(i,1)
             j--;
             len--
            }
           }
          }
          return arr

          方法3:indexOf 實現

          let arr1=[]
          for(var i=0;i<arr.length;i++){
           if( arr1.indexOf(arr[i])===-1 ){
            arr1.push(arr[i])
           }
          }
          return arr1

          方法4:includes 實現

          let arr1=[]
          for(var i=0;i<arr.length;i++){
           if( !arr1.includes(arr[i]) ){
            arr1.push(arr[i])
           }
          }
          return arr1

          方法5:filter 實現

          array.indexOf(item,start) start 表示開始檢索的位置。

          return arr.filter(( item, index )=>{
           return arr.indexOf( item, 0 )==index
          })

          10、call、bind 和 apply 的區別

          三者都是改變函數執行的上下文,即改變 this 指向。

          它們之間的區別為:

          • call 和 apply 會立即執行,bind 返回的是一個函數,需調用后執行。
          • 第二參數是傳入要執行的方法中的參數,call 和 bind 是獨立傳遞參數,apply 是以數組傳遞參數的

          使用場景:
          1、需要改變某個函數的this指向時
          2、當參數較少時可以使用call,參數較多可以使用apply以數組的方式傳遞
          3、當需要重復調用時,可以使用bind新定義一個方法

          11、js 判斷變量是不是數組,你能寫出幾種方法?

          方法1:isArray

          var arr=[1,2,3]
          console.log(Array.isArray(arr))    

          方法2:instanceof

          var arr=[1,2,3]
          console.log( arr instanceof Array )
          console.log( arr instanceof Object )

          該方法不夠嚴謹。

          方法3:prototype

          console.log( Object.prototype.toString.call(arr).indexOf('Array')>-1 )

          方法4:isPrototypeOf

          console.log( Array.prototype.isPrototypeOf( arr ) )

          方法5:constructor

          console.log(arr.constructor.toString().indexOf('Array')>-1 )

          12、slice 是干嘛的? splice 是否會改變原數組?

          slice 是用來截取字符串的,返回一個新數組,但不會影響原數組。

          使用語法:

          arr.slice( start , end )

          截取 arr 數組,從 start 開始到 end 結束,第二個參數是可選參數,沒有時從 start 開始截取到結尾。

          如果 start 參數是負數時,就會從 arr.lengtn + start 開始截取到結束。

          var arr=['a','b','c','d','e']
          console.log( arr.slice(-3) ) // ["c", "d", "e"]
          console.log(arr)  //["a", "b", "c", "d", "e"]

          splice 是一個更強大的方法,可以添加、刪除、替換數組元素,返回的是被刪除元素,它的操作會改變原數組。

          使用語法:

          splice( start, n, new )

          從 start 開始,刪除 n 個元素,然后把 new 添加到 start 元素之后。第三個參數為可選參數

          • n 為 0 且第三個參數不為空時,表示添加新元素到 start 之后。
          • n 不為 0 且第三個參數不為空時,表示把 start 之后的 n 個元素替換成 new 。
          • n 不為 0 且第三個參數為空時,表示刪除 start 后的 n 個元素。
          var arr=['a','b','c','d','e']
          var ar=arr.splice( 1, 1 ,'f','g')
          console.log('ar',ar)    // ["b"]
          console.log('arr',arr) //  ["a", "f", "g", "c", "d", "e"]

          13、==和===有什么不同?

          ==比較的是值,===除了比較值,還比較類型。

          console.log( [1,2]=='1,2'  )       // true
          console.log( [1,2]==='1,2'  )  //false

          valueOf 方法返回 Math 對象的原始值,通常由 javascript 在后臺自動調用,并不顯示的出現在代碼中。

          console.log([1,2].valueOf()) //[1,2]
          console.log('1,2'.valueOf()) //[1,2]
          // 所以
          console.log( [1,2]=='1,2'  )  // true

          不管是字符串和數字比較,還是布爾值和數字比較,都會使用 valueOf 隱式轉換。

          總結:==需要使用 valueOf() 進行隱式轉換,所以性能差。===會避開一些不必要的麻煩。

          14、this 的指向

          大廠筆試題:

          var name='window name'
          var p1={
           name:'p1 name',
           showName:function(){
            console.info(this.name)
           }
          }
          var fn=p1.showName
          fn()
          p1.showName()
          var p2={
           name:'p2 name',
           showName:function(fun){
            fun()
           }
          }
          p2.showName(p1.showName)
          p2.showName=p1.showName
          p2.showName()
          /*
          運行結果:
          window name
           p1 name
           window name
           p2 name
          */

          這是一道關于 this 指向的面試題,接下來我們就說說 this 是如何指向的?

          this 對象是運行時基于函數的執行環境綁定的:

          • 在全局函數中,this 等于 window 。
          • 函數上下文調用,嚴格模式下 this 為 undefined ,非嚴格模式下,this 指向 window 。
          • 當函數被作為某個對象的方法被調用時,this 等于那個對象。如果使用 call apply 改變當前 this 時,將會指向為傳遞過來的那個 this 。
          • 匿名函數的執行環境具有全局性,因此 this 指向 window。
          • 構造函數內的 this 指向創建的實例對象。
          • dom 事件處理函數,this 指向觸發該事件的元素。
          • setTimeout 和 setInterval 中的 this 指向全局變量 window

          15、js 中的繼承有哪些方式呢?

          第 1 種:原型鏈繼承

          function Parent(){
           this.name="前端人"
          }
          Parent.prototype.showName=function(){
           console.log(this.name)
          }
          function Child(){}
           //原型鏈繼承   
          Child.prototype=new Parent()
          var p=new Child()
          console.dir(p.name) //前端人

          特點:

          • 實例的是子類的實例,也是父類的實例。
          • 父類新增原型方法和屬性,子類都能訪問到。
          • 簡單,方便實現

          第 2 種:借用構造函數

          function Animal (name) {
           this.name=name || 'Animal';
           this.sleep=function(){
            console.log(this.name + '正在睡覺!');
           }
          }
          Animal.prototype.eat=function(food) {
           console.log(this.name + '正在吃:' + food);
          };
          function Cat(name){
           Animal.call(this);
           this.name=name || 'Tom';
          }
          // Test Code
          var cat=new Cat();
          console.log(cat.name);
          console.log(cat.sleep());
          console.log(cat instanceof Animal); // false
          console.log(cat instanceof Cat); // true

          特點:

          • 創建子類時,可以向父類傳遞參數。
          • 可以實現多繼承,call 多個父類對象。
          • 解決方法1中,子類實例共享父類引用屬性的問題。

          還有組合式繼承、ES6 的繼承 和 寄生組合繼承等等。每種繼承方式都有各自的特點和缺點。

          16、嚴格模式與非嚴格模式的區別,你了解多少?

          JavaScript 語言是一門弱類型語言,存在許多類型錯誤,因此 ES6 引入了嚴格模式概念。

          如果不加 ‘use strict’ 常規模式下就是屬于非嚴格模式。

          嚴格模式

          在 js 文件頂部添加 ‘use strict’ 就屬于嚴格模式,嚴格模式也可以指定在函數內部。

          <script>
           'use strict'  
           //或者函數內部
           (function(){
            'use strict'
           })()
          </script>

          嚴格模式,是為 js 定義來了一種不同的解析與執行模型,在嚴格模式下,ECMAScipt 3 中一些不解和不確定的行為將得到處理,而且會對不安全的操作會拋出異常。‘use strict’ 會告訴瀏覽器引擎可以切換到嚴格模式執行。

          嚴格模式與非嚴格模式區別

          嚴格模式

          非嚴格模式

          變量必須聲明才能賦值

          變量不進行聲明,可直接賦值

          不能使用 delete 字符刪除變量或對象

          可以使用 delete 刪除

          函數參數變量名不允許重復

          變量名重復,獲取最后最后那個值

          普通函數內的 this 為 undefined

          普通函數內的 this 為 window

          不允許使用八進制

          允許任意進制

          eval 和 arguments 當做關鍵字,不能被賦值和用作變量名

          可以使用 eval 、arguments 作為變量名

          call、apply 傳入 null undefined 保持原樣不被轉為window

          默認轉為 window 對象

          限制對調用棧的檢測能力,訪問 arguments.callee 會拋出異常

          arguments.callee 運行正常

          17、隱式轉化相關面試題

          console.log( '2'>10 ) //false
          console.log( '2'>'10' ) //true
          console.log( 'abc'>'b' ) //false
          console.log( 'abc'>'aab' ) //true
          console.log( undefined==null ) //true
          console.log( NaN==NaN )//false
          console.log( []==0 ) //true
          console.log( ![]==0 ) //true
          console.log( []==[] ) //false
          console.log( {}=={} ) //false
          console.log( {}==!{} ) //false

          18、事件循環機制相關面試題。

          阿里面試題1:

          <script type="text/javascript">
           var p=new Promise(resolve=>{
            console.log(4)
            resolve(5)
           })
           function f1(){
            console.log(1)
           }
           function f2(){
            setTimeout(()=>{
             console.log(2)
            },0)
            f1()
            console.log(3)
            p.then(res=>{
             console.log(res)
            })
           }
           f2()
          </script>
          // 運行結果 4 1 3 5 2
          // 如果已經了解事件運行機制,就可以跳過該問題了

          事件循環機制,event-loop 。包含三部分:調用棧、消息隊列、微任務隊列。

          事件循環開始的時候,會從全局一行一行的執行代碼,遇到函數調用的時候,就會壓入調用棧中,當函數執行完成之后,彈出調用棧。

          // 如:代碼會一行一行執行,函數全部調用完成之后清空調用棧
          function f1(){
           console.log(1)
          }
          function f2(){
           f1()
           console.log(2)
          }
          f2()
          // 執行結果 1 2

          如果遇到 fetch、setInterval、setTimeout 異步操作時,函數調用壓入調用棧時,異步執行內容會被加入消息隊列中,消息隊列中的內容會等到調用棧清空之后才會執行。

          // 如:
          function f1(){
           console.log(1)
          }
          function f2(){
           setTimeout(()=>{
            console.log(2)
           },0)
           f1()
           console.log(3)
          }
          f2()
          // 執行結果 :1 3 2

          遇到 promise、async、await 異步操作時,執行內容會被加入微任務隊列中,會在調用棧清空之后立即執行。

          調用棧加入的微任務隊列會立即執行。

          如
          let p=new Promise(resolve=>{
           console.log('立即執行')
           resolve(1) //在 then 調用中執行
          })

          微任務隊列中內容優先執行,所以比消息隊列中的內容執行得早。

          了解這些知識后,再試一下最前面的那道面試題,應該就沒什么問題了。

          20、前端領域內,你比較擅長什么?

          這個問題就留給讀到最后,能夠堅持學習的人,問問我們自己有什么是我們擅長的?在哪塊領域是我們占據競爭優勢的?

          、jQuery概述

          什么是jquery

          jQuery是JavaScript的一個庫,jQuery 極大地簡化了 JavaScript 編程。我們在做網站或web應用的過程中,需要用JavaScript為我們完成一些用戶與頁面的交互效果,jQuery庫可以讓我們用更少的JavaScript代碼完成更多的功能。

          jQuery的優勢與劣勢

          幾年前的web開發,瀏覽器兼容是一個非常重要的問題,前端工程師為了讓自己的程序在多個瀏覽器中正確運行,常常需要編寫更多的代碼來解決瀏覽器兼容問題,jQuery出現之后,它為前端工程師們解決了大量的JavaScript兼容問題,并且封裝了大量的DOM接口和動畫效果,讓我們可以用更少的代碼實現更多的功能并且保持良好的兼容性,jQuery因此迅速成為了世界上最流行的JavaScript庫。

          jQuery的流行還有一個原因就是因為它簡單、易上手。很多人在不熟悉JavaScript的情況下,仍然可以使用jQuery完成各種頁面效果。

          隨著時間的推移,瀏覽器的兼容問題越來越少,css3也解決了大量的頁面動畫效果,jQuery的優勢漸漸沒有那么突出了,但是它仍然是當前被使用了最多的JavaScript庫,是前端工程師必須掌握的技能。

          二、jQuery代碼的編寫

          引入jQuery

          要使用jQuery,首先我們需要下載和引入jQuery,我們可以到jquery官網下載jQuery文件,然后在html頁面中添加script標簽引入jQuery。

          我們將jQuery放在一個名為script的目錄中,然后用下面的代碼引入jQuery。

          1 <body>
          2     <script src="script/jquery.js"></script>
          3     <script>
          4         //這里可以編寫jQuery代碼
          5     </script>
          6 </body>

          引入jQuery的注意事項

          • 如果要編寫jQuery的代碼,一定要用兩個script標簽,一個用來引入jQuery,一個用來編寫代碼,且不可將jQuery的代碼寫在第一個script標簽當中,這樣編寫的代碼將沒有任何作用。
          • 一定要在第一個script引入jQuery,上面的script標簽編寫代碼,下面的script引入jQuery,程序不能正常運行。

          三、jQuery選擇器

          剛剛學習jQuery的時候,可以與css做比較:css使用【選擇器】查找元素,使用【屬性名:屬性值】改變元素樣式。jQuery與之類似,可以使用【jQuery選擇器】查找元素,然后使用【jQuery方法】操作元素。這里的操作不只可以操作元素的樣式,還可以添加和刪除元素,或者獲取元素的屬性和文本等等功能。

          改變元素樣式

          jQuery選擇器和css選擇器很類似(其實可以理解為jQuery選擇器擴展了css選擇器,在$()中添加css選擇器就能找到我們想要的元素),下面我們使用jQuery選擇器和css方法來找到并且改變一個元素的樣式。

          1 <body>
          2     <h1>hello jquery</h1>
          3     <script src="script/jquery.js"></script>
          4     <script>
          5         $("h1").css("color","red");  //將選擇器$("h1")找到的元素的樣式color設置成紅色
          6     </script>
          7 </body>
          • 在上面的例子中$(“h1”)是選擇器,我們可以在雙引號內插入各種css選擇器,jQuery就會找到響應的元素。
          • css稱作jQuery方法,我們可以用jQuery方法來操作元素,這里面的css方法可以設置元素的樣式,后續我們還會講解其他的方法。
          • 使用方法的時候需要在方法名的后面添加一個括號,括號內可以添加參數,用來進一步描述方法的作用。

          獲取元素文本

          上個例子中我們使用了一個jQuery的元素選擇器和css方法實現了改變元素樣式,接下來我們使用類選擇器和text方法獲取元素文本。

          1 <body>
          2     <h1 class="title">hello jquery</h1>
          3     <script src="script/jquery.js"></script>
          4     <script>
          5         var txt=$(".title").text();
          6         console.log(txt);
          7     </script>
          8 </body>
          • 在上面的代碼中使用$(".title")選擇器找到class值為title的元素,讓后通過text方法獲取元素的文本。
          • var可以聲明一個變量,“=”可以將獲取的文本賦值給txt變量。
          • 使用console.log()可以在控制臺輸出文本的內容。

          設置元素屬性

          我們還可以通過jQuery的attr方法來設置元素的屬性,下面的例子我們使用attr方法將img標簽的src屬性指定成一張圖片的路徑。

          1 <body>
          2     <img class="pic" src="">
          3     <script src="script/jquery.js"></script>
          4     <script>
          5         $(".pic").attr("src","images/0.jpg");
          6     </script>
          7 </body>
          • 在上面的代碼中,html標簽img并沒有設置src屬性,我們通過jQuery的attr方法設置了img標簽src屬性。
          • attr方法可以設置兩個參數,第一個參數是要設置的屬性名,第二個參數是屬性值。

          添加和刪除class

          在說添加和刪除class之前,我們先來看一個略復雜的選擇器,代碼如下所示。

           1 <body>
           2     <ul class="nav">
           3         <li>香蕉</li>
           4         <li>蘋果</li>
           5         <li>鴨梨</li>
           6     </ul>
           7     <script src="script/jquery.js"></script>
           8     <script>
           9         $(".nav li:eq(1)").css("background-color","red");
          10     </script>
          11 </body>

          上面的選擇器$(".nav li:eq(1)")我們可以將其拆分來理解

          • ".nav"可以找到class名為nav的元素
          • ".nav li"可以找到class名為nav中的所有li元素
          • ".nav li:eq(1)"可以找到class名為nav中,li標簽的第二個元素,這里需要注意的是元素的索引(編號)從0開始,所以1代表第二個元素。

          在上面的代碼中,我們將第二個li元素背景設置成了紅色。

          我們經常會使用jQuery操作元素的樣式,上面我們已經學習了css方法,但是在實際開發中,css方法并不常用,我們更多的是使用addClass和removeClass方法來操作元素的樣式,示例代碼如下所示。


          • 通過addClass方法,我們可以給元素添加一個class名active,這樣style標簽中定義的樣式就會作用于這個元素。
          • 同理,removeClass方法可以刪除元素的class名,我們會在后續的課程中講解。

          課后練習

          1. 圖卡片切換
          2. 選項卡
          3. 模態框

          【融職教育】在工作中學習,在學習中工作


          主站蜘蛛池模板: 国产精品无码不卡一区二区三区 | 中文字幕精品无码一区二区三区| 伊人精品视频一区二区三区| 无码福利一区二区三区| 国产不卡视频一区二区三区| 天堂va视频一区二区| 亚洲制服中文字幕第一区| 国产成人无码精品一区在线观看| 大帝AV在线一区二区三区| 国产精品一区视频| 人妻无码一区二区三区AV| 丰满爆乳一区二区三区| 在线精品动漫一区二区无广告| 秋霞鲁丝片一区二区三区| 日韩一区在线视频| 日美欧韩一区二去三区| 精品国产一区在线观看| 韩国女主播一区二区| 精品久久综合一区二区| 日本一区二区三区在线看| 日本一区二区三区在线观看视频| 国产精品无码亚洲一区二区三区 | 蜜臀AV免费一区二区三区| 国产精品女同一区二区| 亚洲av综合av一区| 亚洲精品一区二区三区四区乱码| 无码一区二区三区老色鬼| 日韩亚洲AV无码一区二区不卡| 国产一区二区在线视频| 3d动漫精品一区视频在线观看| 无码毛片视频一区二区本码| 亚洲AV成人精品一区二区三区 | 亚洲AⅤ无码一区二区三区在线| 国模视频一区二区| 国产精品免费综合一区视频| 国产精品区一区二区三| 99久久精品国产免看国产一区| 国产一区二区免费视频| 无码人妻一区二区三区免费手机| 国产精品亚洲一区二区在线观看| 国产日韩精品一区二区在线观看 |