函数&&对象

  • 函数实际上是对象
  • 函数都是Function类型的实例
  • Function也有属性和方法
  • 函数名是指向函数对象的指针

定义函数的几种方式

① 函数声明

1
2
3
function fun(param1,param2){
return param1 + param2;
}

② 函数表达式

1
2
3
let fun = function(num1, num2){
return num1 + num2;
}

③ 箭头函数

1
2
3
let fun = (param1, param2) => {
return param1 * param2;
}

④ Function构造函数

1
let fun = new Function('param1','param2','return param1 % param2');

Function构造函数的参数

  • 最后一个参数 始终被当做函数体
  • 非最后一个参数 作为新函数的参数

不推荐使用原因:两次解释代码,会影响性能

  1. 将它当做常规ECMAScript代码
  2. 解释传给构造函数的字符串

重要的是:

把函数想象为对象,
把函数名想象为指针

10.1.1 箭头函数

箭头函数适合嵌入函数的场景

1
2
3
let ints = [1, 2, 3];
console.log(ints.map(function (i) { return i + 1 }));
console.log(ints.map(i => i + 1));

只有一个参数的情况下可以不加括号

1
2
3
4
5
6
// 一个参数可以省略括号
let triple = x => { return 3 * x; }
// 没有参数需要括号
let getRandom = () => { return Math.random(); }
// 多个参数需要括号
let sum = (a, b) => { return a + b; }

函数体单条语句隐藏大括号表示返回这行代码的值

1
2
3
4
5
6
let triple = x => 3 * x;
// 直接赋值
let value = {};
let setName = x => x.name = 'Matt';
setName(value);
console.log(value.name); //Matt

箭头函数局限

  • 不能使用 arguments、super、new.target
  • 不能用作构造函数
  • 没有 protortpe 属性

10.1.2 函数名

函数名作为指针就意味着:
一个函数可以有多个名称

1
2
3
4
5
6
7
8
function sum(num1, num2) {
return num1 + num2;
}
console.log(sum(10, 20)); //30
let anotherSum = sum;
console.log(anotherSum(10, 10)); //20
sum = null;
console.log(anotherSum(10, 10)); //20

函数的name属性

  • name属性一般保存的是函数标识符
  • name属性只读
  • 没有名称的函数,name为空字符串
  • Function构造的函数,name为’anonymous’
1
2
3
4
5
6
7
8
function foo() { }
let bar = function () { };
let baz = () => { };
console.log(foo.name); //foo
console.log(bar.name); //bar
console.log(baz.name); //baz
console.log((() => { }).name); //''
console.log((new Function()).name); //anonymous

特殊函数的标识前缀

对于获取函数get、设置函数set、使用bind()实例化的函数,
标识符前会加上一个前缀

函数前缀
getget
setset
bindbound
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function foo() { }

console.log(foo.bind(null).name); //bound foo

let dog = {
years: 1,
get age() {
return this.years;
},
set age(newAge) {
this.years = newAge;
}
}
let propertyDescriptor = Object.getOwnPropertyDescriptor(dog, 'age');
console.log(propertyDescriptor.get.name); //get age
console.log(propertyDescriptor.set.name); //set age