《JS函数》

89 阅读2分钟

一、函数是一种对象

函数的构造函数是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的值:

  1. 如果什么都不传,默认是window

  2. 如果传一个对象,this就是这个对象

  3. 如果传一个数字,JS会把数字封装成对象

  4. 如果传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