92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线

首頁

網頁設計基礎之HTML(一)

seo達人

網頁設計基礎之HTML(一)

1.Web的基本概念

web(World Wide Web)即全球廣域網,也稱為萬維網,它是一種基于超文本和HTTP的、全球性的、動態交互的、跨平臺的分布式圖形信息系統。是建立在Internet上的一種網絡服務,為瀏覽者在Internet上查找和瀏覽信息提供了圖形化的、易于訪問的直觀界面,其中的文檔及超級鏈接將Internet上的信息節點組織成一個互為關聯的網狀結構。

主要包含結構,表現和行三個方面



2.HTML簡介

<!DOCTYPE html> 聲明為 HTML5 文檔

<html> 元素是 HTML 頁面的根元素

<head> 元素包含了文檔的元(meta)數據

<title> 元素描述了文檔的標題

<body> 元素包含了可見的頁面內容

<h1> 元素定義一個大標題

<p> 元素定義一個段落

<標記名>內容</標記名> 雙標記,也稱標記體

<標記名/> 單標記,也稱空標記

<!--注釋內容--> 注釋標記

<標記名 屬性1="屬性值1" 屬性2="屬性值2">內容<//標記名>

<title>網頁標題名</title> 設置頁面標題標記

<meta/> 定義頁面原信息

<link> 引用外部文件標記

1

2

3

4

5

6

7

8

9

10

11

12

13

14

注意元素的就近原則

補充:link的屬性 請參考此網址



3.HTML入門

①HTML的概念:HTML 是用來描述網頁的一種語言。

②HTML的文本控制標記

1.標題標記:

標題(Heading)是通過<h1> - <h6>標簽進行定義的。



對齊方式:

left:設置標題文字左對齊

center:設置標題文字居中

ringt: 設置標題文字右對齊

使用方法 <h2 align="left">二級標題 左對齊</h2>



2.段落標記

段落是通過 <p>標簽定義的;其他同標題標記一致。



3.水平線標記<hr/>

相關屬性

使用方法<hr color="red" align="left" size="5" width"600"/>



4.換行標記<br/>

1.1文本樣式標記

font的屬性



1.2文本格式化標記

詳情請點我



1.3特殊字符標記

詳情請點我,并查看HTML字符實體部分



4.附上本節課的腦圖





注:本文參考自菜鳥教程


字面量方式和new方式的區別及用法

seo達人

一 - 字面量方式和new方式

?每次創建數組或對象的時候,都能用以下兩種方法創建:咦?有什么區別呢?還有哪些可以有這兩種方法呢?我到底用哪一種呢?



var arr = [];//字面量方法創建數組

var arr = new Array();//實例化構造函數方法創建數組



var obj = {};//字面量方法創建對象

var obj = new Object();//實例化構造函數方法創建對象



二 - 哪些對象可以new?

?只要存在構造函數的都可以new出來。



var num = new Number();

var boo = new Boolean(); 

var str = new String(); 

var arr = new Array(); 

var obj = new Object(); 

var fn = new Function();

var reg = new RegExp();

var date = new Date();



基本上來說 js中對象,除了null ,undefined,其他的都是可以用new出來的。



三 - 字面量是什么?

字面量表示如何表達這個值,一般除去表達式,給變量賦值時,等號右邊都可以認為是字面量。



JavaScript支持字面量,允許使用一種簡潔而可讀的記法來創建對象、數組



字面量分為:字符串字面量(string literal )、數組字面量(array literal)和對象字面量(object literal),另外還有函數字面量(function literal)等等。



var num = 1;

var boo = true;

var str = "a";

var arr = [];

var obj = {};

var fn = function(){};

var reg = /\s/g;



四 - 兩種的區別

字面量語法簡單,直接,優雅

也沒有必要去使用new去調用構造方法,減少代碼,減少代碼運算量。

那new這個操作符到底做了什么?

var arr = new Array();

