1.作为值传进去的函数
函数名可以作为函数的参数传进去,进行一系列的计算,我们在平常的业务逻辑中应该会看到这样的:
function sum(param) { return param + 10; } function a(fun, param) { return fun(param); }; const res = a(sum, 20); console.log(res); // 30
2.对于递归函数的使用小技巧
我们都知道在计算阶乘的时候,在函数的内部会进行递归计算,一直计算到乘以1。
function factorial(num) { if(num <= 1) { return 1; } return num * factorial(num - 1); }
在上面的这个函数里,可以发现函数名个函数体中的递归函数式紧耦合的,这就会使得在一定的场景下出现问题😆,我在下面进行演示。
const fun = factorial; fun(10); // 在执行时对于函数体中的factorial就会找不到了
又会用什么方案去解决呢?(๑•ᴗ•๑),答案是可以使用arguments的属性callee进行解决,该属性是一个指针,它指向拥有这个arguments对象的函数,所以上面的例子可以改为下面。
function factorial(num) { return num * arguments.callee(num - 1); } let fun = factorial; // 下面的两个函数执行时会正常执行,因为函数体中的函数名和函数名不是紧耦合了 fun(3); // 6 factorial(5); //120
3.函数内部的属性this
对于this,我一般理解的都是指向调用创建函数的实例,这里指的是函数的执行环境。
var color = "red"; function test() { console.log(this.color); //red,这里的this指向的是当前函数执行的环境,这里的环境就是 window } var obj = {color: "blue"}; obj.fun = test; // 将test指针赋值给obj.fun obj.fun(); //blue,这里的函数的执行环境变为了obj,所以this.color就是obj.color
4.函数的属性length和继承方法
length属性表示函数希望接收到的命名参数的个数。arguments是一个类数组的对象,它的length属性代表是传递给函数的实际参数的个数。
function fun(a, b) { // 函数体 } console.log(fun.length); // 2
对于这个函数继承的两个方法,之前使用最多的还是call(),apply()方法之前也使用,但使用的场景很少。但是在书中又发现了一个新的知识就是和apply()方法的书写区别。
function sum(a, b) { return a + b; } // 对call()方法的使用 function test1(num1, num2) { return sum.call(this, num1, num2); //这里是继承了sum方法,返回两个数的和,this指的是全局变 量window } test1(10, 20); // 30 // 对apply方法的使用 function test2(num1, num2) { return sum.apply(this, [num1, num2]); //这里是继承了sum方法,返回两个数的和,this指的是全 局变量window } test2(10, 30); // 和以上apply()方法的不同,这也是我第一次见这么写的,很有趣 function test3(num1, num2) { return sum.apply(this, arguments); // 第二个参数变化了,arguments代表的是传给test3的类 数组对象,长见识啦! } test3(20, 30); // 50
这里针对上面的方法,总结一下:
- call()方法可以接受多个参数,第一个是所调用的函数的执行环境,其余的参数是传递给这个函数的参数,是枚举出来的
- apply()方法接受两个参数,第一个参数是所调用的函数的执行环境,第二个参数是传递给这个函数的参数所组成的数组,当然还可以直接写成arguments
- 如果不需要传递,则调用那个方法都是一样的
其还有一个作用就是可以扩充函数运行的作用域
window.color = "red"; var obj = {color: "blue"}; function fun() { console.log(this.color); } fun.call(this); // red,因为函数是在全局作用域下,所以这里的this指的就是window对象 fun.call(window); // red,这里就是扩充函数运行的作用域的一个体现,传入的不是this,而是window fun.call(obj); // blue, 这里扩充的函数运行的作用域就是obj
5.bind()方法
这个方法是通过函数名调用bind(),作用和上面的call()和apply()方法进行扩充函数作用域相似,都是通过传入的参数,改变当前函数的执行环境。
还可以通过在函数的末尾打点调用bind()使用,这和下面的使用函数名调用bind()函数一样。
window.name = "lisi"; var person = {name: "zhangsan"}; function test() { console.log(this.name); } test(); // lisi test.call(this); // lisi test.apply(this); // lisi test.bind(this); // lisi, 这里绑定的this就是全局对象window test.bind(person); // zhangsan, 这里绑定的是person对象,改变函数体中的this的指向,现在this对象代表的是person
网友评论