成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

D3 源代碼解構(gòu)

AbnerMing / 1422人閱讀

摘要:查詢網(wǎng)上關(guān)于這三種格式的定義是如上所示,不過(guò)的實(shí)現(xiàn)不太一樣,是可以定義為任何一種分隔符,但是分隔符只能為長(zhǎng)度為的字符,是以半角符逗號(hào)作為分割符,則是以斜杠作為分隔符。

D3是一個(gè)數(shù)據(jù)可視化的javascript庫(kù),相對(duì)于highchart和echarts專注圖表可視化的庫(kù),D3更適合做大數(shù)據(jù)處理的可視化,它只提供基礎(chǔ)的可視化功能,靈活而豐富的接口讓我們能開(kāi)發(fā)出各式各樣的圖表。

D3代碼版本:“3.5.17”

D3的代碼骨架比較簡(jiǎn)潔,相比jquery來(lái)說(shuō)更適合閱讀,你可以很舒服地自上而下的看下去而不用看到一個(gè)新的函數(shù)發(fā)現(xiàn)聲明在千里之外,然后在代碼中跳來(lái)跳去。

內(nèi)部代碼流水線

基本的數(shù)學(xué)計(jì)算:最小最大、均值中值方差、偏分值……

各種集合類型: map、set、nest……

集合的操作、方法: text、html、append、insert、remove

d3的dragging

圖形操作

……

自執(zhí)行匿名函數(shù)

首先是典型的自執(zhí)行匿名函數(shù),對(duì)外提供接口,隱藏實(shí)現(xiàn)方式,實(shí)現(xiàn)私有變量等等功能。

!function() {
   // code here
}()

這里用到的是感嘆號(hào),其實(shí)和使用括號(hào)是一樣的作用,就是將函數(shù)聲明變成函數(shù)表達(dá)式,以便于函數(shù)的自執(zhí)行調(diào)用,你可以試試

function() {
  console.log("no console")
}()

這是因?yàn)镴S禁止函數(shù)聲明和函數(shù)調(diào)用混用,而括號(hào)、邏輯運(yùn)算符(+、-、&&、||)、逗號(hào)、new等都可以將函數(shù)聲明變成函數(shù)表達(dá)式,然后便可以自執(zhí)行。有人做過(guò)調(diào)查關(guān)于這些轉(zhuǎn)化的方法哪個(gè)更快,可以查看這篇博客,大概new是最慢的,相比使用括號(hào)是基本最快,感嘆號(hào)反而性能一般,所以其實(shí)用哪個(gè)都沒(méi)什么區(qū)別,當(dāng)然如果你想省敲一個(gè)符號(hào)也是可以用感嘆號(hào)的。

對(duì)外暴露私有變量d3

對(duì)于d3,采用的是創(chuàng)建私有變量對(duì)象,然后對(duì)它進(jìn)行擴(kuò)展,最后對(duì)外暴露

var d3 = {
  version: "3.5.17"
};

// code here
//...

if (typeof define === "function" && defind.amd) 
  this.d3 = d3, define(d3);
else if (typeof module == "object" && module.exports)
  module.exports = d3;
else
  this.d3 = d3;

第一種為異步模塊加載模式,第二種為同步模塊加載或者是ecma6的import機(jī)制,第三種則是將d3設(shè)置為全局變量,因?yàn)槟涿詧?zhí)行函數(shù)中,函數(shù)的環(huán)境就是全局的,所以this == window。

創(chuàng)建公用方法

d3的方法是屬于d3對(duì)象的屬性:

d3_xhr( url, mimeType, response, callback) {
  // code 
}
d3.json = function(url, callback) {
  return d3_xhr(url, "application/json", d3_json, callback);
};
function d3_json(request) {
  return JSON.parse(request.responseText);
}

不太好的是d3沒(méi)有在命名上區(qū)分哪些是私有函數(shù),哪些是公用函數(shù),不過(guò)對(duì)于通過(guò)創(chuàng)建對(duì)象來(lái)對(duì)外暴露接口的對(duì)象來(lái)說(shuō),應(yīng)該也不用去區(qū)分吧。