/

new:

       1:var obj = {};

       2:obj.proto = Array.prototype;

       3:Array.call(obj);

/



五 - 使用哪一種?

字面量比new

比如:{}是字面量,可以立即求值



而new Object()本質上是方法(只不過這個方法是內置的)調用, 既然是方法調用,就涉及到在proto鏈中遍歷該方法,當找到該方法后,又會生產方法調用必須的堆棧信息,方法調用結束后,還要釋放該堆棧。

————————————————


JS實現xml與json互轉且基本保持原樣

seo達人



如果非要代碼實現的話,github上一個不錯的js庫(X2JS):https://github.com/abdolence/x2js

自己寫了demo測試了一下:



<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title></title>

</head>

<body>

</body>

<script src="js/xml2json.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">

var xmlText =

'<mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="220" y="90" width="120" height="80" as="geometry"/></mxCell><mxCell id="3" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1"><mxGeometry x="410" y="110" width="80" height="80" as="geometry"/></mxCell></root></mxGraphModel>';

console.log("原始數據xml:"+xmlText);

var x2js = new X2JS();

var jsonObj = x2js.xml_str2json( xmlText );

console.log(jsonObj);

var xmlAsStr = x2js.json2xml_str( jsonObj );

console.log(xmlAsStr);

</script>

</html>

效果如下:







基本能還原,只是""變成了'',這個應該問題不大的。






DataGridView(VS中表格)刪除和刷新

seo達人

功能描述:右擊表格中對應的行,進行刪除或者刷新的操作。

先往DataGridView上拖一個ContextMenuStrip控件





在下面分別輸入刪除與刷新





雙擊刪除,輸入代碼:



  private void 刪除ToolStripMenuItem_Click_1(object sender, EventArgs e)

        {

            try

            {

                DialogResult dr = MessageBox.Show("確定刪除嗎?", "提示", MessageBoxButtons.OKCancel);

                if (dr == DialogResult.OK)

                {

                    //獲取選中行的數據

                    Facade.FoodMenuCateFa?ade fa?ade = new Facade.FoodMenuCateFa?ade();

                    Entity.T_FoodMenuCate t_Food = new Entity.T_FoodMenuCate();

                    t_Food.CateName = dataFood.CurrentRow.Cells[1].Value.ToString();

                    int list1 = fa?ade.DeleteFoodMenu(t_Food);



                    frmTips f = frmTips.GetInstance("刪除完成");

                    f.Show();

                }



            }

            catch (Exception ex)

            {

                MessageBox.Show(ex.Message);

            }

        }



雙擊刷新,輸入代碼:

        private void 刷新ToolStripMenuItem_Click(object sender, EventArgs e)

        {//通過走七層查詢出數據庫中新的內容:

            Facade.FoodMenuCateFa?ade fa?ade = new Facade.FoodMenuCateFa?ade();

            Entity.T_FoodMenuCate t_Food = new Entity.T_FoodMenuCate();

            List<Entity.T_FoodMenuCate> list = fa?ade.SelectFoodMenu(t_Food);

            //把值賦給表格

            dataFood.DataSource = list;

        }


前端解決跨域問題的常用方法

seo達人

首先,跨域是什么?



只要協議、域名、端口有任何一個不同,都被當作是不同的域。為什么三者任何一個不同就會產生跨域呢,想想也很容易知道,要是很隨便引用什么外部文件,不同標簽下的頁面引用類似的彼此的文件,瀏覽器很容易懵逼的,保障不了安全問題,但在安全限制的同時也給注入iframe或是ajax請求上帶來了不少麻煩。所以我們要通過一些方法使本域的js能夠操作其他域的頁面對象或者使其他域的js能操作本域的頁面對象



但有兩點至少要清楚:



如果是協議和端口造成的跨域問題“前臺”是無能為力的;

在跨域問題上,域僅僅是通過“URL的首部”來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上。

