一、函数是一种对象
函数的构造函数是Function()
所以创建一个函数可以这么写:
let f1 = new Function('x', 'y', 'return x + y')
但这种写法太复杂,一般没有使用
但这种写法可以让我们知道:
所有函数都是Function构造出来的,包括Object, Array, Function
1.1 常见的定义函数方式
具名函数
function 函数名(形参1, 形参2) {
语句
return 返回值
}
匿名函数
具名函数去掉函数名就是匿名函数
let a = function(x, y) {return x + y}
箭头函数
let f1 = x => x*x
let f2 = (x, y) => x+y //圆括号不能省略
let f3 = (x, y) => {return x+y} //花括号不能省
let f4 = (x, y) => ({name:x, age:y}) // 直接返回对象会出错,需要加一个圆括号
二、函数的执行机制
www.yuque.com/docs/share/… 《JS 函数的执行时机》
三、函数提升
什么是函数提升
function fn(){}
不管你把具名函数声明在哪里,它都会跑到第一行去
什么不是函数提升
let fn = function(){}
这是在赋值,右边的匿名函数不会提升
四、arguments 和 this
所有函数都有arguments和this, 除了箭头函数
箭头函数没有arguments, 箭头函数没有this!!!箭头函数默认this是window,拿call或者apply改了也没用
function fn(x, y, z){
console.log(arguments)
console.log(this)
}
arguments是函数形式参数的伪数组
如果不指定this, this默认是window
4.1 用call传this
但如果传进去的this不是一个对象,而是一个数字,默认情况下,JS会自动把数字装箱成对象
function fn(x, y, z){
console.log(arguments)
console.log(this)
}
fn.call(1)
可以看到打印出的this是 new Number(1) 创造出来的一个Number对象
如果我们不希望JS把数字变成对象,可以在函数里写一句 'use strict'
如果传进去的this是Undefined,JS会让this是window
小结:this的值:
-
如果什么都不传,默认是window
-
如果传一个对象,this就是这个对象
-
如果传一个数字,JS会把数字封装成对象
-
如果传Undefined, JS会把this设置为this => 其实和第一种情况等价, 即不传this
关于this的究极真理:谁调用函数,谁就是this
如果不传this,就默认this是window
4.2 call的用法
fn.call(xxx, 1, 2, 3)
第一个参数是this, 后面所有的参数是arguments
Array.prototype.forEach2 = function(fn) {
for (let i = 0; i < this.length; i++) {
fn(this[i], i)
}
}
let arr = [1,2,3]
arr.forEach2.call(arr, (item)=>console.log(item))
打印出来1,2,3
4.3 bind的用法:
绑定this和参数
4.4 apply 的用法:
该方法的语法和作用与call方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
求数组里的的最大值和最小值:
const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);
console.log(max);
// expected output: 7
const min = Math.min.apply(null, numbers);
console.log(min);
// expected output: 2