摘要:之前的函數聲明及表達式函數的聲明函數表達式也可以此時的只是這個匿名函數的名字,和變量沒有關系構造函數這種方法會運行兩次代碼先實例后執行函數體數的默認值如果沒有傳入參數就使用默認值,利用的短路特性傳入的參數為值會忽略判斷是否傳參,如果沒
ES5之前的函數聲明及表達式
1,函數的聲明
function fn(){ dosomething; };
2,函數表達式
var fn = function(){}
//也可以var fn = function newFn(){},此時的newFn只是這個匿名函數的名字,和變量沒有關系;
3,構造函數
var fn = new Function("num1","num2","return num1 ,num2") //這種方法會運行兩次代碼 //先實例后執行函數體
ES5數的默認值
function fn(arg1,arg2){ arg2 = arg2 || "the value"; //如果沒有傳入參數就使用默認值,利用||的短路特性 return arg1+arg2; }; fn("hello") ->hello the value; fn("hello","world") ->hello world; fn("obama","")->obama the value //傳入的參數為falsey值會忽略 typeof arg2 === "undefined" //判斷是否傳參,如果沒有實參的話,就是undefined; arg2=(typeof arg2 !=="undefined")?arg2:"the value";//判斷是否有傳入值 arguments.length ===1 //判斷傳遞的參數個數
ES6的參數默認賦值
function fn(arg1,arg2 = "value"){ let arg2 = 34; //此處的arg2 默認是已經聲明,所以內部使用let const會語法報錯! console.log(arg1,arg2) } //內部的arguments對象也默認和嚴格模式一樣的行為,不在動態的反應變化;默認值不計入arguments對象 //函數的參數,也可以是其他值,默認參數只有在調用的時候才會求值,因此可以用第一個參數作為默認的值 function fn(a , b =a){}; //參數的作用域和ES6之前的一樣,和其他的參數都是同一作用域,如果參數的值是一個變量,那么這個參數的作用域先是局部(確認是否也是形參)后是全局; let a = 34; function fn(b = a){ //尤其注意,參數b賦值的是變量a,那么就默認變量a已經聲明,此時的a,如果不是參數,就是全局的變量,如果是參數,就會報錯,重復賦值,使用let和const要注意語法錯誤 let a= 11; console.log(b); } fn() ->34 //當參數b賦值變量a的時候,a是全局注冊的,因此,fn()是34,如果沒有let a = 34;就會報錯, fn(22) ->22 //此時參數的作用域是局部 let a = 23; function (a,b=a){ //參數b的值是a,相當于再次給a賦值,由于參數是函數內部變量,所以和 let a = 12沖突;會報錯 let a = 12; console.log(b); } function fn(arg1,arg2){ console.log(arg1 === arguments[0]); //true console.log(arg2 === arguments[1]); //true arg1 = newarg1; arg2 = newarg2; console.log(newarg1 === arguments[0]); //true console.log(new arg2 === arguments[1]); //true }
rest參數(...rest)不定參數;只能放在形參的最后面,否則會報錯,這是一個數組對象
function fn(...value){ console.dir(value); value.slice() //可以使用數組的方法,區分arguments } fn(1,2,3,4,4)->[1,2,3,4,4]返回的是數組,可以使用數組的方法; //無論形參是否有不定參數,arguments對象正常使用,反應傳入的參數的數量
...擴展運算符 把運算符后面的數組,轉為用逗號分開的參數序列;可以用在所有使用數組的的方法中
console.log(1,2,3,4) //1 2 3 4; console.log(...[1,2,3,4])//同上 //利用call的屬性,轉化數組
判斷函數的調用,是直接調用還是new
function A(a){this.a = a;} var b = new A(3); //生成了對象 var c = A(4); //此時給全局屬性添加了a=4 function A(a){ if(this instanceof A){this.a =a} //判斷是否是new調用 else{return new A(a)} } var d = A.call(b,333) //通過call強制的指定this //正確的寫法 function B(b){ if(typeof new.target ! == "undefined"){this.b =b} //新的元屬性 else{return new B(b)}; } //es6可以在塊級代碼中,聲明和使用函數,但是會作為全局函數
箭頭函數 =>
//當函數沒有參數時; var f1 = function(){ };//默認函數返回一個undefined; var f1 = ( )=>{}; //空函數 var f2= ()=>"the value you want"; var f3 = ()=>{ //如果需要在函數體內執行多條代碼,就必須用大括號包裹 doSomethings; doantherthings; return value; //必須用return 返回值;否則默認返回undefined; } //箭頭函數有一個函數的時候 var f1 = function(arg1){ }; var f1 = arg1 =>undefined; //箭頭函數有多個參數的時候; var f1 = function (arg1,arg2,arg3){ }; var f1 = (arg1,arg2,arg3)=> undefined; var f2 = (arg1,arg2,arg3)=>arg1-arg2-arg3; //注意如果箭頭函數只是多帶帶的返回一個對象要在大括號的外面加個小括號; var f1 = ()=>{ doSomething; return { //此時不是多帶帶返回所以不需要 name : "name", value : "value" } }; var f2 = ()=>({ //此時為了區分{}是否是函數體,所以要加上小括號; name : "name", value : "value" }) //箭頭函數的函數體內正常和一般函數一樣,但是沒有arguments數組對象, //IIFE關于立即執行的函數 var f1 = (function(arg){ return { getArg :function(){return arg} } })(arg) //返回對象的方法 var f1 = (arg=>{ return { getArg :function(){return arg} } })("arg") //同上;
箭頭函數的this指向問題 (this僅僅是外一層非箭頭函數的函數this,否則就是undefined)
一般函數的this是根據調用的對象來指定的或者用new ,bind ,call 等操作符或者方法來綁定;
1,默認的this 指向
function fn(){console.dir(this)} //此時默認的指向是window
2,隱式的this 指向
var obj = { name : "obama", getName : function(){ return this.name //此時的指向是對象 } }
3,new操作符
function Name(name){ this.name = name; } var man = new Name("obama"); //此時指向的是new調用的對象
4,硬指定的this
var getName= function(){ console.log(this.name) } var name = "bush"; var predents = { name : "obama", } getName(); //bush getName.call(preddents) //obama;
ES6的箭頭函數this是和變量的作用域一樣的詞法指定(寫在哪里就是那里的引用),不能更改,也不可以用new操作符,本著用完即丟的思想
var a = ()=>this; //此時返回的是this對象是undefined; var obj = {age : 45}; obj.b = a; //把函數a當作obj的方法; obj.b() //正常不使用箭頭函數的話, this的指向應該是調用的obj對象,但是這里顯示的 是原來定義的window對象 a.call(obj) //顯試的綁定,也不能改變this 的作用域; var newa = new a() //報錯,a不是一個構造函數; 如果要使用箭頭函數的綁定的話在ES7里雙冒號::左邊是對象,右邊的是方法,這樣就可以綁定, var foo = {age : 34}; var bar = ()=>this.age; foo::bar //以上僅作了解
尾調用優化特指函數的最后一步(一般函數最后一步默認是return undefined)這一步不能有其他任何的操作,比如賦值,算術運算 屬于引擎的優化
一般JS引擎 在執行中,會進入執行上下文,全局,函數和eval上下文,三者中的一個,
保存這個上下文的地方就是在調用棧,棧的頂端就是一個變量對象,保存當前函數的使用的變量;
函數調用會在內存形成一個調用記錄稱之為調用幀,保存位置和內部變量,所有的調用幀就形成了一個調用棧;
尾調用因為是函數的一步,所以返回這個函數后,原函數就不必記住自己的變量,尾調用的函數會保存這個信息,所以內層的函數取代外部的函數,這樣就行成優化
function fn(){ let a = 1; let b = 2; return f2(a + b); } fn(); f2(3) //在函數fn里f2是尾調用,fn執行后,就不必記住自身可調用的變量,因為f2會記住執行;最終取代原函數; function fn(num){ ///一般遞歸函數 if(num ===1){return 1}; return num+fn(num-1) }
注意只有使用use strict 尾調用優化才會生效,而且argument 和caller 不能使用
function fn(n,total=1){ //尾調用優化 if(n ===1) return total; return fn(n-1,n+total) } //柯里化,將多參數的函數層層的使用單參數的函數調用 function add(n){ return curry(n,1) }; function curry(n,total){ if(n ===1) return total; return curry(n-1,n+total) }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89125.html
摘要:之小白初入江湖超文本標記語言簡稱是一種用于創建網頁的標準標記語言。描述了一個網站的結構語義隨著線索的呈現,使之成為一種標記語言而非編程語言。是塊級元素,是行內元素。層疊樣式表簡稱是一種用來為結構化文檔如添加樣式的工具。 HTML & CSS之小白初入江湖 1. HTML 超文本標記語言(HyperText Markup Language, 簡稱HTML)是一種用于創建網頁的標準標記語言...
摘要:之小白初入江湖超文本標記語言簡稱是一種用于創建網頁的標準標記語言。描述了一個網站的結構語義隨著線索的呈現,使之成為一種標記語言而非編程語言。是塊級元素,是行內元素。層疊樣式表簡稱是一種用來為結構化文檔如添加樣式的工具。 HTML & CSS之小白初入江湖 1. HTML 超文本標記語言(HyperText Markup Language, 簡稱HTML)是一種用于創建網頁的標準標記語言...
摘要:剛開始做項目,正好碰上了一個批量下載的功能就是下面圖片中的一個導出的功能后臺返回的數據格式是這樣的,如下做批量下載后臺需要前端給一個必需字段,在我這里也就是上代碼這樣我們的就是一個由組成的數組,搞定 剛開始做vue項目,正好碰上了一個批量下載的功能 就是下面圖片中的一個導出的功能showImg(https://segmentfault.com/img/bVbsuIr); 后臺返回的數據...
摘要:本人前端萌新大概花了一周多一點,完成了一個前后端分離解耦的簡易個人博客項目。項目前后端分離,路由完全交給處理,后端只負責操作數據庫,暴露。目前項目提供做學習用途,希望能給大家一些幫助,對全棧項目有一個初步的了解,謝謝。 本人前端萌新大概花了一周多一點,完成了一個前后端分離解耦的簡易個人博客項目。項目前后端分離,路由完全交給vue-router處理,后端只負責操作數據庫,暴露api。 技...
閱讀 998·2023-04-26 02:21
閱讀 2818·2021-09-24 09:47
閱讀 1608·2019-08-30 15:55
閱讀 2163·2019-08-30 14:01
閱讀 2320·2019-08-29 14:01
閱讀 2048·2019-08-29 12:46
閱讀 814·2019-08-26 13:27
閱讀 1933·2019-08-26 12:23