Function的之callee

187 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

上篇文章我们学习了函数的caller, 谁调用了我?

今天我们就来学习callee,我是谁!

定义

callee这个属性并不是属于Function的属性,而是属于 arguments的属性。 它可以用于引用该函数的函数体内当前正在执行的函数。

简单说,就是 我是谁!

function sum(num1, num2){
    console.log("sum===arguments.callee:", sum === arguments.callee);
    return num1 + num2;
}
sum()
// sum === arguments.callee: true

严格模式

我们在严格模式下试试, 在代码顶部添加use strict

"use strict"
function sum(num1, num2){
    console.log("sum===arguments.callee:", sum === arguments.callee);
    return num1 + num2;
}
sum()

结果是收到如下的错误的提示: image.png

更多关于严格模式,可以参见 严格模式 MDN

起源

// TODO::

命名函数表达式

用途

递归

主要是匿名函数,没办法获得对函数的引用,比如如下例子:

const utils = {
    sumTotal: function (n) {
        if (n == 1) return 1;
        return arguments.callee(n - 1) + n;
    }
}

console.log("sumTotal:", utils.sumTotal(100)
// sumTotal: 5050

其实上面的代码也可以写成如下:
utils.sum替换arguments.callee

const utils = {
    sumTotal: function (n) {
        if (n == 1) return 1;
        return utils.sumTotal(n - 1) + n;
    }
}

console.log("sumTotal:", utils.sumTotal(100))
// sumTotal: 5050

那再换一个例子:

function sumTotal(n) {
    if(n == 1) return 1;
    return arguments.callee(n - 1) + n;
};

console.log([5, 10, 20].map(sumTotal))
// [ 15, 55, 210 ]

上线的写法没问题,如果使用匿名函数呢?

console.log([5, 10, 20].map(function(){
    if(n == 1) return 1;
    return /这里写什么呢?/(n - 1) + n;
}))

答案就是arguments.callee:

console.log([5, 10, 20].map(function(n){
    if(n == 1) return 1;
    return arguments.callee(n - 1) + n;
}))
// [ 15, 55, 210 ]

写这么多,有人说,给函数取个名字不行吗? 答案是行啊,这不是为了演示, 特定场景下非你不可以吗?

我就是要用匿名函数,可能就是非你不可。

动态创建的函数

var sumTotal = new Function("n", `
    if(n == 1) return 1;
    return /这里写什么?/(n - 1) + n;
`)

这里,arguments.callee闪亮登场!

var sumTotal = new Function("n", `
    if(n == 1) return 1;
    return arguments.callee(n - 1) + n;
`)

console.log(sumTotal(100));

附送一个吧

所以能不能用,我们检查是不是有严格模式和处于严格模式。

有没有严格模式:
主要是利用严格模式下 this 是等于undefined这个特性

var hasStrictMode = (function(){ 
 "use strict";
 return this == undefined;
}()); 

是否处于严格模式:

var isStrict = (function(){
  return this === undefined;
}());

小结

今天一起学了函数的一个有意思的特性, callee, 其属于arguments的属性,不是Function的属性,大多数情况下并没有太多的用途,而且严格模式还不可以使用, 但是匿名函数和动态函数场景下,还是有其特定的作用。

今天你收获了吗?

引用

深入理解JavaScript系列(2):揭秘命名函数表达式
arguments.callee