◆

JavaScript 函数声明、属性与参数传递详解

2023-02-02 01:370

函数声明

  • function 命令
function fnn(name) {
  console.log(name);
}
  • 函数表达式
const fnn = function (name) {
  console.log(name);
};

注意点

函数表达式的写法相当于将一个匿名函数赋值给变量。 函数表达式声明的函数,function 命令后面不带有函数名。如果加上函数名, 该函数名只在函数体内部有效,在函数体外部无效

const fnn = function fx(name) {
  console.log(name);
  console.log(fx);
};

/**
 输出 fnn 以及
 ƒ fx(name) {
     console.log(name);
     console.log(fx);
   }
 */
fnn('fnn');

// Uncaught ReferenceError: fx is not defined
fx('fx');

加入函数名出现报错,有函数名称则显示函数名称

const fnn = function (name) {
  console.log(name);
  throw Error(1);
};

fnn('fnn');

// 控制台报错测试

const fnn = function fx(name) {
  console.log(name);
  throw Error(1);
};

fnn('fnn');

在控制台的显示如下

js函数知识

使用函数名称实现自调用

const fnn = function fx(name) {
  console.log(name);
  if (name === 'fx') {
    return;
  }
  fx('fx');
};

fnn('fnn');

输出如下

js函数知识
  • Function 构造函数
const fnn = new Function(
  'name',
  'age',
  'sex',
  "return 'name:' + name + ' age:' + age + ' sex:' + sex",
);

// name:fx age:18 sex:girl
console.log(fnn('fx', 18, 'girl'));

// 等同于
function copyFnn(name, age, sex) {
  return 'name:' + name + ' age:' + age + ' sex:' + sex;
}

const fx = Function(
  'name',
  'age',
  'sex',
  "return 'name:' + name + ' age:' + age + ' sex:' + sex",
);

// name:fnn age:18 sex:girl
console.log(fx('fnn', 18, 'girl'));

测试如下

js函数知识

上述代码中 Function 构造函数接受三个参数,除了最后一个参数是 fnn 函数的“函数体”,其他参数都是 fnn 函数的参数。

  • 只有最后一个参数会被当做函数体,如果只有一个参数,该参数就是函数体。
  • Function 构造函数可以不使用 new 命令,输出结果一致

对象中函数的 name 属性

对象方法也是函数,因此也有 name 属性

const person = {
  sayName() {
    console.log('hello!');
  },
};

person.sayName.name;

如果对象的方法使用了取值函数(getter)和存值函数(setter),则 name 属性不是在该方法上面,而是该方法的属性的描述对象的 get 和 set 属性上面,返回值是方法名前加上 get 和 set。

const obj = {
  get foo() {},
  set foo(x) {},
};

obj.foo.name;
// TypeError: Cannot read property 'name' of undefined

const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');

descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo"

有两种特殊情况

  • bind 方法创造的函数,name 属性返回 bound 加上原函数的名字;
  • Function 构造函数创造的函数,name 属性返回 anonymous。
new Function().name; // "anonymous"

var doSomething = function () {
  // ...
};
doSomething.bind().name; // "bound doSomething"

如果对象的方法是一个 Symbol 值,那么 name 属性返回的是这个 Symbol 值的描述。

const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
  [key1]() {},
  [key2]() {},
};
obj[key1].name; // "[description]"
obj[key2].name; // ""

函数提升相关

函数提升相关

函数的属性与方法

  • name 属性
function fnn() {}

// fnn
console.log(fnn.name);

var fx = function () {};
// fx
console.log(fx.name);

var wfly = function fly() {};
// fly
console.log(wfly.name);
js函数知识
  • length 属性

函数的 length 属性返回函数预期传入的参数个数,即函数定义之中的参数个数

它的 length 属性就是定义时的参数个数。不管调用时输入了多少个参数

function fnn(name, age, sex) {
  console.log(fnn.length);
}

// 输出 3
fnn();
  • toString() 方法

返回一个字符串,内容是函数的源码

function fnn(name, age, sex) {
  console.log(fnn.length);
}

// 输出函数源码
console.log(fnn.toString());
js函数知识

原生的函数,toString() 方法返回 function (){[native code]}

// 'function isNaN() { [native code] }'
console.log(isNaN.toString());

函数作用域相关

函数作用域

函数参数的省略

如下代码所示,函数调用时省略的参数都是 undefined,如果一定要省略靠前的参数,只有显式传入 undefined。

function fnn(name, age, sex) {
  console.log(name, age, sex);
}

// fnn undefined undefined
fnn('fnn');

// undefined 18 undefined
fnn(undefined, '18');

同名参数

如果有同名的参数,则取最后出现的那个值。

function fnn(name, name) {
  console.log(name);
}

// undefined
console.log(fnn('fnn'));

// 18
console.log(fnn(undefined, '18'));

值的传递

function fnn(obj, money) {
  obj.age = 8;
  money = 1000;
}

const messgae = {
  name: 'wfly',
  age: 18,
};

const num = 100;

fnn(messgae, num);

// {name: 'wfly', age: 8}
console.log(messgae);
// 100
console.log(num);
js函数知识

如上述所示,message 的值被修改了,但是 num 的值没有被修改。

  • 函数参数如果是原始类型的值(数值、字符串、布尔值),传递方式是传值传递。这意味着,在函数体内修改参数值,不会影响到函数外部。
  • 如果函数参数是复合类型的值(数组、对象、其他函数),传递方式是传址传递。也就是说,传入函数的原始值的地址,因此在函数内部修改参数,将会影响到原始值。
  • 如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值。 这是因为,形式参数(函数的参数)的值实际是外部参数的地址,重新对形式参数赋值导致形式参数指向另一个地址,保存在原地址上的值当然不受影响。

arguments 详解

arguments 详解

立即执行函数表达式(IIFE)

立即执行函数表达式

eval 函数

eval 函数

💬留言板0

还没有留言,来发表第一条吧~

PAGE LOAD / LIVEJavaScript 函数声明、属性与参数传递详解加载中