多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] ## 函数的形参与实参 ### arguments是一个类数组 类数组的**类**意味着什么呢? 这意味着他们都有长度,都能够被遍历,它们是长成如下样子的**对象**而不是数组 ``` { '0':'a' ,'1':'b' ,length:2 ,ƒ ifn(a,b,c) ,Symbol(Symbol.iterator):ƒ values() ,__proto__:Object } ``` 但,毕竟只是相似,具有一些数组的特征,不是真正的数组,So他们**不在Array的原型链上**,不具有Array原型上的方法,也就是说所有数组独有的方法这些类数组都不能够使用。 #### 转真·数组 - Array.prototype.slice.call(arguments); - Array.from(arguments) ### 两种获取参数长度的方式 `fn.length` 和 `arguments.length`都能获得一个函数的参数的长度, 但!`fn.length`拿到的是**形参**的长度,而`arguments.length`拿到的是所传**实参**的长度,这两个值不总是相等的,因为实际传入的参数的个数可以大于或小于形参的个数。 ``` function ifn(a,b,c){ console.log(arguments.length); console.log(ifn.length); } ifn(); <<< 0 3 ``` ### 形参和arguments都指向实际的参数 下例中,实际传入的第一个参数的值将会被修改,并且在arguments中得到显示 ``` function ifn(a,b,c){ console.log(arguments[0]); a = 'x'; //实际传入的第一个参数的值将会被修改,并且在arguments中得到显示 console.log(arguments); } ifn(1,2,3) <<< 1 { '0': 'x', '1': 2, '2': 3 } ``` ## 函数、剩余运算符与解构运算 ### 函数与剩余 注意,若使用剩余运算符必须在形参的末尾处使用 ``` function sum(zero,...args){ return currency+eval(args.join('+')); } sum (0,1,2,3,4,5,6) ``` ### 函数与解构 对象作为实参可在形参处被解构 ``` function ajax({url=new Error('url不能为空'),method='get'}){ ... } ajax({url:'/test',method:'get'}); ``` 但并不支持解构数组 ``` let fn1 = function(...args){ console.log(args) }; fn1([1,2,3]) <<< [ [ 1, 2, 3 ] ] //--- --- --- let fn1 = function(a,b,c){ console.log(a) }; fn1([1,2,3]) <<< [1,2,3] ``` ## Function ### 用字符串创建一个函数 此种创建函数的方式常常和模板拼接一起配套使用,让我们能够更自由的创建函数 ``` let strFnBody = `if(arg1)console.log('参数存在')`; let fn = Function('arg1','arg2',...,strFnBody); fn(); //执行函数 ``` ### 所有函数们的粑粑 所有函数都是Function函数的实例 ``` let fn1 = function(){}; console.log(fn1.__proto__ === Function.prototype) <<< true ``` ## 箭头函数 ### 箭头函数木有arguments 替代方案是利用剩余运算符,嘿,我们得到了还是一个真·数组 ``` (...args)=>{ console.log(args); } <<< [ 1, 2, 3 ] ``` 其次虽然没有arguments,我们仍然能通过`fn.length`来拿到形参的个数 ``` let arrow = (a,b,c)=>{ console.log(arrow.length) } arrow(1,2,3); <<< 3 ``` ### 箭头函数木有this ``` let obj = { fn:function(){ console.log(this); } } let fn = obj.fn; fn(); //global||window obj.fn(); //obj //--- --- --- let obj = { fn:()=>{ console.log(this); } } let fn = obj.fn; fn(); //本模块的最顶层的this window||{} obj.fn(); //因为箭头函数不再有this会往上找,如果是nodejs会找到{},如果是浏览器会找到window ``` 当一个函数本身没有this时(箭头函数),那么**谁调用的函数this就指向谁这句话就不再适用**,它会查找上级作用域的this是指向谁。而又因为Node.js中,最顶层的作用域(模块作用域)的this指向的是`{}`(空对象),故上栗中会指向{}。(注意Node.js中文件模块的this并不指向全局对象global,而浏览器是指向window全局对象的) ## 函数作用域链的查找 函数作用域链的查找 是顺着【函数定义时】所处的作用域来查找的 ``` let b = '123' function bbb(){ console.log(b) } (function(){ let b = 'bbb'; bbb(); //123 })(); ```