Function.name

995 阅读2分钟

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

前言

函数有具名函数,也有匿名函数,其实都是有一个name属性的,平时可能大家感觉不到啥用处,在特定场景还是非你不可,今天一起来学习Function.name属性吧。

具名函数函数名

具名函数

function sum(num1, num2){
  return num1 + num2;
}

console.log("name:", sum.name); 
// name: sum

匿名函数函数名

匿名函数, name的值为空字符串。

var person = {
  name: "Tom"
};

person.getName = function (){
  return this.name
}

console.log("name:", person.getName.name); 
// name: 

到这里,你也许以为你已经懂了,其实还不然。

var sum = function (num1, num2){
    return num1 + num2;
} 

var person = {
    name: "tom",
    getName: function(){
        return this.name;
    }
}

console.log("sum.name:", sum.name);
// sum.name: sum
console.log("person.getName.name:", person.getName.name);
// person.getName.name: getName

这就是推断函数名称,变量和方法可以从句法位置推断匿名函数的名称(ECMAScript 2015中新增)。

到这里,你也许你以为又懂了,哦哦!

var person = {
  name: "tom",
  getName: function getNameMethod(){
      return this.name;
  }
}
console.log("person.getName.name:", person.getName.name);
// person.getName.name: getNameMethod

这个例子中函数getName.name并不等于getName,而是getNameMethod,是不是很有意思。

再回头看看:

const sum = function sumFun(num1, num2){
  return num1 + num2;
}
console.log("sum.name", sum.name);
// sum.name sumFun

所以,要以函数的名字为准,而不是变量名或者属性名为准,如果没有定义函数名,那么就可能走推导。

new Function 函数名

我们也可以使用new Function创建函数,那么这类函数的name值是什么呢?

// new Function 
var addFn = new Function("num1", "num2", "return num1 + num2");

console.log(addFn(1,2));
// 3
console.log("name:", addFn.name);
// name: anonymous

可以看出,name的值为 anonymous

属性简写函数名

方法名就是属性名。

var person = {
    name: "Tom",
    getName(){
        return this.name;
    }
}
console.log("person.getName.name:",person.getName.name);
// person.getName.name: getName

被bind之后的函数名

创建的函数将会在函数的名称前加上"bound ",注意有一个空格。

function sum(num1, num2){
    return num1 + num2;
}

const sumBound = sum.bind(null, 1);
console.log("sumBound.name:", sumBound.name);

// sumBound.name: bound sum

getter和setter函数名

getter和setter也是函数系列,其规则是 get [函数名]或者set [函数名];

var person = {
  _name: "Tom",
  get name(){
    return this._name;
  },
  set name(val){
    this._name = val;
  }
}

var descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log("get.name:", descriptor.get.name); 
// get.name: get name
console.log("set.name:", descriptor.set.name); 
// set.name: set name

Symbol作为函数名

const symbolGetName = Symbol("getName");
const symbolGetName2 = Symbol("getName2");
const symbolGetName3 = Symbol("getName3");
const person = {
    name: "Tom",
    [symbolGetName]: function getNameMethod(){
        return this.name;
    },
    [symbolGetName2](){
        return this.name;
    },
    [symbolGetName3]: function(){
      return this.name;
  },
}

console.log("symbolGetName.name:", person[symbolGetName].name);
// symbolGetName.name: getNameMethod

console.log("symbolGetName2.name:", person[symbolGetName2].name);
// symbolGetName2.name: [getName2]

console.log("symbolGetName3.name:", person[symbolGetName3].name);
// symbolGetName3.name: [getName3]

可以看出,又分几种情况

  1. 作为属性值得函数本身有名字(非简写)
    name为作为属性值得函数名称
  2. 简写
    name为 [Symbol名]
  3. 推导
    name为[Symbol名]

函数名的作用

递归

调试或者跟踪

小结

函数名也是很有意思的一个属性,你学会了吗? 今天你收获了吗?

引用

Function.name