- 函数的形参与实参
- arguments是一个类数组
- 转真·数组
- 两种获取参数长度的方式
- 形参和arguments都指向实际的参数
- arguments是一个类数组
- 函数、剩余运算符与解构运算
- 函数与剩余
- 函数与解构
- Function
- 用字符串创建一个函数
- 所有函数们的粑粑
- 箭头函数
- 箭头函数木有arguments
- 箭头函数木有this
函数的形参与实参
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都指向实际的参数
下例中&#xff0c;实际传入的第一个参数的值将会被修改&#xff0c;并且在arguments中得到显示
function ifn(a,b,c){console.log(arguments[0]);a &#61; &#39;x&#39;; //实际传入的第一个参数的值将会被修改&#xff0c;并且在arguments中得到显示console.log(arguments)&#xff1b;
}
ifn(1,2,3)<<<
1
{ &#39;0&#39;: &#39;x&#39;, &#39;1&#39;: 2, &#39;2&#39;: 3 }
函数、剩余运算符与解构运算
函数与剩余
注意&#xff0c;若使用剩余运算符必须在形参的末尾处使用
function sum(zero,...args){return currency&#43;eval(args.join(&#39;&#43;&#39;));
}
sum (0,1,2,3,4,5,6)
函数与解构
对象作为实参可在形参处被解构
function ajax({url&#61;new Error(&#39;url不能为空&#39;),method&#61;&#39;get&#39;}){...
}
ajax({url:&#39;/test&#39;,method:&#39;get&#39;});
但并不支持解构数组
let fn1 &#61; function(...args){console.log(args)
};fn1([1,2,3])<<<
[ [ 1, 2, 3 ] ]
//--- --- ---
let fn1 &#61; function(a,b,c){console.log(a)
};fn1([1,2,3])<<<
[1,2,3]
Function
用字符串创建一个函数
此种创建函数的方式常常和模板拼接一起配套使用&#xff0c;让我们能够更自由的创建函数
let strFnBody &#61; &#96;if(arg1)console.log(&#39;参数存在&#39;)&#96;;
let fn &#61; Function(&#39;arg1&#39;,&#39;arg2&#39;,...,strFnBody);
fn(); //执行函数
所有函数们的粑粑
所有函数都是Function函数的实例
let fn1 &#61; function(){};
console.log(fn1.__proto__ &#61;&#61;&#61; Function.prototype)
<<<
true
箭头函数
箭头函数木有arguments
替代方案是利用剩余运算符&#xff0c;嘿&#xff0c;我们得到了还是一个真·数组
(...args)&#61;>{console.log(args);
}<<<
[ 1, 2, 3 ]
其次虽然没有arguments,我们仍然能通过fn.length
来拿到形参的个数
let arrow &#61; (a,b,c)&#61;>{ console.log(arrow.length)
}
arrow(1,2,3);<<<
3
箭头函数木有this
let obj &#61; {fn:function(){console.log(this);}
}
let fn &#61; obj.fn;
fn(); //global||window
obj.fn(); //obj
//--- --- ---
let obj &#61; {fn:()&#61;>{console.log(this);}
}
let fn &#61; obj.fn;
fn(); //本模块的最顶层的this window||{}
obj.fn(); //因为箭头函数不再有this会往上找&#xff0c;如果是nodejs会找到{}&#xff0c;如果是浏览器会找到window
当一个函数本身没有this时&#xff08;箭头函数&#xff09;&#xff0c;那么谁调用的函数this就指向谁这句话就不再适用&#xff0c;它会查找上级作用域的this是指向谁。而又因为Node.js中&#xff0c;最顶层的作用域&#xff08;模块作用域&#xff09;的this指向的是{}
&#xff08;空对象&#xff09;&#xff0c;故上栗中会指向{}。&#xff08;注意Node.js中文件模块的this并不指向全局对象global&#xff0c;而浏览器是指向window全局对象的&#xff09;
函数作用域链的查找
函数作用域链的查找 是顺着【函数定义时】所处的作用域来查找的
let b &#61; &#39;123&#39;function bbb(){console.log(b)}(function(){let b &#61; &#39;bbb&#39;;bbb(); //123})();