(“URL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and ports must match”。)

1.通過HTML5的postMessage方法跨域



頁面M通過postMessage方法發送消息如下:



window.onload = function() {  

    var iframe_dom = document.getElementById('iframId');  

    var targetOrigin = ";

    iframe_dom.contentWindow.postMessage('hello world!', targetOrigin);  

};

備注:



postMessage的使用方法:



originwindow.postMessage(message, targetOrigin);



originwindow:是說的目標窗口,即要給某個window發消息,是 window.frames 屬性的成員或者由 window.open 方法創建的窗口

message: 是要發送的消息,類型為 String、Object (但IE8、9 不支持)

targetOrigin: 是限定消息接收范圍,不限制請使用 '*

頁面N通過message事件監聽并接受消息如下:



let onmessage = function (event) {  

  var data = event.data;//由發送窗口傳過來的消息內容  

  var origin = event.origin;//由發送窗口傳過來的消息來源地址  

  var source = event.source;//源Window對象  

  if(origin=="
;

    console.log(data);//hello world!  

  }  

};  

if (typeof window.addEventListener != 'undefined') {  

  window.addEventListener('message', onmessage, false);  

} else if (typeof window.attachEvent != 'undefined') {  

  //for ie  

  window.attachEvent('onmessage', onmessage);  

}

或者為了防止接入方的命名沖突,也可以約定事件名,以此加以區分



例如



window.addEventListener("message", function(event) {

  if (

    event &&

    typeof event.data == "object" &&

    event.data.event == "FUNCTION_NAME"

){

document.getElementById("val").innerHTML = event.data.value;

} });

2.通過JSONP



上面那種方式的通信是雙向的,頁面與iframe或是頁面與頁面之間的



JSONP主要是封裝好的請求方式添加callback,這個callback是由前后端約定好的



它的優劣勢:



JSONP的優點:它不像XMLHttpRequest對象實現的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都可以運行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調用callback的方式回傳結果。

JSONP的缺點:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題;無法判斷它是否請求成功,只能通過timeout

3.CORS跨域



實現CORS通信的關鍵是服務器端,只要服務端那邊實現了CORS接口,就可以跨源通信



CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS背后的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功還是失敗。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對于開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺



服務器端對于CORS的支持,主要就是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置,便可以允許Ajax進行跨域的訪問



 



CORS和JSONP對比



JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求。



使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。



JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS)。



CORS與JSONP相比,顯然更為先進、方便和可靠。



4.設置代理



目前市場上用vue技術不在少數,下面介紹一種配置代理方式



在vue.config.js該文件里面配置如下:



 devServer: {

        port: 8001,

        open: true,

        disableHostCheck: true,

        proxy: {

            '/api': {

                target: 'https:/xxx.com',

                secure: true, // false為http訪問,true為https訪問

                ws: true,

                changeOrigin: true,

                pathRewrite: {

                    '^/api': ''

                }

             }

        }

 }

 



后面請求是需要帶上‘/api’請求即可


ES6的解構賦值的用途總結

seo達人

二 - ES6的解構賦值的用途總結

2 - 什么是ES6解構

在ES6中添加了一個新屬性:解構,允許你使用類似數組或對象字面量的語法將數組和對象的屬性賦給各種變量。解構是一種打破數據結構,將其拆分為更小部分的過程,允許我們將右邊的表達式看起來也像變量聲明一般,然后在左邊將值一一提取。 解構這種賦值語法較為簡潔,比傳統的屬性訪問更為清晰。

還不了解什么是解構賦值的,請參考:https://blog.csdn.net/azxqwe123/article/details/103296603

下面只講怎么應用:



2.1 - ES6解構賦值7種場景案例—用途

(1)交換變量的值



[x, y] = [y, x];

上面代碼交換變量x和y的值,這樣的寫法不僅簡潔,而且易讀,語義非常清晰。



(2)從函數返回多個值