提取一些常用的原生函數(shù)
var d3_arraySlice = [].slice, d3_array = function(list) {
  return d3_arraySlice.call(list);
};
var d3_document = this.document;

提取slice方法,使用它來(lái)生成數(shù)組的副本,slice不會(huì)對(duì)原生數(shù)組做切割,而是會(huì)返回?cái)?shù)組的復(fù)制品,但是要注意是淺復(fù)制,對(duì)于數(shù)組中的對(duì)象、數(shù)組,是單純的引用,所以對(duì)原數(shù)組中的對(duì)象或數(shù)組的更改還是會(huì)影響到復(fù)制品。

部分代碼實(shí)現(xiàn)閱讀 一段用來(lái)測(cè)試d3_array的函數(shù),但什么情況下會(huì)重寫d3_array函數(shù)呢?

【line15】

if (d3_document) {
  var test = d3_array(d3_document.documentElement.childNodes);
  console.log(test);
  try {
    d3_array(d3_document.documentElement.childNodes)[0].nodeType;
  } catch (e) {
    console.log("catch error:", e);
    d3_array = function(list) {
      var i = list.length, array = new Array(i);
      while (i--) array[i] = list[i];
      return array;
    };
  }
}

由前面我們可以知道d3_array可以用來(lái)獲取傳入數(shù)組的副本,通過(guò)try來(lái)測(cè)試document的子節(jié)點(diǎn)的第一個(gè)子元素,一般就是header這個(gè)元素,我們通過(guò)查詢w3c可以知道nodeType為1,表示html element,感覺(jué)應(yīng)該是測(cè)試是否是瀏覽器環(huán)境,如果不是的話,就換成自己寫的函數(shù)的意思嗎?還是為了兼容一些少數(shù)的瀏覽器呢?

設(shè)置對(duì)象屬性的兼容?

【line 30】

if (d3_document) {
  try {
    d3_document.createElement("DIV").style.setProperty("opacity", 0, "");
  } catch (error) {
    var d3_element_prototype = this.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = this.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
    d3_element_prototype.setAttribute = function(name, value) {
      d3_element_setAttribute.call(this, name, value + "");
    };
    d3_element_prototype.setAttributeNS = function(space, local, value) {
      d3_element_setAttributeNS.call(this, space, local, value + "");
    };
    d3_style_prototype.setProperty = function(name, value, priority) {
      d3_style_setProperty.call(this, name, value + "", priority);
    };
  }
}

暫時(shí)不知道是為了跨瀏覽器還是跨文檔而做的檢測(cè),待研究。

數(shù)組最小值函數(shù)

【line 53】

  d3.min = function(array, f) {
    var i = -1, n = array.length, a, b;
    if (arguments.length === 1) {
      while (++i < n) if ((b = array[i]) != null && b >= b) {
        a = b;
        break;
      }
      while (++i < n) if ((b = array[i]) != null && a > b) a = b;
    } else {
      while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
        a = b;
        break;
      }
      while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
    }
    return a;
  };

首先獲取第一個(gè)可比較的元素,測(cè)試了下,發(fā)現(xiàn)對(duì)于b >= b,無(wú)論b是數(shù)字、字符串、數(shù)組甚至是對(duì)象都是可以比較的,那么什么情況下 b>=b == false呢,對(duì)于NaN來(lái)說(shuō),無(wú)論和哪個(gè)數(shù)字比較,都是false的,但是對(duì)于Infinity卻返回真,是個(gè)點(diǎn)。所以應(yīng)該是為了排除NaN這種有問(wèn)題的數(shù)字。

d3的洗牌方法
  d3.shuffle = function(array, i0, i1) {
    if ((m = arguments.length) < 3) {
      i1 = array.length;
      if (m < 2) i0 = 0;
    }
    var m = i1 - i0, t, i;
    while (m) {
      i = Math.random() * m-- | 0;
      t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;
      console.log(i, m);
    }
    return array;
  };

d3使用的洗牌算法,關(guān)于Fisher-Yates shuffle的文章可以參考一下,它的演變思路簡(jiǎn)單而優(yōu)雅:

正常的思路是

每次從原數(shù)組中隨機(jī)選擇一個(gè)元素,判斷是否已經(jīng)被選取,是的話刪除并放入新的數(shù)組中,不是的話重新選擇。

