首页 > 解决方案 > 使用函数调用作为默认参数 javascript

问题描述

帮助我理解为什么我不能执行以下操作:

function rgb(r = 0, g = 0, b = 0) {
  this.r = r % 255
  this.g = g % 255
  this.b = b % 255,
    this.str = function() {
      return `rgb(${this.r}, ${this.g}, ${this.b})`
    }
}

function rect(w, h, x, y, rgb = new rgb()) {
  this.dim = {
    w: w,
    h: h
  }
  this.pos = {
    x: x,
    y: y
  }
  this.rgb = rgb
}

我收到以下错误(调用时rect()):

ReferenceError:在初始化之前无法访问词法声明“rgb”

function rgb(r = 0, g = 0, b = 0) {
  this.r = r % 255
  this.g = g % 255
  this.b = b % 255,
    this.str = function() {
      return `rgb(${this.r}, ${this.g}, ${this.b})`
    }
}

function rect(w, h, x, y, rgb = new rgb()) {
  this.dim = {
    w: w,
    h: h
  }
  this.pos = {
    x: x,
    y: y
  }
  this.rgb = rgb
}

const r = new rect(1, 2, 3, 4);

rgb和都rect定义在同一个文件中,并且rgbrect.

标签: javascriptdefault-parametersdefault-arguments

解决方案


您的变量名称有冲突。您rgb在顶层有一个函数,但rgbrect的参数列表中也有一个参数。在参数列表中,当引用变量名时,解释器将尝试查找变量名绑定到的内容 - 如果参数列表已经具有该变量名,它将引用该绑定。new rgb()引用rgb尚未初始化的参数也是如此。

这并不完全是发生了什么,但参数列表的范围看起来有点像参数名称用 声明let,然后分配值,例如范围

const fn = (a, b, c = 'bar') => {
  console.log('fn invoked');
};

类似于:

const fn = (argA, argB, argC) => {
  let a;
  let b;
  let c;
  a = argA;
  b = argB;
  c = argC === undefined ? 'bar' : argC;
  fnBody(a, b, c);
};
const fnBody = (a, b, c) => {
  console.log('fn invoked');
}

这样做rgb = new rgb()就像

let rgb;
rgb = argRGB === undefined ? new rgb() : argRGB
//                               ^^^ reference to un-initialized variable

出于类似的原因,您可以这样做:

const fn = (a, b = a) => {
  console.log(a, b);
};

fn('foo');

同样,在声明变量时,在变量完成初始化之前,您不能引用要声明的变量的名称:

const foo = null || foo;

精确的函数名称也有助于防止错误。考虑改为:

function makeColors(r = 0, g = 0, b = 0) {
  this.r = r % 255;
  this.g = g % 255;
  this.b = b % 255;
  this.str = function() {
    return `rgb(${this.r}, ${this.g}, ${this.b})`
  };
}

function rect(w, h, x, y, colors = new makeColors()) {
  this.dim = {
    w: w,
    h: h
  }
  this.pos = {
    x: x,
    y: y
  }
  this.colors = colors
}

const r = new rect(3, 4, 5, 6);
console.log(r);


推荐阅读