什麼是webpack模塊化構建工具

百度百科模塊化:是指解決一個複雜問題時自頂向下逐層把系統劃分紅若干模塊的過程,有多種屬性,分別反映其內部特性。javascript

 

計算機模塊化:通常指的是能夠被抽象封裝的最小/最優代碼集合,模塊化解決的是功能耦合問題。css

 

組件化:是模塊化進一步封裝,根據業務特色或者不一樣的場景封裝出具備必定功能特性的獨立總體,html

    另外,前端提到組件化更多的是具備模板,樣式和js交互的UI組件。前端

 

工程化java

  工程化是Web開發是遇到的問題:前端工程化

  1,模塊多了,依賴管理怎麼作;數組

  2,頁面複雜度提高以後,多頁面,多系統,多狀態怎麼辦;瀏覽器

  3,怎麼解決多人研發中的性能,代碼風格等問題;app

  4,團隊擴大以後,團隊合做怎麼作;異步

  5,權衡研發效率和產品迭代的問題。

 

Webpack 與 早期構建工具的區別:

1,早期前端工程化構建工具:Grunt,Gulp等構建工具

  該階段解決的問題是:重複任務的問題,他們將某些功能拆解成固定步驟的任務,而後編寫工具來解決

  如:圖片壓縮,地址添加hash,替換等,都是固定套路的重複工做。

2,現階段的Webpack構建工具:

  現階段Webpack則更像是從一套解決JS模塊化依賴打包開始,利用強大的插件機制,逐漸解決前端資源依賴管理問題,

  依附社區力量逐漸進化成一套前端工程化解決方案。

 

什麼是Webpack

  1,本質上是一個現代JS應用程序的靜態模塊打包器(static module bundler)。

  2,在Webpack處理應用程序是,它會在內部建立一個依賴圖(dependency graph),用映射到項目須要的每一個模塊,

    而後將全部這些依賴生成到一個或多個bundle。  

 

 

 

前端模塊化:指JavaScript的模塊。

最多見的模塊化:Nodejs的NMP包。

模塊化的規範有:

  CommonJS  ,   AMD  ,  ES6 Module ,  CMD , UMD等等

一,CommonJS : 是Nodejs普遍使用的一套模塊化規範,是一種同步加載模塊化依賴的方式:

  1,require  引入一個模塊

  2,exports  導入模塊內容

  3,module  模塊自己

 

二, AMD:是js模塊加載庫RequireJS提出並完善的一套模塊化規範,AMD是一條異步加載模塊依賴的方式:

  1,id   模塊的id

  2,dependencies   模塊依賴

  3,factory   模塊的工廠函數,即模塊的初始化操做函數

  4,require   引入模塊

 

三,ES6 Module : ES6退出的一套模塊化規範

  1,import     引入模塊依賴

  2,export    模塊導出

 

四,CMD:國產庫SeaJS提出來的一套模塊化規範

五,UMD:兼容 CommonJS 和 AMD 的一套規範

目前多數模塊的封裝,便可以Node.js環境運行,又能夠在Web環境運行。通常會採用UMD的規範。

 

CSS也可使用@import的方式來引入本身依賴的模塊:

      @import  'reset.css';

 

 

 

 

 

 

