整合營銷服務商

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

          免費咨詢熱線:

          碎片時間學編程「34]:如何在 JavaScript

          碎片時間學編程「34]:如何在 JavaScript 中克隆數組?


          avaScript 提供了很多克隆數組的方法,其中大多數在性能和結果方面都非常相似。以下是一些可用選項的簡要介紹。

          擴展運算符

          ES6 引入了擴展運算符 ( ...),它提供了可能是創建數組的淺層克隆的最簡單和最常用的方法。

          let x=[1, 2, 3, 4];
          let y=[...x];
          

          Array.from()

          Array.from()有一個非常強大的 API,可以用于許多不同的事情,包括創建一個數組的副本。

          let x=[1, 2, 3, 4];
          let y=Array.from(x);
          

          Array.prototype.slice()

          與擴展運算符類似,Array.prototype.slice()可用于創建數組的淺拷貝。

          let x=[1, 2, 3, 4];
          let y=x.slice();
          

          Array.prototype.map()

          研究一個非正統的選項,Array.prototype.map()可用于將數組的每個元素映射到自身以創建一個新數組。

          let x=[1, 2, 3, 4];
          let y=x.map(i=> i);
          

          Array.prototype.filter()

          類似地,Array.prototype.filter()可用于返回true的每個元素,從而生成一個包含所有原始數組元素的新數組。

          let x=[1, 2, 3, 4];
          let y=x.filter(()=> true);
          

          對象.assign()

          最后,Object.assign()方法可以以與創建對象克隆數組完全相同的方式使用。

          let x=[1, 2, 3, 4];
          let y=Object.assign([], x);
          

          更多內容請訪問 https://www.icoderoad.com

          內容首發于工粽號:程序員大澈,每日分享一段優質代碼片段,歡迎關注和投稿!

          大家好,我是大澈!

          本文約 900+ 字,整篇閱讀約需 1 分鐘。

          今天分享一段優質 JS 代碼片段,輕松實現了對象間的深度克隆。

          老規矩,先閱讀代碼片段并思考,再看代碼解析再思考,最后評論區留下你的見解!

          const a={ x: 1, y: { y1: 'a' }, z: new Set([1, 2]) };
          const b=structuredClone(a); 
          // a !==b, a.y !==b.y, a.z !==b.z


          分享原因

          這段代碼展示了 structuredClone 方法在深度復制對象方面的應用,這對于處理復雜的數據結構非常有用。

          它比 JSON.parse(JSON.stringify()) 方法更安全,能避免一些類型轉換問題,例如:保留日期對象的原有類型,而不是轉換為字符串。

          這個方法相對簡便易用,只需將需要拷貝的對象作為參數傳入即可,項目中推薦去使用!

          代碼解析

          1. const a={ ... };

          這里定義了一個名為 a 的對象,它包含一個基本類型的屬性 x,一個嵌套對象 y ,以及一個 Set 類型的屬性 z 。

          2. structuredClone(a);

          structuredClone() 是 JavaScript 中用于深拷貝對象的方法。

          它使用結構化克隆算法創建給定值的深層拷貝。

          語法是 structuredClone(value, { transfer }) :

          value:被克隆的對象,可以是任何結構化克隆支持的類型。

          transfer(可選參數):是一個可轉移對象的數組,里面的值并沒有被克隆,而是被轉移到被拷貝對象上。

          支持多種類型:可以復制大多數內置值,如數組、普通對象、日期(Date)、正則表達式(RegExp)、集合(Set)、映射(Map)等,還包括一些 Web API 類型,如 AudioData、Blob、CryptoKey 等。

          但它的一些限制也不可忽略:

          不支持拷貝函數,嘗試復制函數會導致 DataCloneError 異常。

          不支持 DOM 節點,復制 DOM 節點也會引發異常。

          不復制屬性描述符、setter 和 getter 等元數據屬性,getter 屬性的值會被復制,但 getter 函數本身不會被復制。

          不遍歷或復制對象原型,克隆后的對象不再屬于原始構造函數的實例,不過其屬性會被復制。

          在 Web Workers 中的支持不完全,具體可查看 MDN 瀏覽器兼容性表。在不支持的平臺上,可以使用 polyfill 來模擬該方法。

          最后,附上兼容性

          OM to Image

          dom-to-image是一個js庫,可以將任意dom節點轉換為矢量(SVG)或光柵(PNG或JPEG)圖像。

          安裝

          npm install dom-to-image -S

          加載

          /* in ES 6 */
          import domtoimage from 'dom-to-image';
          /* in ES 5 */
          var domtoimage=require('dom-to-image');

          用法

          所有高階函數都接受DOM節點和渲染選項options ,并返回promises。

          1. 獲取PNG圖像base64編碼的data URL:
          <div id="my-node"></div>
          var node=document.getElementById('my-node');
          // options 可不傳
          var options={}  
          domtoimage.toPng(node, options)
              .then(function (dataUrl) {
                  var img=new Image();
                  img.src=dataUrl;
                  document.body.appendChild(img);
              })
              .catch(function (error) {
                  console.error('oops, something went wrong!', error);
              });
          1. 獲取圖像blob:
          domtoimage.toBlob(document.getElementById('my-node'))
              .then(function (blob) { 
                  console.log('blob', blob)
              });
          1. 獲取JPEG圖像base64編碼的data URL并下載:
          domtoimage.toJpeg(document.getElementById('my-node'), { quality: 0.95 })
              .then(function (dataUrl) {
                  var link=document.createElement('a');
                  link.download='my-image-name.jpeg';
                  link.href=dataUrl;
                  link.click();
          });
          1. 獲取SVGdata URL,但篩選出所有元素:
          function filter (node) {
              return (node.tagName !=='i');
          }
           
          domtoimage.toSvg(document.getElementById('my-node'), {filter: filter})
              .then(function (dataUrl) {
                  /* do something */
          });
          1. 以uint8數組的形式獲取原始像素數據,每4個數組元素表示一個像素的RGBA數據:
          var node=document.getElementById('my-node');
           
          domtoimage.toPixelData(node)
              .then(function (pixels) {
                  for (var y=0; y < node.scrollHeight; ++y) {
                    for (var x=0; x < node.scrollWidth; ++x) {
                      pixelAtXYOffset=(4 * y * node.scrollHeight) + (4 * x);
                      /* pixelAtXY is a Uint8Array[4] containing RGBA values of the pixel at (x, y) in the range 0..255 */
                      pixelAtXY=pixels.slice(pixelAtXYOffset, pixelAtXYOffset + 4);
                    }
                  }
              });

          options參數

          Name

          類型

          Default

          Description

          filter

          Function

          ——

          以DOM節點為參數的函數。如果傳遞的節點應包含在輸出中,則應返回true(排除節點意味著也排除其子節點)

          bgcolor

          String

          ——

          背景色的字符串值,任何有效的CSS顏色值。

          height

          Number

          ——

          渲染前應用于節點的高度(以像素為單位)。

          width

          Number

          ——

          渲染前應用于節點的寬度(以像素為單位)。

          style

          Object

          ——

          object對象,其屬性在渲染之前要復制到節點的樣式中。

          quality

          Number

          1.0

          介于0和1之間的數字,表示JPEG圖像的圖像質量(例如0.92=>92%)。默認值為1.0(100%)

          cacheBust

          Boolean

          false

          設置為true可將當前時間作為查詢字符串附加到URL請求以啟用清除緩存。

          imagePlaceholder

          Boolean

          undefined

          獲取圖片失敗時使用圖片的數據URL作為占位符。默認為未定義,并將在失敗的圖像上引發錯誤。

          原理

          dom-to-image使用SVG的一個特性,它允許在標記中包含任意HTML內容。

          • 遞歸地克隆原始DOM節點
          • 計算節點和每個子節點的樣式,并將其復制到相應的克隆 創建偽元素,因為它們不是以任何方式克隆的
          • 嵌入web字體 查找所有@font face聲明的web字體 解析文件URL,下載相應文件 base64編碼的內聯作為data:URLs 將所有已處理的CSS放入中,然后將其附加到克隆
          • 嵌入圖片 在嵌入圖片URL 使用backgroundCSS屬性的圖片,方法類似于字體
          • 將克隆的節點序列化為XML
          • 將XML包裝到標記中,然后包裝到SVG中,然后使其成為data URL
          • 或者,要以Uint8Array的形式獲取PNG內容或原始像素數據,可以創建一個以SVG為源的圖像元素,并將其呈現在已經創建的canvas上,從canvas讀取內容

          部分源碼分析

          dom-to-image.js

          // Default impl options
          var defaultOptions={
              // Default is to fail on error, no placeholder
              imagePlaceholder: undefined,
              // Default cache bust is false, it will use the cache
              cacheBust: false
          };
          
          var domtoimage={
              toSvg: toSvg,
              toPng: toPng,
              toJpeg: toJpeg,
              toBlob: toBlob,
              toPixelData: toPixelData,
              impl: {
                  fontFaces: fontFaces,
                  images: images,
                  util: util,
                  inliner: inliner,
                  options: {}
              }
          };
          
          if (typeof module !=='undefined')
              module.exports=domtoimage;
          else
              global.domtoimage=domtoimage;
          • defaultOptions設置默認options選項
          • domtoimage的核心api:
            • toSvg
            • toPng
            • toJpeg
            • toBlob
            • toPixelData
          • 例:toJpeg:將draw函數返回的canvas實例,使用canvas的toDataURL方法生成jpeg圖片。toSvg函數將遞歸地克隆原始DOM節點, 將克隆的節點序列化為XML,將XML包裝到標記中,然后包裝到SVG中,然后使其轉成dataURL。
          function toJpeg(node, options) {
             options=options || {};
             return draw(node, options)
                 .then(function (canvas) {
                     return canvas.toDataURL('image/jpeg', options.quality || 1.0);
                 });
          }
          復制代碼
          function draw(domNode, options) {
              return toSvg(domNode, options)
                  .then(util.makeImage)
                  .then(util.delay(100))
                  .then(function (image) {
                      var canvas=newCanvas(domNode);
                      canvas.getContext('2d').drawImage(image, 0, 0);
                      return canvas;
                  });
          
              function newCanvas(domNode) {
                  var canvas=document.createElement('canvas');
                  canvas.width=options.width || util.width(domNode);
                  canvas.height=options.height || util.height(domNode);
          
                  if (options.bgcolor) {
                      var ctx=canvas.getContext('2d');
                      ctx.fillStyle=options.bgcolor;
                      ctx.fillRect(0, 0, canvas.width, canvas.height);
                  }
          
                  return canvas;
              }
          }
          function toSvg(node, options) {
              options=options || {};
              copyOptions(options);
              return Promise.resolve(node)
                  .then(function (node) {
                      return cloneNode(node, options.filter, true);
                  })
                  .then(embedFonts)
                  .then(inlineImages)
                  .then(applyOptions)
                  .then(function (clone) {
                      return makeSvgDataUri(clone,
                          options.width || util.width(node),
                          options.height || util.height(node)
                      );
                  });
          
              function applyOptions(clone) {
                  if (options.bgcolor) clone.style.backgroundColor=options.bgcolor;
          
                  if (options.width) clone.style.width=options.width + 'px';
                  if (options.height) clone.style.height=options.height + 'px';
          
                  if (options.style)
                      Object.keys(options.style).forEach(function (property) {
                          clone.style[property]=options.style[property];
                      });
          
                  return clone;
              }
          }


          作者:知其
          https://juejin.cn/post/6988045156473634852


          主站蜘蛛池模板: 成人精品一区二区三区电影| 成人精品一区二区三区中文字幕| 亚洲熟妇无码一区二区三区导航 | 日本视频一区二区三区| 久久青草精品一区二区三区| 国产精品免费视频一区| 精品国产一区二区三区香蕉| 亚洲国产视频一区| 免费一区二区三区| 一区二区视频在线免费观看| 国产精品成人一区无码| 蜜桃AV抽搐高潮一区二区| 激情内射亚洲一区二区三区| 久久精品无码一区二区无码| 国产成人精品一区二区秒拍| 三上悠亚日韩精品一区在线| 成人区精品人妻一区二区不卡| 国产成人精品a视频一区| 丰满岳乱妇一区二区三区| 亚洲一区二区三区在线播放| 合区精品久久久中文字幕一区| 日本精品夜色视频一区二区| 小泽玛丽无码视频一区| 一区二区三区在线观看免费| 久久精品国产一区二区三区| 精品国产一区二区三区在线观看| 三上悠亚一区二区观看| 久久国产一区二区| 精品福利视频一区二区三区 | 91精品国产一区| 亚洲Av无码一区二区二三区| 日韩免费一区二区三区在线播放| 91国偷自产一区二区三区| 少妇一夜三次一区二区| 国产成人AV区一区二区三| 亚洲欧洲无码一区二区三区| 国产精品美女一区二区三区| 国内精品一区二区三区在线观看 | 成人影片一区免费观看| 久久亚洲国产精品一区二区| 人妖在线精品一区二区三区|