缺點(diǎn):越到后面重復(fù)選擇的概率越大,放入新數(shù)組的時(shí)間越長(zhǎng)。

優(yōu)化

為了防止重復(fù),每次隨機(jī)選擇第m張卡牌,m為待洗牌組從原始長(zhǎng)度n逐步遞減的值

缺點(diǎn):每次都要重新獲取剩余數(shù)組中的卡牌的緊湊數(shù)組,實(shí)際的效率為n2

再次優(yōu)化

就地隨機(jī)洗牌,使用數(shù)組的后一部分作為存儲(chǔ)新的洗牌后的地方,前一部分為洗牌前的地方,從而將效率提升為n。

d3.map 關(guān)于內(nèi)置對(duì)象

【line 291】

  function d3_class(ctor, properties) {
    for (var key in properties) {
      Object.defineProperty(ctor.prototype, key, {
        value: properties[key],
        enumerable: false
      });
    }
  }
  d3.map = function(object, f) {
    var map = new d3_Map();
    if (object instanceof d3_Map) {
      object.forEach(function(key, value) {
        map.set(key, value);
      });
    } else if (Array.isArray(object)) {
      var i = -1, n = object.length, o;
      if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);
    } else {
      for (var key in object) map.set(key, object[key]);
    }
    return map;
  };
  function d3_Map() {
    this._ = Object.create(null);
  }
  var d3_map_proto = "__proto__", d3_map_zero = "x00";
  d3_class(d3_Map, {
    has: d3_map_has,
    get: function(key) {
      return this._[d3_map_escape(key)];
    },
    set: function(key, value) {
      return this._[d3_map_escape(key)] = value;
    },
    remove: d3_map_remove,
    keys: d3_map_keys,
    values: function() {
      var values = [];
      for (var key in this._) values.push(this._[key]);
      return values;
    },
    entries: function() {
      var entries = [];
      for (var key in this._) entries.push({
        key: d3_map_unescape(key),
        value: this._[key]
      });
      return entries;
    },
    size: d3_map_size,
    empty: d3_map_empty,
    forEach: function(f) {
      for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);
    }
  });

關(guān)于enumerable

在這里,使用d3_Map來(lái)作為對(duì)象的構(gòu)造函數(shù),d3_class來(lái)封裝類,這里調(diào)用了Object.defineProperty來(lái)設(shè)置屬性和值,這里有一個(gè)enumerable: false的屬性,它將該屬性的可枚舉性設(shè)置為false,使得該屬性在一般的遍歷中(for...in...)等中無(wú)法被獲取,但是還是可以通過(guò)obj.key直接獲取到,如果需要獲取對(duì)象自身的所有屬性,不管enumerable的值,可以使用 Object.getOwnPropertyNames 方法。

為什么要設(shè)置這個(gè)屬性呢?我們可以看到對(duì)d3_Map構(gòu)造對(duì)象時(shí),引入了一些原生內(nèi)置的方法,其中有一個(gè)叫做empty的方法用來(lái)判斷后來(lái)設(shè)置的屬性是否為空,我們來(lái)看看這個(gè)函數(shù)的實(shí)現(xiàn):

  function d3_map_empty() {
    for (var key in this._) return false;
    return true;
  }

看完之后再結(jié)合上面提到的enumerable設(shè)置為false的屬性在for循環(huán)中會(huì)被忽略,這樣的話就不用再寫額外地條件去判斷是否為內(nèi)置屬性,很棒的實(shí)現(xiàn)方式。

數(shù)據(jù)綁定函數(shù)data

還記得D3獨(dú)特的將數(shù)據(jù)和圖形領(lǐng)域聯(lián)系起來(lái)的方式嗎?進(jìn)入(enter)--更新(update)--退出(exit) 模式。

【line 832】

d3.selectAll("div")
  .data(dataSet)
  .enter()
  .append("div")
  ;
d3.selectAll("div")
  .data(data)
  .style("width", function(d) {
     return d + "px";
  })
 ;
d3.selectAll("div")
  .data(newDataSet)
  .exit()
  .remove()
  ;

