[JS]函数对象

函数对象

当我们对函数使用typeof操作符会返回什么?

function f() {
    console.log(‘hello‘)
}

console.dir(typeof f) // function

实际上函数是一种特殊的JavaScript对象。由于函数是对象,所以它也有属性和方法,甚至还可以使用Function()构造函数创建新函数对象。

函数属性

原有属性

length属性表示函数的参数列表中的参数个数。

name属性表示定义函数时使用的名字,如果是未命名的函数则为匿名函数。

prototype属性是函数对象的原型对象,每个函数都有自己的原型对象,当函数被作为构造函数使用是,新创建的对象从这个原型对象继承属性。

自定义属性

执行f.count = 0不是在函数内定义一个局部变量count。换句话说,函数属性和变量是毫不相关的两个东西。

函数是一种特殊的对象,可以在它里面添加属性,而且对它的执行没有任何影响。因此,可以将自定义属性缓存到函数对象中,而这个属性只有函数自己会用到。

function f() {
    console.log(‘hello‘)
    f.count++
}
f[‘count‘] = 1 // 自定义函数属性
f() // 执行函数
f() // 执行函数
console.log(`调用次数: ${f.count}`) // 2

使用函数自定义属性实现计算阶乘:

function f(n) {
    if (Number.isInteger(n) && n > 0) {
        if (!(n in f)) {
            f[n] = n * f(n - 1)
        }
        return f[n]
    } else {
        return NaN
    }
}
f[1] = 1 // 利用属性访问表达式f[1] = 1,初始化函数对象f存储的名为1的属性的值
f(6)
console.dir(f[5]) // 120,获取名为5的属性的值

[JS]函数对象

函数方法

call()

call()和apply()允许为不同的对象分配和调用属于一个对象的函数,提供新的 this 值给当前调用的函数。

let o = {
    print: function(date) {
        console.log(`Time: ${date} | ${this.name} 说:${this.content}`)
    }
}

let a = {
    name: ‘xiaoming‘,
    content: ‘今天天气真好!‘
}

let b = {
    name: ‘xiaohong‘,
    content: ‘今天天气一般!‘
}

o.print.call(a, new Date().getHours()) // Time: 22 | xiaoming 说:今天天气真好!
o.print.call(b, new Date().getHours()) // Time: 22 | xiaohong 说:今天天气一般!

call()和apply()类似于Java一样,子类继承父类,并调用父类方法。

bind()

bind()方法可以把函数绑定到对象上。如果在函数func上调用bind()方法并传入对象o,则这个方法会返回一个新函数,这个函数就像是func函数一样。

function func(y) {
    return this.x + y
}

let o = {
    x: 1
}

let bindFunc = func.bind(o)
console.log(bindFunc(10)) // 11

绑定完成之后,再将这个函数作为另一个对象的属性:

let p = {
  x: 10,
  bindFunc
}

console.log(p.bindFunc(10)) // 20 

说明bindFunc依旧绑定的是对象o。

构造方法

因为函数是对象,所以就有一个Function()构造函数可以用来创建函数:

const f = new Function(‘x‘, ‘y‘, ‘return x * y‘)

// 类似于

const f = function(x, y) {
  return x * y
}

[JS]函数对象

上一篇:上传文件


下一篇:Web前端(三)-文本和字体相关样式、元素显示方式display、盒子模型(宽高、外边距、边框、内边距)、CSS三大特性(继承、层叠性、选择器优先级)