函數的定義, 普通函數 構造函數 本質 做爲數據,遞歸, 鏈式調用,間接調用,  arguments參數 return返回值函數的定義:   //函數:一次申明,四次使用(調用)   //函數分爲:命名函數(有函數名稱的函數) 和 匿名函數(沒有名稱的函數)   //命名函數   function add(a,b){   //函數體,屬於局部做用域   return a+b;// return 表示函數一死,能夠燒紙,return後面的是函數返回值   console.log("return 後面的代碼永遠不會執行。");   };   add(3,8);   //匿名函數    window.onload=function(){   //函數體,屬於局部做用域   alert("hellow");   };   //------函數執行過程-------   function add(a,b){   var result=a+b;   return result;   }   /*   -------上述函數每次被調用時都會發生的事情-------   1,瀏覽器全局對象window下面建立一個add方法   2,在add方法下面建立一個局部做用域   3,在局部做用域中建立變量 a=undefined , b=undefined , result=undefined   4,執行函數add(1,2);   5,給每一個變量賦值 a=1 , b=2 , result=3   6,函數執行完畢,第一個要作的就是刪除 add方法裏面的局部做用域以及裏面的變量,因此在外面沒法訪問裏面的變量*///------------------------------------------   //------爲何要使用函數-------   /*1,複用代碼   2,易於修改,維護   3,增長程序的可讀性*/   //如下函數對可讀性的優化   //下面代碼每次看的話都要分析如何實現,怎麼判斷春夏秋冬,   //每次查看都要分析,細節暴露太多了,因此可讀性不是很強。這裏就須要封裝函數了   function doThings(month){   if (month>=3 && month<=5) {   //踏春   }else if(month>=6 && month<=8){   //游泳   }else if(month>=9 && month<=11){   //秋收   }else{   //冬天睡覺   }   }   //何時可使用函數?   //1,代碼中有重複代碼,或者有類似代碼時,須要封裝函數。   //2,功能實現時有不少代碼,細節暴露太多,可讀性不好時,就須要封裝函數。   //   //把上面函數封裝成可閱讀性比較強,不暴露細節,直接讀函數名稱就能夠知道作什麼?   //在實現比較強的閱讀性時,不要暴露具體實現的函數過程,直接一個函數名便可。   function isSpring(month){     return month>=3 && month<=5;   }   function isSummer(month){     return month>=6 && month<=8;   }   function isAutumn(month){     return month>=9 && month<=11;   }   function isWinter(month){     return month>12 && month<=2   }   function doThings(month){      if (isSpring()) {      //踏春      }else if(isSummer()){      //游泳      }else if(isAutumn()){      //秋收      }else{      //冬天睡覺      }   }</script><script>//-------------函數的本質---------------/*函數二象性1,函數能夠調用2,函數實際上是對象:{}定義對象的方式:a,字面量的方式: var a={...}b,構造函數的方式: var obj=new Object();var arr=new Array();添加屬性和方法:var person={};person.name="zheng";person.setName=function(name){this.name=name;}var Person(arguments){name:"zheng",age:"18",addredd:"China"}定義函數的方式:a: function Person(arguments){...}b: var fn = new Person(a,b,c);*///-----如下是對象的操做-------/*var a={"name":"zheng","age":18,"love":"you"}a.name="love";a.setAge=function(age){return a.age=age;}console.log(a.name);console.log(a.setAge(88));*///-----如下是函數的操做-------function add(a,b){age="zheng";//設置age屬性return a+b}console.log(add.name);//返回 add,這裏name是函數關鍵字 表示返回當前函數的函數名稱//給函數add設置age屬性add.setage=function(age){this.age=age;}add.age="love";//從新設置 age 屬性值console.log(add.age);//返回 loveadd.setage("you");//修改age的值console.log(add.age);//返回 youconsole.log(add(1,3));//輸出 4console.log(add);//輸出add函數本體//給add函數對象添加一個start函數add.start=function(){console.log("hello");}add.start();//執行start方法,輸出hello</script><script>//---------函數做爲數據值來使用----------//值的集合是數組,鍵值對出現的就是對象//值的集合是數組var arr=[1,"a",function(){}];for(var p in arr){console.log(p);//輸出的索引值 0 1 2console.log(arr[p]);//arr[p] 輸出的是arr中的對象}//鍵值對是對象var array={"a":"love","b":"you","c":function(){}};for(var p in array){console.log(p);//輸出array的屬性console.log(array[p]);//輸出array的屬性值}//---------函數做爲參數來使用----------//這裏的函數做爲參數使用// setTimeout(function(){alert(1)},1000);//一秒鐘後跳出彈窗setTimeout(fn,1000);//函數名稱表示函數本體,fn()表示當即執行該函數本體。function fn(){alert(1);}//---------函數做爲返回值來使用----------function add(){return function(){alert(2)};}/*var newFn=add();//返回 return 後面的匿名函數本體newFn();//函數本體後面添加小括號,表示當即執行該函數*/add();//獲得 function(){alert(2)}; 這個返回值,是一個匿名函數本體。add()();//表示執行匿名函數本體</script>//========函數的三種定義方式============//-----第一,二種函數定義方式:------字面量:   function聲明:  function add(){...body...}  //這裏能夠不要使用分號,這是函數調用: add();var賦值表達式:var add=function(){...body...};//這裏必定要使用分號,這是語句調用: add();var add=function fn(){...}add(); //只能在外部調用,不能再函數體內調用fn();//這麼調用是錯誤的,fn屬於局部變量,不能夠在外面調用//-----第三種函數定義方式:------構造函數:申明:var fn=new Function("a","b","return a+b;");調用:fn();//============函數定義的區別===============字面量於構造函數的區別:1,字面量定義:直觀,簡潔,方便書寫2,構造函數:笨重,複雜,效率低(解析字符串是變量是還函數體,實例化構造函數,函數體多的時候很難看)        構造函數的定義方式複雜難懂,效率較低,通常不用它來定義函數         使用構造函數的方式定義函數,不會被提早,函數調用必須在定義以後聲明方式:var聲明方式 和 function聲明方式 的區別:1,使用var聲明方式 是一個條語句,不會申明提早,因此最後要加分號;2,使用function聲明方式 是一個函數,會被申明提早,因此最後不要加分號。3,預解析的過程的不一樣,以下代碼:<script>//這裏是預解析的時候已經定義了function add(),//因此能夠提早輸出:function add(){return "a";}//使用function聲明的方式定義函數,聲明會被提早,函數調用在定義先後都無所謂console.log(add());//輸出 afunction add(){return "a";}//-----console.log(add());var add=function(){return "a";}//預解析://var add=nudefined//預解析完了再逐行執行代碼。//因此add是一個變量,不能當作函數執行add();//-----var ad=function(){return "b";}console.log(ad());//預解析://var ad=undefined;//預解析完成,再重頭開始逐行執行代碼//給 ad 進行賦值 ad=function(){return "b";}//因此這裏的 ad是一個函數 ad();</script>//使用時怎麼選擇函數//構造函數 傻大黑粗效率低,通常不建議使用//var 和 function 兩種都差很少,通常都是根據團隊風格進行選擇的。======================<script>//使用構造函數實現:21 * 32 + 24 / 3 - 5var multiply=new Function("a","b", "return a*b;");//全部參數都必須使用字符串的形式,包括函數體。// console.log(multiply("21","32"));//調用該方法時,只須要帶參數便可,函數體不用寫。var divide=new Function("a","b","return a/b;");//全部參數都必須使用字符串的形式,包括函數體。// console.log(divide("24","3"));//調用該方法時,只須要帶參數便可,函數體不用寫。var substract=new Function("a","b","return a-b;");//全部參數都必須使用字符串的形式,包括函數體。// console.log(substract("333","222"));//調用該方法時,只須要帶參數便可,函數體不用寫。//等價下行:var add=new Function("a","b","return +a + +b;");//+a,+b表示取正,-a表示取負,!表示取反var add=new Function("a","b","return parseInt(a)+parseInt(b);");//全部參數都必須使用字符串的形式,包括函數體。// console.log(add("22","33"));//調用該方法時,只須要帶參數便可,函數體不用寫。var mul=multiply("21","32");//返回:672var divide=divide("24","3");//返回:8var add=add(mul,divide);console.log(add);//返回 680var sub=substract(add,"5"); //返回 675console.log(sub);//返回 675</script>//========函數定義的位置============//具體哪裏能夠訪問,請使用搜狗:zuoyongyu:做用域的知識1,全局做用域function add(){...} 在哪裏均可以調用2,函數做用域//fn1()函數只能在substract函數中進行訪問,不能夠在全局中訪問。function substract(){fn1();//能夠訪問function fn1(){fn1();//能夠訪問function fn3(){fn1();//能夠訪問}}fn1();//能夠訪問function fn2(){fn1();//能夠訪問}}3,不建議在代碼塊中定義函數:在javascript中不存在 if/for代碼塊的做用域,裏面的函數預解析爲window全局做用域if(true){function add(argument){...}}else{function substract(argument){...}}//函數預解析時就提早聲明瞭:window下面的屬性及其方法:function add(argument){...}function abstract(argument){...}再逐行執行代碼------若是爲真,就能夠執行add()函數,不然就能夠執行substract()函數-------if(true){var add=function(){...};}else{var substract=function(){...};}函數是在預解析以後再賦值的:var add=undefined;var substract=undefined;再逐行執行代碼------B:JS中沒有塊級做用域,因此不會在if中發生預解析,在外部預解析的時候,if中聲明的全部函數都會被提早,因此沒法達到按需定義的目的。C:方法的調用必須指定對象,通常經過 對象.函數名() 的方式調用D:內部函數能夠訪問外部函數的變量(做用域鏈的機制)------4,函數做爲對象的屬性值:<script>var person={name:"zheng",age:18,address:"China",setAddress:function(address){this.address=address;}};console.log(person.name);//輸出:zhengconsole.log(person.name="liang");//輸出:liangperson.setName=function(name){this.name=name;}//添加設置修改姓名的方法person.setName("zhu");//從新把name設置爲:zhuconsole.log(person.name);//輸出:zhuconsole.log(person.address);//輸出:Chinaperson.setAddress("American");//從新把address設置爲:Americanconsole.log(person.address);//輸出:American</script><script>//若是輸入兩個數字類型,就相加,不然提示請輸入數字類型的參數var add=function(a,b){if (isNumber(a) && isNumber(b)) {return parseInt(a)+parseInt(b);//等價:return +a + +b; 一元運算符: +取正,-取負 !取反}else{return "請輸入數字類型的參數";}}function isNumber(a){return isNaN(a)?false:true;//若是isNaN(a)=true,那麼返回false ,不然返回true}console.log(add("333","bbb"));console.log("33","22");</script>//------函數的調用------<script>//命名函數的調用function add(a,b){return a*b;}add();//命名函數的調用//匿名函數的調用//1,使用 變量名+() 進行調用var add=function(a,b){return a*b;}add();////2,匿名函數自我執行/*function(){console.log(1);}();在預解析時:function後面必定要跟上一個函數名稱,但這裏沒有函數名稱,因此會報錯。解決辦法以下:*///匿名函數自執行方法一://把匿名函數自我執行後的結果賦值給變量a便可,函數名稱+()表示當即執行函數本體。/*var a =function(a,b){return 3*4}();console.log(a);//匿名函數自執行方法二,三效果如出一轍//匿名函數自執行方法二:(function(){console.log(2)}());//匿名函數自執行方法三:(function(){console.log(3)})()//匿名函數自執行方法四://!表示取反,+表示取正,-表示取負數,只要不讓匿名函數的function打頭,那就能夠匿名函數自執行!function(){console.log(4)}();+function(){console.log(4)}();-function(){console.log(4)}();!+~-function(){console.log(4)}();//匿名函數自執行方法五:console.log(function(){return 5;}());*/<script>(function(){function add(a,b){return a+b;}console.log(add(1,3));//而這裏返回的4})();console.log(add(1,3));//這裏調用報錯,由於add函數是在匿名函數的做用域內,不能夠當作全局變量來使用</script>//------遞歸函數------5的階乘:5*4*3*2*1//遞歸函數,相似於循環//1,必定有一個終結點退出函數執行//2,同理一直進行自我調用<script>function factorial(num){if (num<=1) return 1;return num*factorial(num-1);}console.log(factorial(5));//上面的遞歸等同於下面的函數:/*5*4*3*2*15!5*4!5*4*3!*/var sum=1;function a(num){var i=1;while (i<=num) {sum=sum*i;i++;}return sum;}console.log(a(5));</script><script>//求階乘,這裏沒有終止條件,值域溢出,因此死循環function factorial(num){return num*factorial(num-1);}factorial(5);</script><!-- 對象調用方法 --><script>var operation={//加法add:function(a,b){return a+b;},//減法substract:function(a,b){return a-b;},//乘法multiply:function(a,b){return a*b;},//除法divide:function(a,b){return a/b;},//使用不合法的字符串時,只能使用:對象["@"]()運行函數"@":function(){console.log("999");alert("1");}}//使用合法字符串命名,可使用如下兩種方法進行調用函數console.log(operation["add"](3,6));console.log(operation.add(3,6));//使用不合法的字符串時,只能使用: 對象["@"]() 運行函數operation["@"]();var key="add";// []方括號中,有雙引號的表示字符串,沒有雙引號的表示變量,謹記console.log(operation[key](1,3));//返回:4  這裏的是變量:key="add"console.log(operation["key"]());// 返回:key  這裏的key是對象operation中的方法。//-------鏈式調用方法-------// $("p").html("love you forever").css("backgrond","red")...var operation={//加法add:function(a,b){console.log(a+b);return this;//返回的是operation對象},//減法substract:function(a,b){console.log(a-b);return this;//返回的是operation對象}}// operation.add(2,3); 返回的是 operation 對象// operation.substract; 返回的是 operation 對象//因此可使用下面的鏈式調用,不然是不能夠的。operation.add(2,3).substract(33,3);</script><script>//這是須要鼠標點擊才能夠調用點擊方法document.onclick=function(){alert("1");}//不用點擊直接調用方法,任意方法直接在方法名稱後面添加 (),就會立馬執行該方法document.onclick();</script><script>//什麼是構造函數//普通函數有return 則返回 return後面的值,若是沒有return,則返回undefined//函數名稱小寫用於區分:普通函數,不是嚴格規定//函數名稱大寫的用於區分:構造函數,不是嚴格規定 function add(a,b){return a+b;}//普通函數的調用:函數名稱()add(3,4);// function Person(){...}//new Person() 用於實例化構造函數// var Obj=new Person();//Person();這麼調用就是普通函數//Array();這是普通函數//Object();這是普通函數console.log(Array());//返回 []console.log(Object());//返回 {}var arr=new Array();//實例化一個數組 返回的永遠是對象var obj=new Object();//實例化一個對象 返回的永遠是對象////-------實例化一個Person--------/////構造函數,顧名思義:被構造的對象也必須是一個函數。function Person(){this.name="zheng";//這裏必定要使用this.屬性,不然後面輸出都是undefined.this.age=18;//這裏必定要使用this.屬性,不然後面輸出都是undefined.var address="China";//實例化後,輸出爲undefined}var xm=new Person();//實例化一個Person對象console.log(xm);//Person {name: "zheng", age: 18} address定義錯誤不是屬性console.log(xm.name);//輸出 zhengconsole.log(xm.age);//輸出 18console.log(xm.address);//輸出 undefined</script><script>//建立一個空的Person對象var Person=function(){};//實例化Person對象var per=new Person();//給對象添加屬性per.name="zheng";per.age="18";per.sex="male";//實例化一個數組var arr=new Array();//給數組arr添加屬性arr[0]="zheng";arr[1]="liang";//遍歷per對象並輸出屬性及其屬性值for(var p in per){console.log(p+":"+per[p]);}//遍歷數組arr並輸出值for (var i = 0; i < arr.length; i++) {console.log(arr[i]);}</script><script>//------間接調用--------var name="xm";var person={};person.name="xh";person.getName=function(){return this.name;}console.log(person.getName());//輸出:xh//這裏的window用於改變person.getName裏面的this變成:window,即返回window.name的值console.log(person.getName.call(window));//輸出:xm//這裏的window用於改變person.getName裏面的this變成:window,即返回window.name的值console.log(person.getName.apply(window));//輸出:xmvar arr=[2,5];function add(a,b){return a+b;}//直接調用console.log(add(3,6));//使用了間接調用,call(指定做用域對象,argument1,argumen2...)console.log(add.call(window,2,5));//這裏間接調用了window下面的arr的數組值, apply(指定做用域對象,數組)console.log(add.apply(window,arr));//間接調用://1,對象沒有call和apply方法,只有函數有//2,apply能夠將數組和類數組一次性的傳遞進函數中,call只能一個一個的傳</script>//------arguments 參數------//參數分爲:實參,形參1,當參數爲基本數據類型時,只是進行了複製操做,不不會修改原來的值。2,當參數爲引用類型時,由於兩個引用地址相同,指向同一個值。若是修改其中一個,另外一個也會被修改。//三種狀況:1,實參=形參<script>//函數中的參數:形式參數 實際參數function add(a,b){//這裏的 a,b是形式參數,佔位符的做用return a+b;}add(3,8);//這裏的3 ,8 是實際參數//本質上就是複製一個副本:  形參=實參 ,對於原來的值是不改變的。// var a=3;  var b=8;//參數爲對象時,參數爲引用類型,那麼傳遞的是地址。修改一個同時也會修改另外一個var person={};var setName=function(obj){//這裏的參數是對象,給指定對象設置name屬性obj.name="zheng";}setName(person);//這裏的person是對象,給person對象設置name屬性console.log(person.name);</script>2,實參<形參<script>//求數的冪  Math.pow(base,power);function pow(base,power){return Math.pow(base,power);}console.log(pow(3,4));//返回 81console.log(pow(3,2));//返回 9function pow(base,power){// if (!power) power=2;//若是b爲空:!power=true,若是b不存在爲真的,那麼返回b=2.//短路操做power=power || 2;//或邏輯 一個爲真即爲真 若是power=power返回true,那麼power=power,不然b=2;return Math.pow(base,power);}console.log(pow(4));//返回 16console.log(pow(3));//返回 9//$("p");//默認省略document//在JQuery中的參數: $("p",document):表示在文檔中查找P標籤。//也可指定某個對象:$("p",document.getElementById("box")),//指定id="box"的對象下面查找p標籤。</script>3,實參>形參<script>function add(){//任何函數都有返回值,返回return後面的值,若是省略return或者return後面沒有值,則返回undefinedif (arguments.length==0) return;var sum=0;for (var i = 0; i < arguments.length; i++) {sum+=arguments[i];}return sum;}console.log(add()); // 返回 undefinedconsole.log(add(1,3,4));//返回 8</script><script>// 輸入任意個數字參數,輸出最小值function mix(){var len=arguments.length;if (len==0) return;if (len==1) return arguments[0];var mi=0;for (var i = 1; i < len; i++) {//思路決定出路// 這裏是精華所在,先後對比,把較小的一個賦值給arguments[i]arguments[i]= arguments[i-1]<arguments[i]?arguments[i-1]:arguments[i];mi = arguments[i];}return mi;}console.log(mix(1,3,444,2,5245,7373,2452,-11,-23432,-234,-245));console.log(mix());console.log(mix(888))</script>//arguments//參數是每一個函數都有的,是一個局部變量//類數組對象,但不是數組的實例。可使用arguments[index]進行取值.<script>//合法標識符:不能以數字,關鍵字,保留字開頭,以字母,數字,下劃線組成的字符串;//這裏arguments的索引是 "0" 到 "5" ,數字是不合法的標識符,因此只能使用雙引號。//如下就是類數組對象:var arguments={"0":"argument1","1":"argument2","2":"argument3","3":"argument4","4":"argument5","5":"argument6"};//遍歷arguments類數組對象for(var p in arguments){console.log(p+":"+arguments[p]);}//1.對象的長度不能用.length獲取,用js原生的Object.keys能夠獲取到console.log(arguments.length);//返回 undefinedvar keys=Object.keys(arguments)//使用原生Object.keys,獲取鍵值對中鍵的集合,都是數組var values=Object.values(arguments)//使用原生Object.values,獲取鍵值對中值的集合,都是數組console.log(keys.length);//兩種均可以得到對象的長度console.log(values.length);//兩種均可以得到對象的長度//可是,若是arguments做爲函數中的參數,是能夠經過arguments.length得到實際參數個數。//函數是一個特殊對象,也能夠經過add.length 得到形式參數個數<script>function add(a,b,c){console.log(arguments.length);//返回 5 調用函數是寫入的實際參數console.log(add.length);//返回 3,定函數時,定義的形式參數console.log(arguments.callee.length);//返回 3 形式參數,函數固定的形式參數長度return +a + +b + +c;//一元運算符,+取正,-取負,!取反}// console.log(add(1,3,5));console.log(add(1,3,6,7,8));//返回:10 只對前面3個參數進行相加</script>//------function fn(arguments){console.log(argument);function fn1(arguments){console.log(argument);}fn1(2);//輸出2}fn(1);//輸出1//arguments是每一個函數中獨有的,不一樣做用域不一樣//預解析:/*fn函數做用域:var argument=undefined;fn1函數做用:var argument=undefined;*/</script>//--------// "use strict" //表示使用嚴格模式// var num=1;//這樣定義num變正確// num=1;//這樣定義num變就會報錯</script><script>//判斷傳入參數是否等於實際參數function add(a,b){//console.log(arguments.length);//返回 5實際參數,咱們實際傳入的參數//console.log(arguments.callee.length);//返回 2 形式參數,函數固定的形式參數// console.log(add.length);返回 2 //形式參數,函數固定的形式參數,能夠在函數外面進行調用if (arguments.length!==add.length) throw new Error("請輸入:"+add.length+"個參數");return a+b;}// console.log(add(2,4));//返回 6console.log(add(1,3,4,5,6));//參數不對,參數過多。返回:text2.html:13 Uncaught Error: 請輸入:2個參數</script>//---------------<body>    <p id="test" style="background-color: red; color: blue;">我是一個段落!</p><script type="text/javascript"> //在使用參數給對象設置CSS屬性時,都是用p.style[property]=value,這樣絕對沒錯//若是使用p.style.property=value。讀取時使用,設置時有可能會報錯。var p=document.getElementById('test');function css(value,property){//必要參數必定要放在第一個,可傳可不傳放在後面if (arguments.length<=0 || arguments.length>=3) throw new Error("請輸入:"+arguments.length+"參數");if (property==undefined) p.style.backgroundColor=value;if (arguments.length==2) p.style[property]=value;}css("orange");//第二個參數省略,默認 property=undefined// css("green","backgroundColor");</script> </body> <script type="text/javascript"> //-----什麼能夠當作變量-------//1,什麼都不傳var a=2;function fn(){function(){alert(a);}}//2,數字function fn(num){console.log(num);}fn(2);//3,字符串//4,booleanfunction a(){}function b(){}//若是傳進來的是布爾值,必定使用要把細節封裝成a,b函數。經驗之談。function fn(boolean){if (true) {a();}else{b();}}//5,undefinedfunction add(a,b){if (b==undefined) return a;return a+b;}console.log(add(6,undefined));//返回 NaN,非數字function pow(bace,power){//短路操做,若是power=power=true則power=power  power=undefined=false 則power=2。power=power || 2;return Math.pow(bace,power);}console.log(pow(3,6));//6,null//以上都是單個參數傳遞////7,傳多個參數,如數組:[1,2,3,4,5]$.each([1,2,3,4,5], function(index, val) {console.log(index);console.log(val);});for (var i = 0; i < [1,2,3,4,5].length; i++) {console.log(index);console.log(val);}//8,傳對象:{"a":"1","b":"2","c":"3"}$.each({"a":"1","b":"2","c":"3"}, function(index, val) {console.log(index);console.log(val);});//下面代碼使用對象做爲參數進行代碼優化:function setPerson(name,sex,age,add,phone){var person={};person.name=name;person.sex=sex;person.age=age;person.add=add;person.phone=phone;}//可讀性,可寫性不強,很容易弄錯參數順序致使錯誤,因此下面可使用對象代替setPerson("zhengl","male",18,"中國China","182...");//當參數超過三個或者三個以上,建議適用對象進行代碼優化以下:var person={};function setPerson(obj){person.name=obj.name || "xh";//若是沒有設置該屬性,則設置一個默認值person.age=obj.age || 18;//若是沒有設置該屬性,則設置一個默認值person.add=obj.add || "中國China";//若是沒有設置該屬性,則設置一個默認值person.sex=obj.sex || "male";//若是沒有設置該屬性,則設置一個默認值person.phone=obj.phone || "110";//若是沒有設置該屬性,則設置一個默認值}//通過代碼優化:對象屬性不用按順序進行書寫,甚至不寫都不會報錯。setPerson({name:"zheng",age:18,sex:"male"// add:"中國China", 兩個屬性值沒寫,使用默認值// phone:"187" 兩個屬性值沒寫,使用默認值});console.log(person.age);console.log(person.add);console.log(person.phone);//9,函數做爲參數,就叫回調函數$.each(obj,function(){...})setInterval(function(){},1000)</script> <script type="text/javascript"> /*//--------返回值:-------- return 1,表示 函數的結束。2,表示 返回return 後面的值。若是後面沒有值,則返回undefinedreturn 表示在函數中使用,函數返回一個值。continue 用於循環,表示跳出本次循環,執行下一次循環break  跳出整個循環,執行循環之外的代碼*///1,沒有返回值: 默認undefinedfunction fn(){}function fn1 () {return;//表示返回值爲undefined}function fn2(a,b){if (b<0) return;//表示函數結束執行return a/b;//表示返回值}console.log(fn());//返回 undefinedconsole.log(fn1());//返回 undefined//2,數字作返回值//3,字符串做爲返回值alert(1,2,3,4);返回字符串:1,2,3 alert([1,2,3,4]);//返回字符串:1,2,3 默認會隱式轉換:[1,2,3,4].toString();alert([1,2,3,4].toString());返回字符串:1,2,3//4,boolea  return true/false//5,null//6,數組 返回多個值function fn(a,b){return [a+b,a,b];}//7,對象function getPerson(){return {//不用建立對象了,直接返回一個對象便可name:"zheng",age:18};}console.log(getPerson());//{name: "zheng", age: 18}//一下代碼風格要當心,return在解析時,系統會自動給return添加分號;,從而報錯。/*function getPerson(){return //return在解析時,系統會自動給return添加分號;,從而報錯。{name:"zheng",age:18};}console.log(getPerson());//{name: "zheng", age: 18}*///8,函數function fn(){return function (){console.log("one");}}// 返回:// ƒ fn(){// return function (){// console.log("one");// }// }console.log(fn);//返回:ƒ (){ console.log("one"); }console.log(fn());//返回:oneconsole.log(fn()());//------document.write([1,3,5]);//返回 1,3,5 進行了隱式轉換[1,3,5].toString();document.write({"name":"zheng","age":18,toString:function(){document.write("love");}});//返回:[object Object]console.log({"name":"zheng","age":18,function(){document.write("love");}});//返回:{name: "zheng", age: 18, function: ƒ}/*爲了寫出更優雅的函數,會將函數做爲參數傳遞到另外一個函數中,組成一個新功能的函數:兩個功能:1,傳進來函數的功能。2,接收函數的功能。一個函數實現一個功能,把多個函數組合成一個新的函數,就實現了一個複合的功能。*/</script>    //------關於局部做用域,調用一次就建立一次,也刪除一次-------<script type="text/javascript"> function count(){ var num=1; return function(){ return num++;//先返回 num,再num+1 // return ++num;//先num+1,再返回 num } } console.log(count()());//每次調用普通函數,都會建立一個新的局部做用域,函數執行完連被刪除 console.log(count()());//每次調用普通函數,都會建立一個新的局部做用域,函數執行完連被刪除 console.log(count()());//每次調用普通函數,都會建立一個新的局部做用域,函數執行完連被刪除 var fn=count();//這裏只調用一次函數,只開闢一個局部做用域,因此裏面的num執行幾回就會加1幾回。 console.log(fn());//fn()=count()(); console.log(fn());//fn()=count()(); console.log(fn());//fn()=count()(); //返回:1 ,1 ,1 ,1 ,2 ,3  // 一、 count()()這樣調用,每次都會建立一個新的局部做用域,num的值會不斷地被初始化爲1 // 二、 return num++表示先返回num的值,再將num加1 // 三、 先將count()賦給fn,此時count()只調用了一次,接下來屢次調用fn()的時候,count函數並無屢次調用,num只會在count函數調用的時候被初始化,因此屢次調用fn()的時候num不會被屢次初始化;因爲fn至關於count函數的內層函數(var fn=count();這行代碼執行後,就調用了count(),調用count後就將裏面的函數賦值給了fn,因此說fn就至關於函數的內層函數了。),能夠訪問count中的變量num,因此屢次調用fn函數,會將num的值累加;</script> 

相關文章
相關標籤/搜索