Skip to content

Function ​

Function 对象提供了用于处理函数的方法。在 JavaScript 中,每个函数实际上都是一个 Function 对象。

构造函数 ​

Function() 创建一个新的 Function 对象。直接调用此构造函数可以动态创建函数,但会遇到和 eval() "evaluate"(求值) 类似的安全问题和(相对较小的)性能问题。然而,与 eval() 不同的是,Function 构造函数创建的函数只能在全局作用域中运行。

实例属性 ​

以下属性定义在 Function.prototype 上,并且被所有 Function 实例共享。

Function.prototype.arguments 已弃用 非标准 ​

表示传递给该函数的参数。对于严格模式、箭头函数、异步函数和生成器函数,访问 arguments 属性会抛出 TypeError 异常。请改为在函数闭包内使用 arguments 对象。

Function.prototype.caller 已弃用 非标准 ​

表示调用该函数的函数。对于严格模式、箭头函数、异步函数和生成器函数,访问 caller 属性会抛出 TypeError 异常。

Function.prototype.constructor ​

创建实例对象的构造函数。对于 Function 实例来说,初始值是 Function构造函数 。

以下属性是每个 Function 实例的自有属性。

displayName 非标准 可选 ​

函数的显示名称。

length ​

指定函数期望的参数个数。

name ​

函数的名称。 name 属性是只读的,不能用赋值运算符修改:

prototype ​

在使用 function 作为构造函数与 new 运算符一起使用时,用作新对象的原型。

实例方法 ​

Function.prototype.apply() ​

>[!tip] 作用 >给调用函数提供this和一个参数的数组

使用给定的 this 值和可选的参数数组(或类数组对象)作为参数来调用一个函数。

语法:

js
apply(thisArg)
apply(thisArg, argsArray)

Function.prototype.bind() ​

>[!tip] 作用 >设置原函数的this和多个参数

Function 实例的 bind() 方法创建一个新函数,当调用该新函数时,它会==调用原始函数并将其 this 关键字设置为给定的值==,同时,还可以传入一系列指定的参数,这些参数会插入到调用新函数时传入的参数的前面。

语法:

js
bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* …, */ argN)

例子:

js
const module = {
  x: 42,
  getX: function () {
    return this.x;
  },
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42

参数:thisArg

  • 在调用绑定函数时,作为 this 参数传入目标函数 func 的值。
  • 如果函数不在严格模式下,null 和 undefined 会被替换为全局对象,并且原始值会被转换为对象。如果使用 new 运算符构造绑定函数,则忽略该值。

arg1, …, argN 可选 在调用 func 时,插入到传入绑定函数的参数前的参数。

返回值: 使用指定的 this 值和初始参数(如果提供)创建的给定函数的副本。

Function.prototype.call() ​

>[!tip] 作用 >给调用函数提供this和多个参数

Function 实例的 call() 方法会以给定的 this 值和==逐个==提供的参数调用该函数。

>[!notice] 备注:  这个函数几乎与 apply() 相同,只是函数的参数以列表的形式逐个传递给 call(),而在 apply() 中它们被组合在一个对象中,通常是一个数组——例如,func.call(this, "eat", "bananas") 与 func.apply(this, ["eat", "bananas"])。

语法:

js
call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /* …, */ argN)

例子:

js
function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5).name);
// Expected output: "cheese"

参数:thisArg 在调用 func 时要使用的 this 值。如果函数不在严格模式下,null 和 undefined 将被替换为全局对象,并且原始值将被转换为对象。

arg1, …, argN 可选 函数的参数。

返回值: 使用指定的 this 值和参数调用函数后的结果。

>[!caution] 警告:  >不要使用 call() 来链式调用构造函数(例如,实现继承)。这会将构造函数作为普通函数调用,这意味着 new.target 的值为 undefined,而类会抛出错误,因为它们不能在没有 new 的情况下被调用。请改用 Reflect.construct() 或 extends。

Function.prototype.toString() ​

返回表示函数源代码的字符串。重写了 Object.prototype.toString 方法。

Function.prototype[Symbol.hasInstance]() ​

指定确定构造函数是否将对象识别为其实例的默认过程。由 instanceof 运算符调用。

示例 ​

Function 构造函数与函数声明之间的不同 ​

由 Function 构造函数创建的函数不会创建当前环境的闭包,它们总是被创建于全局环境,因此在运行时它们只能访问全局变量和自己的局部变量,不能访问它们被 Function 构造函数创建时所在的作用域的变量。这一点与使用 eval() 执行创建函数的代码不同。

js
// 使用 `var` 创建一个全局属性
var x = 10;

function createFunction1() {
  const x = 20;
  return new Function("return x;"); // 这个 `x` 指的是全局 `x`
}

function createFunction2() {
  const x = 20;
  function f() {
    return x; // 这个 `x` 指的是上面的局部 `x`
  }
  return f;
}

const f1 = createFunction1();
console.log(f1()); // 10
const f2 = createFunction2();
console.log(f2()); // 20

虽然这段代码可以在浏览器中正常运行,但在 Node.js 中 f1() 会产生一个“找不到变量 x”的 ReferenceError。这是因为在 Node 中顶级作用域不是全局作用域,而 x 其实是在当前模块的作用域之中。

评论区

欢迎留言、补充或勘误。

xiaoba.blog