函數只能返回一個值,如果要返回多個值,只能將它們放在數組或對象里返回。有了解構賦值,取出這些值就非常方便。



// 返回一個數組



function example() {

  return [1, 2, 3];

}

var [a, b, c] = example();



// 返回一個對象



function example() {

  return {

    foo: 1,

    bar: 2

  };

}

var { foo, bar } = example();



(3)函數參數的定義



解構賦值可以方便地將一組參數與變量名對應起來。



// 參數是一組有次序的值

function f([x, y, z]) { ... }

f([1, 2, 3]);



// 參數是一組無次序的值

function f({x, y, z}) { ... }

f({z: 3, y: 2, x: 1});



(4)提取JSON數據



解構賦值對提取JSON對象中的數據,尤其有用。



var jsonData = {

  id: 42,

  status: "OK",

  data: [867, 5309]

};



let { id, status, data: number } = jsonData;



console.log(id, status, number);

// 42, "OK", [867, 5309]

上面代碼可以快速提取JSON數據的值。



(5)函數參數的默認值



jQuery.ajax = function (url, {

  async = true,

  beforeSend = function () {},

  cache = true,

  complete = function () {},

  crossDomain = false,

  global = true,

  // ... more config

}) {

  // ... do stuff

};





指定參數的默認值,就避免了在函數體內部再寫var foo = config.foo || ‘default foo’;這樣的語句。



(6)遍歷Map結構



任何部署了Iterator接口的對象,都可以用for…of循環遍歷。Map結構原生支持Iterator接口,配合變量的解構賦值,獲取鍵名和鍵值就非常方便。



var map = new Map();

map.set('first', 'hello');

map.set('second', 'world');



for (let [key, value] of map) {

  console.log(key + " is " + value);

}

// first is hello

// second is world

如果只想獲取鍵名,或者只想獲取鍵值,可以寫成下面這樣。



// 獲取鍵名

for (let [key] of map) {

  // ...

}



// 獲取鍵值

for (let [,value] of map) {

  // ...

}



(7)輸入模塊的指定方法



加載模塊時,往往需要指定輸入那些方法。解構賦值使得輸入語句非常清晰。



const { SourceMapConsumer, SourceNode } = require("source-map");


vue項目刷新當前頁面的幾種方式

seo達人

在vue項目中,經常會遇到需要刷新當前頁面的需求。

因為vue-router判斷如果路由沒有變化,是不會刷新頁面獲取數據的。



方式1:go(0)和reload()

通過location.reload()或是this.$router.go(0)兩種強制刷新方式,相當于按F5,會出現瞬間白屏,體驗差,不推薦。



方式2:定義一個空白路由頁面,路由跳轉到該空白頁后立馬跳回當前頁,實現路由刷新。

在router路由表中定義一個空白路由,



 // 強制刷新當前頁所用的中間跳轉頁

   {

        path: '/redirect/:path*',

        component: () => import('@/views/redirect/index')

  }



寫一個空白路由組件



//redirect/index

<script>

export default {

  created() {

    const { params, query } = this.$route

    const { path } = params

    this.$router.replace({ path: '/' + path, query })

  },

  render: function(h) {

    return h() // avoid warning message

  }

}

</script>





在需要刷新的頁面使用



refresh() {

      // 刷新當前路由

      const { fullPath } = this.$route

      this.$router.replace({

        path: '/redirect' + fullPath

      })

    }



這種方式,基本上能夠應付絕大多數情況,推薦使用。

但是,有時候,有一些極端情況下,這種刷新不起作用,而又不想用第一種那種毛子般的簡單粗暴的方式的話,下面的方式可以選擇使用。



方式3:provede/inject 方式

vue官方文檔說了,這個依賴注入方式是給插件開發使用的,普通應用中不推薦使用。

但是,效果卻很好。

app.vue修改



<template>

  <div id="app">

    <router-view v-if="isRouterAlive" />

  </div>