這里涉及到了三個(gè)函數(shù),data、enter、exit,每次進(jìn)行操作前我們需要先調(diào)用data對(duì)數(shù)據(jù)進(jìn)行綁定,然后再調(diào)用enter或者exit對(duì)圖形領(lǐng)域進(jìn)行操作,那么內(nèi)部實(shí)現(xiàn)原理是怎么樣的呢,看完下面這段代碼就恍然大悟了:

  d3_selectionPrototype.data = function(value, key) {
    var i = -1, n = this.length, group, node;
    if (!arguments.length) {
      value = new Array(n = (group = this[0]).length);
      while (++i < n) {
        if (node = group[i]) {
          value[i] = node.__data__;
        }
      }
      return value;
    }
    function bind(group, groupData) {
      var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
      if (key) {
        var nodeByKeyValue = new d3_Map(), keyValues = new Array(n), keyValue;
        for (i = -1; ++i < n; ) {
          if (node = group[i]) {
            if (nodeByKeyValue.has(keyValue = key.call(node, node.__data__, i))) {
              exitNodes[i] = node;
            } else {
              nodeByKeyValue.set(keyValue, node);
            }
            keyValues[i] = keyValue;
          }
        }
        for (i = -1; ++i < m; ) {
          if (!(node = nodeByKeyValue.get(keyValue = key.call(groupData, nodeData = groupData[i], i)))) {
            enterNodes[i] = d3_selection_dataNode(nodeData);
          } else if (node !== true) {
            updateNodes[i] = node;
            node.__data__ = nodeData;
          }
          nodeByKeyValue.set(keyValue, true);
        }
        for (i = -1; ++i < n; ) {
          if (i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true) {
            exitNodes[i] = group[i];
          }
        }
      } else {
        for (i = -1; ++i < n0; ) {
          node = group[i];
          nodeData = groupData[i];
          if (node) {
            node.__data__ = nodeData;
            updateNodes[i] = node;
          } else {
            enterNodes[i] = d3_selection_dataNode(nodeData);
          }
        }
        for (;i < m; ++i) {
          enterNodes[i] = d3_selection_dataNode(groupData[i]);
        }
        for (;i < n; ++i) {
          exitNodes[i] = group[i];
        }
      }
      enterNodes.update = updateNodes;
      enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
      enter.push(enterNodes);
      update.push(updateNodes);
      exit.push(exitNodes);
    }
    var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
    if (typeof value === "function") {
      while (++i < n) {
        bind(group = this[i], value.call(group, group.parentNode.__data__, i));
      }
    } else {
      while (++i < n) {
        bind(group = this[i], value);
      }
    }
    update.enter = function() {
      return enter;
    };
    update.exit = function() {
      return exit;
    };
    return update;
  };

數(shù)據(jù)綁定函數(shù)data最終返回了變量update,這個(gè)變量update一開(kāi)始為一個(gè)空集合,它擁有d3的集合操作方法,然后data函數(shù)通過(guò)調(diào)用bind函數(shù)對(duì)傳入的參數(shù)進(jìn)行逐項(xiàng)綁定,獲得update集合作為本身,以及enter集合和exit集合,最后在update上綁定了函數(shù)enter和exit,使得用戶在調(diào)用data后,可以再次調(diào)用enter和exit去獲取另外兩個(gè)集合。

關(guān)于后期debug的足跡

d3也會(huì)有bug的時(shí)候,這個(gè)時(shí)候需要對(duì)bug進(jìn)行修復(fù),然后再更新,為了方便下次找到修改的bug,在代碼里面對(duì)其進(jìn)行命名,是很好的做法:

【1167】

var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;
D3的顏色空間

D3支持五種顏色表示方式,除了我們常常接觸了rgb、hsl外,還有l(wèi)ab、hcl、cubehelix,它們之間都可以轉(zhuǎn)化為rgb,內(nèi)部的實(shí)現(xiàn)方式值得參考:

