整合營銷服務商

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

          免費咨詢熱線:

          前端基礎 - Javascript函數傳值的方式

          文首發在個人博客上:http://www.brandhuang.com/article/1587859232291

          函數傳值

          《JavaScript高級程序設計》書中說:ECMAScript中所有函數的參數都是按值傳遞的。

          按值傳遞

          把函數外部的值復制給函數內部的參數,就和把值從一個變量復制到另一個變量一樣。

          基本數據類型

          傳遞的是原始值本身

          在函數中修改傳入的值,不會影響原來的數據

          var value = 1;
          function foo(v) {
              v = 2;
              console.log(v); //2
          }
          foo(value);
          console.log(value) // 1
          

          復雜數據類型

          傳遞的是對象的引用的副本,看下面兩個例子,看看有什么不一樣?

          // 例子1
          var obj = {
              value: 1
          };
          function foo(o) {
              o.value = 2;
              console.log(o.value); //2
          }
          foo(obj);
          console.log(obj.value) // 2
          // 例子2
          var obj = {
              value: 1
          };
          function foo(o) {
              o = 2;
              console.log(o); //2
          }
          foo(obj);
          console.log(obj.value) // 1
          

          解釋:

          對于復雜的數據類型,函數內部的臨時變量和傳入的參數指向同一個內存地址,所以有例子一,我們能通過 o.value 找到內存中的 o,也就找到了外部的 obj,所以我們修改 o.value 值的時候,也會影響 obj 中的 value 值。

          對于例子二,因為是直接對傳入的參數進行了賦值操作,這會將內部參數 o 進行重新綁定,指向了一個新的地址,所以此時修改函數內部的值不會對外部有影響。

          參考文章

          https://segmentfault.com/q/1010000003023316

          感謝你的閱讀

          先就記錄這幾個知識點吧,多了一次性也記不住,大概率你也不會來看第二遍

          etch 是 XMLHttpRequest 的升級版,使用js腳本發出網絡請求,但是與 XMLHttpRequest 不同的是,fetch 方式使用 Promise,相比 XMLHttpRequest 更加簡潔。所以我們告別XMLHttpRequest,引入 fetch 如何使用?

          一、fetch介紹

          fetch() 是一個全局方法,提供一種簡單,合理的方式跨網絡獲取資源。它的請求是基于 Promise 的,需要詳細學習 Promise ,請點擊《 Promise詳解 》。它是專門為了取代傳統的 xhr 而生的。

          1.1、fetch使用語法

          fetch(url,options).then((response)=>{
          //處理http響應
          },(error)=>{
          //處理錯誤
          })

          url :是發送網絡請求的地址。

          options:發送請求參數,

          • body - http請求參數
          • mode - 指定請求模式。默認值為cros:允許跨域;same-origin:只允許同源請求;no-cros:只限于get、post和head,并且只能使用有限的幾個簡單標頭。
          • cache - 用戶指定緩存。
          • method - 請求方法,默認GET
          • signal - 用于取消 fetch
          • headers - http請求頭設置
          • keepalive - 用于頁面卸載時,告訴瀏覽器在后臺保持連接,繼續發送數據。
          • credentials - cookie設置,默認omit,忽略不帶cookie,same-origin同源請求帶cookie,inclue無論跨域還是同源都會帶cookie。

          1.2、response 對象

          fetch 請求成功后,響應 response 對象如圖:

          • status - http狀態碼,范圍在100-599之間
          • statusText - 服務器返回狀態文字描述
          • ok - 返回布爾值,如果狀態碼2開頭的,則true,反之false
          • headers - 響應頭
          • body - 響應體。響應體內的數據,根據類型各自處理。
          • type - 返回請求類型。
          • redirected - 返回布爾值,表示是否發生過跳轉。

          1.3、讀取內容方法

          response 對象根據服務器返回的不同類型數據,提供了不同的讀取方法。分別有:

          1. response.text() -- 得到文本字符串
          2. response.json() - 得到 json 對象
          3. response.blob() - 得到二進制 blob 對象
          4. response.formData() - 得到 fromData 表單對象
          5. response.arrayBuffer() - 得到二進制 arrayBuffer 對象

          上述 5 個方法,返回的都是 promise 對象,必須等到異步操作結束,才能得到服務器返回的完整數據。

          1.4、response.clone()

          stream 對象只能讀取一次,讀取完就沒了,這意味著,上邊的五種讀取方法,只能使用一個,否則會報錯。

          因此 response 對象提供了 clone() 方法,創建 respons 對象副本,實現多次讀取。如下:將一張圖片,讀取兩次:

          const response1 = await fetch('flowers.jpg');
          const response2 = response1.clone();
          
          const myBlob1 = await response1.blob();
          const myBlob2 = await response2.blob();
          
          image1.src = URL.createObjectURL(myBlob1);
          image2.src = URL.createObjectURL(myBlob2);

          1.4、response.body()

          body 屬性返回一個 ReadableStream 對象,供用戶操作,可以用來分塊讀取內容,顯示下載的進度就是其中一種應用。

          const response = await fetch('flower.jpg');
          const reader = response.body.getReader();
          while(true) {
            const {done, value} = await reader.read();
            if (done) {
              break;
            }
            console.log(`Received ${value.length} bytes`)
          }

          response.body.getReader() 返回一個遍歷器,這個遍歷器 read() 方法每次都會返回一個對象,表示本次讀取的內容塊。

          二、請求時 POST 和 GET 分別處理

          請求方式不同,傳值方式也不同。xhr 會分別處理 get 和 post 數據傳輸,還有請求頭設置,同樣 fetch 也需要分別處理。

          2.1、get 方式

          只需要在url中加入傳輸數據,options中加入請求方式。如下面代碼所示:

          <input type="text" id="user"><br>
          <input type="password" id="pas"><br>
          <button onclick="login()">提交</button>
          <script>
           function login(){
            fetch(`http://localhost:80/fetch.html?user=${user.value}&pas=${pas.value}`,{
             method:'GET'
            }).then(response=>{
             console.log('響應',response)
            })
           }
          </script>

          2.2、post 方式

          使用 post 發送請求時,需要設置請求頭、請求數據等。

          將上個實例,改寫成 post 方式提交數據,代碼如下:

          fetch(`http://localhost:80/ES6練習題/53fetch.html`,{
           method:'POST',
           headers:{
            'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
           },
           body:`user=${user.value}&pas=${pas.value}`
           }).then(response=>{
            console.log('響應',response)
          })

          如果是提交json數據時,需要把json轉換成字符串。如

          body:JSON.stringify(json)

          如果提交的是表單數據,使用 formData轉化下,如:

          body:new FormData(form)

          上傳文件,可以包含在整個表單里一起提交,如:

          const input = document.querySelector('input[type="file"]');
          
          const data = new FormData();
          data.append('file', input.files[0]);
          data.append('user', 'foo');
          
          fetch('/avatars', {
            method: 'POST',
            body: data
          });

          上傳二進制數據,將 bolb 或 arrayBuffer 數據放到body屬性里,如:

          let blob = await new Promise(resolve =>   
            canvasElem.toBlob(resolve,  'image/png')
          );
          
          let response = await fetch('/article/fetch/post/image', {
            method:  'POST',
            body: blob
          });

          三、fetch 常見坑

          3.1、fetch兼容性

          fetch原生支持率如圖:

          fetch 是相對較新的技術,IE瀏覽器不支持,還有其他低版本瀏覽器也不支持,因此如果使用fetch時,需要考慮瀏覽器兼容問題。

          解決辦法:引入 polyfill 完美支持 IE8 以上。

          • 由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
          • 引入 Promise 的 polyfill:es6-promise
          • 引入 fetch 探測庫:fetch-detector
          • 引入 fetch 的 polyfill: fetch-ie8
          • 可選:如果你還使用了 jsonp,引入 fetch-jsonp
          • 可選:開啟 Babel 的 runtime 模式,現在就使用 async/await

          polyfill 的原理就是探測fetch是否支持,如果不支持則用 xhr 實現。支持 fetch 的瀏覽器,響應中文會亂碼,所以使用 fetch-detector 和 fetch-ie8 解決亂碼問題。

          3.2、fetch默認不帶cookie

          傳遞cookie時,必須在header參數內加上 credentials:'include',才會像 xhr 將當前cookie 帶有請求中。

          3.3、異常處理

          fetch 不同于 xhr ,xhr 自帶取消、錯誤等方法,所以服務器返回 4xx 或 5xx 時,是不會拋出錯誤的,需要手動處理,通過 response 中的 status 字段來判斷。

          sp中四種傳遞參數的方法,我覺得總結一下,挺好的,以備后用!

          1、form表單

          2、request.setAttribute();和request.getAttribute();

          3、超鏈接:<a herf="index.jsp"?a=a&b=b&c=c>name</a>

          1、form表單

          form.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           form.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           
           <h2 style="font-family:arial;color:red;font-size:25px;text-align:center">登錄頁面</h2> 
           
           <form action="result.jsp" method="get" align="center"> 
           姓名:<input type="text" name="name" size="20" value="" maxlength="20"><br/> 
           
           密碼:<input type="password" name="password" size="20" value="" maxlength="20"><br/> 
           
           <!--在愛好前空一個空格,是為了排版好看些--> 
           
           愛好:<input type="checkbox" name="hobby" value="唱歌">唱歌 
           <input type="checkbox" name="hobby" value="足球">足球 
           <input type="checkbox" name="hobby" value="籃球">籃球<br/><br/> 
           
           <input type="submit" name="submit" value="登錄"> 
           <input type="reset" name="reset" value="重置"><br/> 
           </form> 
           
           </body> 
          </html>
          

          result.jsp:

           1 <%@page language="java" import="java.util.*" pageEncoding="GB2312"%> 
           2 <html> 
           3 <head> 
           4 <title> 
           5 result.jsp file 
           6 </title> 
           7 </head> 
           8 
           9 <body bgcolor="ffffff"> 
          10 <% 
          11 request.setCharacterEncoding("GB2312"); 
          12 
          13 String name=request.getParameter("name"); 
          14 name=new String(name.getBytes("iso-8859-1"),"GB2312"); 
          15 
          16 String pwd=request.getParameter("password"); 
          17 String[] hobby=request.getParameterValues("hobby");//注意這里的函數是getParameterValues()接受一個數組的數據 
          18 
          19 %> 
          20 
          21 <% 
          22 if(!name.equals("") && !pwd.equals("")) 
          23 { 
          24 %> 
          25 
          26 您好!登錄成功!<br/> 
          27 姓名:<%=name%><br/> 
          28 密碼:<%=pwd%><br/> 
          29 愛好:<% 
          30 for(String ho: hobby) 
          31 { 
          32 ho=new String(ho.getBytes("iso-8859-1"),"GB2312"); 
          33 out.print(ho+" "); 
          34 } 
          35 %> 
          36 <% 
          37 } 
          38 else 
          39 { 
          40 %> 
          41 請輸入姓名或密碼! 
          42 <% 
          43 } 
          44 %> 
          45 </body> 
          46 </html>
          

          注意:form表單的提交方式為get,在參數傳遞時會遇到中文亂碼的問題,一個簡單的解決方法是,將接受到的字符串先轉換成一個byte數組,再用String構造一個新的編碼格式的String,如:

          1 String name=request.getParameter("name"); 
          2 name=new String(name.getBytes("iso-8859-1"),"GB2312"); 
          

          如果form表單的提交方式為post,解決亂碼問題的簡單辦法是,使用 request.setCharacterEncoding("GB2312");設置request的編碼方式。

          為什么會出現中文亂碼問題呢?因為Tomcat服務器默認的系統編碼方式為iso- 8859-1,你傳遞參數給服務器時,使用的是默認的iso-8859-1的編碼方式,但是服務器向你返回信息時,是按page指令中設置的編碼方式, 如:<%@page language="java" import="java.util.*" pageEncoding="GB2312"%>,這樣就混合了兩種編碼方式,所以會出現亂碼,所以解決之道就是統一傳遞和接收的編碼方式。

          2、request.setAttribute()和request.getAttribute()

          set.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           set.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           <% 
           request.setAttribute("name","心雨"); 
           %> 
           <jsp:forward page="get.jsp"/> 
           </body> 
          </html>
          

          get.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           get.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           <% 
           out.println("傳遞過來的參數是:"+request.getAttribute("name")); 
           %> 
           </body> 
          </html> 
          

          request.setAttribute()和request.getAttribute()是配合<jsp:forward>或是include指令來實現的。

          3、超鏈接:<a herf="index.jsp?a=a&b=b&c=c">name</a>

          href.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           href.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           <a href="getHerf.jsp?name=心雨&password=123">傳遞參數</a> 
           </body> 
          </html> 
          

          getHref.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           getHref.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           <% 
           String name=request.getParameter("name"); 
           name=new String(name.getBytes("iso-8859-1"),"gb2312"); 
           
           out.print("name:"+name); 
           %> 
           <br/> 
           <% 
           out.print("password:"+request.getParameter("password")); 
           %> 
           </body> 
          </html> 
          

          這種傳遞參數的方法和form表單的get方式類似,是通過地址欄傳遞的參數,其亂碼解決方法也和form 的get方式一樣。

          4、<jsp:param>

          param.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           param.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           
           <%request.setCharacterEncoding("GB2312");%> 
           
           <jsp:forward page="getParam.jsp"> 
           <jsp:param name="name" value="心雨"/> 
           <jsp:param name="password" value="123"/> 
           </jsp:forward> 
           
           </body> 
          </html>
          

          getParam.jsp:

          <%@page contentType="text/html; charset=GB2312"%> 
          <html> 
           <head> 
           <title> 
           getParam.jsp file 
           </title> 
           </head> 
           
           <body style="background-color:lightblue"> 
           <% 
           String name=request.getParameter("name"); 
           out.print("name:"+name); 
           %> 
           <br/> 
           <% 
           out.print("password:"+request.getParameter("password")); 
           %> 
           </body> 
          </html> 
          

          這里發現了一個奇怪的問題,還是在中文亂碼的問題上,在form表單的例子中,如果傳遞方式為post,則只需要在接收參數的頁面設置request的編 碼方式就可以了,即request.setCharacterEncoding("GB2312");,注意是在接收參數的頁面,如果將該句放到form 表單里,那么不起作用,仍然是亂碼。而在本例中,為了使傳遞的參數不出現亂碼,卻是將 request.setCharacterEncoding("GB2312");放在發送參數的頁面中,才會正常顯示中文,放在接收參數的頁面中,不起 作用。也許這就是<jsp:param>和form表單傳遞參數不同的地方。為什么會有這個不同呢?可能是因為form表單中的參數是由客戶 端傳送到服務端上的,需要經過一個request的打包過程,但是<jsp:param>傳遞的參數本身就是在服務器端的,不需要經歷由客戶 端到服務端這么一個過程,但是服務器里的參數傳遞是這么回事呢?這個問題,我不知道了!真是知識是一個擴大的圓圈,你知道的越多,那么不知道的就越多!努 力吧!


          主站蜘蛛池模板: 国产免费一区二区三区在线观看| 国产一区二区三区手机在线观看| 国产午夜毛片一区二区三区| 中文字幕精品一区二区精品| 国产香蕉一区二区三区在线视频 | 狠狠色成人一区二区三区| 日本片免费观看一区二区| 日韩精品一区二区三区影院 | 无码中文人妻在线一区| 亚洲永久无码3D动漫一区| 日本一道一区二区免费看| 色偷偷久久一区二区三区| 亚洲第一区精品观看| 国产微拍精品一区二区| 久久精品国产第一区二区三区 | 伊人激情AV一区二区三区| 一区二区和激情视频| 日本一区二区不卡视频| 一区精品麻豆入口| 国模精品视频一区二区三区| 2020天堂中文字幕一区在线观 | 国产精品毛片VA一区二区三区| 国产一区二区三区无码免费| 亚洲AV成人精品日韩一区| 91在线看片一区国产| 久久99精品国产一区二区三区 | 国产美女av在线一区| 精品女同一区二区三区免费播放| 亚洲一区二区三区成人网站| 99精品国产一区二区三区不卡| 亚洲日韩国产精品第一页一区| 亚洲国产精品第一区二区三区| 日韩美女视频一区| 日本精品无码一区二区三区久久久| 乱精品一区字幕二区| 久久一区不卡中文字幕| 亚洲线精品一区二区三区| 国产一区二区精品久久岳 | 濑亚美莉在线视频一区| 天堂Av无码Av一区二区三区| 精品无码一区二区三区在线|