</template>

<script>

export default {

  name: 'App',

  provide() {

    return {

      reload: this.reload

    }

  },

  data() {

    return {

      isRouterAlive: true

    }

  },

  methods: {

    reload() {

      this.isRouterAlive = false

      this.$nextTick(function(){

        this.isRouterAlive = true

      })

    }

  }

}

</script>





使用的時候:

demo.vue



<template>

  <div class="container">

  xxx

  </div>

</template>



<script>

export default {

  inject: ['reload], // 依賴注入

  name: 'Demo',

  computed: {

    message() {

      return '抱歉,您訪問的頁面地址有誤或者該頁面不存在...'

    }

  },

  methods: {

  handleReload() {

  this.reload() // 直接在需要刷新的方法中調用這個reload()

}

  }

}

</script>



<style lang="scss" scoped>

</style>



原理就是通過依賴注入的方式,在頂部app通過v-if的顯示隱藏來強制切換顯示,以此來讓vue重新渲染整個頁面,app中通過provide方式定義的reload方法,在它的后代組件中,無論嵌套多深,都能夠觸發調用這個方法。具體說明查看官方文檔。


用three.js構建自己的后處理渲染器第一篇---抗鋸齒的選擇

seo達人

說到渲染引擎就不得不提到延遲渲染,基本上一個引擎如果沒有實現延遲渲染就不能說是一個好的渲染引擎,不過可惜的是three.js并沒有實現延遲渲染(ps:呼吁作者趕緊實現mrt吧)。由于沒有mrt和延遲渲染,本來不打算寫后處理的,但是即使沒有,我們也希望能實現一些炫酷的效果,那就在現在的基礎上對three.js進行簡單的改造來實現一套高性能的后處理渲染器吧。

要實現后處理我們首先要考慮需求,是否要兼顧移動端,是否要兼顧大屏(4k),是否要支持webgl1,是否要在各種顯卡中都有一個還算不錯的性能。目前我主要考慮的是:性能要好,可以兼顧大屏,不打算完美支持webgl1,盡量多使用webgl2的特性。后面所有的性能測試為都以N卡作為性能測試指標,先不管AMD卡(AMD抗鋸齒的處理性能會高些的,但是動態處理性能會偏低,這里有很多細節問題)

好了,我們關心的是好的性能,盡量多使用webgl2的特性,盡量能兼顧大屏(這里主要是要注意顯存問題),現在開始準備我們的渲染器吧

要完成一個后處理渲染器,我們首先要考慮抗鋸齒,常用的有超采樣技術和多重采樣技術,具體可以看這個介紹 添加鏈接描述

three.js已經實現了SSAA,SMAA,TAA這三種超采樣技術,效果都還不錯,具體實現three.js都有例子,就不詳細說明了。SSAA抗鋸齒效果是最好的,但是性能最差,現實情況下根本無法使用。SMAA性能會好一些,2000個物體差不多掉15幀吧(SMAA比FXAA計算稍微復雜一些,SMAA研究的少,不知道能不能解決line的鋸齒問題,如果知道的歡迎留言)。SMAA效果基本可以接受,但是2000個物體掉的幀率還是有點多,這個也不是我們首選的。TAA效果很好,如果場景里面很少動的東西,它是個不錯的選擇,如果有運動的物體或者動畫等等,基本上抗鋸齒就沒效果了,理論上應該可以實現動態的TAA,但是用目前的技術很難實現。所以TAA先不考慮加入我們的后處理渲染器(真實使用場景下一般都有動畫或者貼圖流動效果,所以TAA無法使用)。

SMAA:效果不錯,開銷15幀左右(2000物體)

SSAA:效果最好,開銷太大 (2000物體基本已經沒有了幀率)





TAA:效果基本和SSAA差不多,但目前只有靜止的時候才有效果



再來看看多重采樣MSAA,這個特性必須使用webgl2,是webgl提供的方式,和瀏覽器自身的抗鋸齒原理一樣,效果不錯,和正常渲染的結果沒有區別,性能開銷也不是太大,前提是我們不要使用stencilbuffer。而且three.js MSAA這塊的釋放有些小問題,詳細可以在deallocateRenderTarget這個接口中進行修改?,F在我們可以把MSAA作為主要的抗鋸齒技術。MSAA雖然性能開銷不大,但是唯一的不足是比較吃顯存,如果是大屏,而且顯卡不好的話還是容易崩,無法開啟。因此我們還要繼續選擇一個開銷小不吃顯存的抗鋸齒(當然也可以考慮SMAA,目前由于幀率開銷較大(2000物體掉了15幀左右),我們不考慮加入SMAA)

MSAA:基本沒有幀率開銷,效果不錯,但是耗費顯存(2000物體)



最后的備選方案就是FXAA了,FXAA可以參考這個文章:添加鏈接描述講的很詳細,FXAA性能開銷很小,但是效果很一般,特別是細線的鋸齒沒法解決,轉動攝影機邊緣的閃動效果也無法解決,而且還有一個問題是由于FXAA就是靠邊緣模糊抗鋸齒,所以必然導致畫面會略有模糊。但是它最大的好處是開銷很小而且不耗費顯存,并且集成到后處理渲染器中最簡單。但是當顯存不足顯卡太差的時候它還是個不錯的選擇。因此需要加入FXAA。

FXAA:效果一般,開銷很小,無法解決線的鋸齒問題,帶來模糊(2000物體)

我們看了下各大引擎,基本每個引擎都實現了FXAA,還有很多引擎實現了FXAA3,FXAA3效果會好一些,但是依然無法解決線的問題。cesium的抗鋸齒就是完全采用FXAA3,效果還可以接受,所以目前我們把cesium的fxaa3_11拿過來用,最終引擎選擇使用MSAA加FXAA3_11的抗鋸齒策略(當然SMAA和TAA也可以選擇)。


js reduce()

seo達人

是什么

ES5提供的數組的方法。

reduce() 方法接收一個函數作為回調函數(accumulator),數組中的每個值(從左到右)開始縮減(其實就是從左往右開始對每個數執行回調函數),最終為一個值。



PS: 回調函數的返回結果類型和傳入的初始值相同



語法以及參數

arr.reduce(  callback(accumulator, currentValue,index ,array ) ,initialValue )

1

initialValue 可選

如果有的話則作為,第一次調用 callback函數時的第一個參數的值。

如果沒有提供初始值,callback則使用數組的第一個元素,作為第一次調用的初始值。

在沒有初始值的空數組上調用 reduce 將報錯。



accumulator

默認傳入上一次調用回調函數的的返回值。

初始值: initialValue存在的話,則是initialValue 若沒有則是數組的第一個元素



currentValue

數組中正在處理的元素。



index 可選

數組中正在處理的當前元素的索引。 如果提供了initialValue,則起始索引號為0,否則從索引1起始。



array可選

調用reduce()的數組



一個小小的例子

例1 無initialValue

var  arr = [1, 2, 3, 4, 5];

sum = arr.reduce(function(result, cur, index, arr) {

    console.log(result, cur, index,arr);

    return result+ cur;

})

console.log(sum) // 最后的結果是15



result cur index arr

第1次 1 2 1 [1, 2, 3, 4, 5]

第2次 3 3 2 [1, 2, 3, 4, 5]

第3次 6 4 3 [1, 2, 3, 4, 5]

第4次 10 5 4 [1, 2, 3, 4, 5]

例2 有initialValue 傳入10

var  arr = [1, 2, 3, 4, 5];

sum = arr.reduce(function(result, cur, index, arr) {

    console.log(result, cur, index,arr);

    return result+ cur;

},10)

console.log(sum) // 最后的結果是25



result cur index arr

第1次 10 1 0 [1, 2, 3, 4, 5]

第2次 11 2 1 [1, 2, 3, 4, 5]

第3次 13 3 2 [1, 2, 3, 4, 5]

第4次 16 4 3 [1, 2, 3, 4, 5]

第5次 20 5 4 [1, 2, 3, 4, 5]

回調函數的返回值

上面的例子返回的都是一個整型數字,如果希望返回其他類型的數據呢?



這個就跟accumulator的初始值有關系了。

下面的例子我們傳入的是一個object {sum: 0}



var items = [0,1,2,3,4];

var reducer = function add(sumT, item) {

  console.log(sumT)

  sumT.sum = sumT.sum + item;

  return sumT;

};

var total = items.reduce(reducer, {sum: 0});

console.log(total); // {sum:1130}



運行結果



 {sum: 0}

 {sum: 1}

 {sum: 3}

 {sum: 6}

 {sum: 10}



reduce()的應用

  1. 數組扁平化

    遞歸+reduce



    let arr = [1, 2, '3js', [4, 5, [6], [7, 8, [9, 10, 11], null, 'abc'], {age: 12}, [13, 14]], '[]'];



    function flatten(arr) {

      if(Array.isArray(arr)) {

        return arr.reduce((prev, cur) => {

           // 如果遍歷的當前項是數組,遞歸調用flatten

          return Array.isArray(cur) ? prev.concat(flatten(cur)) : prev.concat(cur)

        }, [])

      } else {

        throw new Error(' 當前參數不是數組')

      }

    }

    console.log(flatten(arr));



    PS:這里的throw new Error只是用來判斷一開始的arr,這是因為在遞歸只傳入數組。


日歷

鏈接

個人資料

藍藍設計的小編 http://m.skdbbs.com

存檔

92国产精品视频_亚洲a级在线观看_国产精品电影观看_国产精品免费观看在线_精品伊人久久97_亚洲人成在线观_尤物九九久久国产精品的特点_成人激情在线播放_成人黄色大片在线免费观看_亚洲成人精品久久久_久久免费视频在线观看_久久精品国产一区_国产一区二区三区18_亚洲欧美中文字幕在线一区_日韩美女中文字幕_日韩视频免费在线
国产亚洲精品美女久久| 久久亚洲国产精品一区二区| 成人黄色视屏网站| 欧美成人午夜电影| 亚洲国产成人91porn| 亚洲欧美色一区| 日韩欧美中文字幕制服| 欧美精品一区二区三区在线四季| 国产精品美女久久久浪潮软件| 中文字幕亚洲一区二区三区| 1卡2卡3卡精品视频| 国内精品不卡在线| 国产精品久久久久久久久久直播| 国产电影一区二区三区| 国产91在线视频蝌蚪| 国产欧美精品日韩区二区麻豆天美| 日韩资源av在线| 亚洲第一伊人| 日韩精品亚洲一区二区三区免费| 欧美老少做受xxxx高潮| 99视频在线| 欧美一区二区播放| 电影一区二区| 国产一区二区三区四区五区入口| 91精品久久久久久综合乱菊| 国内不卡的二区三区中文字幕| 97se亚洲国产综合自在线| 亚洲激情五月| 日韩午夜在线电影| 国产黑丝在线一区二区三区| 国产欧美日韩精品一区二区免费| 不卡av影片| 一区二区三区精品视频在线观看| 一色屋精品亚洲香蕉网站| 欧美色大人视频| 精品国产一区二区三区久久久蜜臀| 色狠狠久久aa北条麻妃| 国产精品久久久久久久久快鸭| 日本动漫同人动漫在线观看| 国产精品sss| 亚洲伊人色欲综合网| 国产精品99久久久| 国产综合久久| 欧美一区二区三区免费在线看| 欧美三级乱人伦电影| 欧美巨乳美女视频| 欧美日韩精品综合| 欧美日韩第一区日日骚| 成人av资源站| 91精品国产网站| 久久精品72免费观看| 亚洲国产一区在线观看| 精品欧美午夜寂寞影院| 亚洲国产另类久久精品| 久久久久久久久99精品| 亚洲精品毛片| 国产精品久久久久久久久久妞妞| 99久久精品久久久久久清纯| 五月天亚洲一区| 欧美日韩一级二级| 国产精品国产三级国产aⅴ浪潮| 麻豆传媒在线观看| 在线视频1区2区| 牛牛电影国产一区二区| 成人免费观看49www在线观看| 国产欧美一区二区精品忘忧草| 亚洲在线免费看| 擼擼色在线看观看免费| 丝袜在线观看| 日韩国产高清视频在线| 北岛玲日韩精品一区二区三区| 欧美中文一区| 国产精品一区二区精品| av中文字幕亚洲| 亚洲第一男人天堂| 国产乱子轮精品视频| 国产一区2区在线观看| 成人性生交大片免费看小说| 日韩一区二区三区电影在线观看| 一区二区三区视频在线看| 成人国产二区| 亚洲一区二区精品视频| 久久久中精品2020中文| 亚洲色图第一页| 国内露脸中年夫妇交换精品| 狠狠色狠狠色综合系列| a毛片在线看免费观看| 999av小视频在线| 久久久精品人体av艺术| 欧美精品国产精品| 天堂一区二区在线| 色综合天天综合网中文字幕| 欧美激情成人在线| 欧美性猛交xxxx乱大交极品| 欧美人体视频xxxxx| 久久精品99久久香蕉国产色戒| 无遮挡动作视频在线观看免费入口| 66精品视频在线观看| 亚洲日本在线视频观看| 欧美大片在线观看| 欧美黑白配在线| 国产欧美精品在线观看| 91色在线视频| 四虎精品一区二区免费| 精品蜜桃在线看| 久久亚洲精精品中文字幕| 欧美午夜精品一区二区三区| 欧美电影免费网站| 欧美日韩在线观看视频小说| 亚洲自拍偷拍色片视频| 成人亚洲综合色就1024| 上原亚衣av一区二区三区| 在线观看网站免费入口在线观看国内| 丁香婷婷综合网| 99re在线精品| 欧美一级片在线看| 欧美性猛片xxxxx免费中国| 日本欧美一区| 国产中文一区二区三区| 欧美精品在欧美一区二区少妇| 成人欧美一区二区三区小说| 精品一区二区三区中文字幕| 亚洲巨乳在线观看| 亚洲精品日本| 日韩亚洲精品电影| 中文字幕在线高清| 亚洲国产一区二区在线播放| 国产经典三级在线| 国产婷婷97碰碰久久人人蜜臀| 在线亚洲激情| 99re热精品视频| 国产欧美一区二区三区精品观看| 妖精视频一区二区三区| 专区另类欧美日韩| 欧美一级大片视频| 中文字幕精品一区| 一区二区三区在线| 亚洲国产人成综合网站| 国产成人精品999在线观看| 国产亚洲一区二区三区啪| 国产精品欧美一区二区三区| 久久久影院官网| 国产欧美一区二区白浆黑人| 福利写真视频网站在线| 久久先锋影音av| 国产乱人伦偷精品视频不卡| 欧美高清视频一二三区| 蜜桃视频在线观看一区二区| 日韩免费一区二区三区| 一区二区网站| 国产一区二区三区在线视频| 成人午夜亚洲| 一区二区三区高清| 成人婷婷网色偷偷亚洲男人的天堂| 西游记1978| 亚洲成年网站在线观看| 91免费看国产| 日韩视频一二区| 精品久久久香蕉免费精品视频| 午夜精品一区二区三区av| 欧美精品一区二区三区中文字幕| 嫩草影视亚洲| 99久久综合国产精品二区| 国产精品亚洲欧美导航|