【line 1582】

  function d3_hsl_rgb(h, s, l) {
    var m1, m2;
    h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
    s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
    l = l < 0 ? 0 : l > 1 ? 1 : l;
    m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
    m1 = 2 * l - m2;
    function v(h) {
      if (h > 360) h -= 360; else if (h < 0) h += 360;
      if (h < 60) return m1 + (m2 - m1) * h / 60;
      if (h < 180) return m2;
      if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
      return m1;
    }
    function vv(h) {
      return Math.round(v(h) * 255);
    }
    return new d3_rgb(vv(h + 120), vv(h), vv(h - 120));
  }
關(guān)于csv、dsv、tsv存儲(chǔ)方式

看代碼的好處之一是能看到很多平時(shí)不會(huì)用到的接口,然后會(huì)主動(dòng)去了解是干什么的。

csv格式

在文本數(shù)據(jù)處理和傳輸過(guò)程中,我們常常遇到把多個(gè)字段通過(guò)分隔符連接在一起的需求,如采用著名的CSV格式(comma-separated values)。CSV文件的每一行是一條記錄(record),每一行的各個(gè)字段通過(guò)逗號(hào)","分隔。

dsv格式

由于逗號(hào)和雙引號(hào)這兩個(gè)特殊字符的存在,我們不能簡(jiǎn)單地通過(guò)字符串的split操作對(duì)CSV文件進(jìn)行解析,而必須進(jìn)行CSV語(yǔ)法分析。雖然我們可以通過(guò)庫(kù)的形式進(jìn)行封裝,或者直接采用現(xiàn)成的庫(kù),但畢竟各種平臺(tái)下庫(kù)的豐富程度差異很大,這些庫(kù)和split、join這樣的簡(jiǎn)單字符串操作相比也更加復(fù)雜。為此,我們?cè)贑SV格式的基礎(chǔ)上設(shè)計(jì)了一種DSV (double separated values)格式。DSV格式的主要設(shè)計(jì)目的就是為了簡(jiǎn)化CSV語(yǔ)法,生成和解析只需要replace, join, split這3個(gè)基本的字符串操作,而不需要進(jìn)行語(yǔ)法分析。

DSV的語(yǔ)法非常簡(jiǎn)單,只包括以下兩點(diǎn):

通過(guò)雙豎線"||"作為字段分隔符

把字段值中的"|"替換為"_|"進(jìn)行轉(zhuǎn)義

tsv格式

TSV 是Tab-separated values的縮寫,即制表符分隔值。

查詢網(wǎng)上關(guān)于這三種格式的定義是如上所示,不過(guò)d3的實(shí)現(xiàn)不太一樣,dsv是可以定義為任何一種分隔符,但是分隔符只能為長(zhǎng)度為1的字符,csv是以半角符逗號(hào)作為分割符,tsv則是以斜杠作為分隔符。

d3.geo

【line 2854】

geo是d3的圖形處理實(shí)現(xiàn),應(yīng)該算是核心代碼了,不過(guò)到了4.0版本被分割成依賴,并且不再有d3.geo.path了,而是改用d3.geoPath的方式去引用。

總結(jié)

版本3的d3九千多行代碼,版本4的d4則進(jìn)行了依賴分割,如果全部依賴引入的話不壓縮就要過(guò)16000行了,如果想整體去看骨架的話,版本3是比較清晰的,版本4則適合深入研究每一部分的實(shí)現(xiàn),因?yàn)橐蕾嚩挤指畹煤芮逦?,并且相互?dú)立開(kāi)。

初步了解整個(gè)d3的骨架后,接下來(lái)可以深入到代碼函數(shù)實(shí)現(xiàn)中去研究其中奧妙。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/79912.html

相關(guān)文章

  • D3 代碼解析(二)

    摘要:第一節(jié)點(diǎn)位于第二節(jié)點(diǎn)內(nèi)。例如,返回意味著在在內(nèi)部,并且在之前。這個(gè)函數(shù)返回一個(gè)函數(shù),返回的函數(shù)綁定了當(dāng)前對(duì)象并執(zhí)行。 這是繼上一篇D3源碼解構(gòu)文章后的對(duì)D3的研究筆記,筆者的能力有限,如有哪里理解錯(cuò)誤,歡迎指正。 對(duì)集合的操作 關(guān)于d3.attr 一個(gè)可以處理很多情況的函數(shù),當(dāng)只傳入一個(gè)參數(shù)時(shí),如果是string,則返回該屬性值,如果是對(duì)象,則遍歷設(shè)置對(duì)象的鍵值對(duì)屬性值,如果參數(shù)大于等...

    tainzhi 評(píng)論0 收藏0
  • 聲明式與響應(yīng)式——前端新一代數(shù)據(jù)可視化方案

    摘要:數(shù)據(jù)可視化圖表圖表作為數(shù)據(jù)可視化最常見(jiàn)的表現(xiàn)形式之一,往往被以偏概全的認(rèn)為圖表就是數(shù)據(jù)可視化。嚴(yán)格來(lái)說(shuō),數(shù)據(jù)可視化應(yīng)該是連接數(shù)據(jù)與視覺(jué)的一個(gè)映射關(guān)系,將數(shù)據(jù)映射成人更容易感知其規(guī)律的可視化結(jié)果。 題目中的新一代是個(gè)相對(duì)的概念,事實(shí)上本文即將介紹的方法已經(jīng)有了生產(chǎn)環(huán)境可用的實(shí)現(xiàn)方案(這也側(cè)面佐證了其可行性),但考慮到此方法與現(xiàn)在大部分前端項(xiàng)目中所使用的數(shù)據(jù)可視化方案相比仍有一些優(yōu)勢(shì),因此...

    xuhong 評(píng)論0 收藏0
  • 前端每周清單第 11 期:Angular 4.1支持TypeScript 2.3,Vue 2.3優(yōu)化

    摘要:斯坦福宣布使用作為計(jì)算機(jī)課程的首選語(yǔ)言近日,某位有年教學(xué)經(jīng)驗(yàn)的斯坦福教授決定放棄,而使用作為計(jì)算機(jī)入門課程的教學(xué)語(yǔ)言。斯坦福官方站點(diǎn)將它們新的課程描述為是最流行的構(gòu)建交互式的開(kāi)發(fā)語(yǔ)言,本課程會(huì)用講解中的實(shí)例。 前端每周清單第 11 期:Angular 4.1支持TypeScript 2.3,Vue 2.3優(yōu)化服務(wù)端渲染,優(yōu)秀React界面框架合集 為InfoQ中文站特供稿件,首發(fā)地址為...

    warkiz 評(píng)論0 收藏0
  • ES6常用知識(shí)點(diǎn)概述

    摘要:那之前的例子來(lái)使用一下的話,你會(huì)發(fā)現(xiàn)瀏覽器報(bào)錯(cuò)了,如圖定義的變量不允許二次修改。如圖箭頭函數(shù)沒(méi)有它自己的值,箭頭函數(shù)內(nèi)的值繼承自外圍作用域。如圖這里兩邊的結(jié)構(gòu)沒(méi)有一致,如果是的話,是可以正常解構(gòu)的。 前言 國(guó)慶假期已過(guò)一半,來(lái)篇干貨壓壓驚。 ES6,并不是一個(gè)新鮮的東西,ES7、ES8已經(jīng)趕腳了。但是,東西不在于新,而在于總結(jié)。每個(gè)學(xué)前端的人,身邊也必定有本阮老師的《ES6標(biāo)準(zhǔn)入門》或...

    keithyau 評(píng)論0 收藏0
  • 學(xué)習(xí)筆記: JS數(shù)組

    摘要:數(shù)組元素甚至可以是對(duì)象或其它數(shù)組。它執(zhí)行的是淺拷貝,這意味著如果數(shù)組元素是對(duì)象,兩個(gè)數(shù)組都指向相同的對(duì)象,對(duì)新數(shù)組中的對(duì)象修改,會(huì)在舊的數(shù)組的相同對(duì)象中反應(yīng)出來(lái)。 JS中的數(shù)組是弱類型的,數(shù)組中可以含有不同類型的元素。數(shù)組元素甚至可以是對(duì)象或其它數(shù)組。JS引擎一般會(huì)優(yōu)化數(shù)組,按索引訪問(wèn)數(shù)組常常比訪問(wèn)一般對(duì)象屬性明顯迅速。數(shù)組長(zhǎng)度范圍 from 0 to 4,294,967,295(2^...

    archieyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<