ES6 函数扩展:参数默认值;reset 剩余参数;name属性;箭头函数用法以及不能访问arguments,无法new,没有this,this指向父作用域使用

60 阅读2分钟

1. 参数默认值

1.1 基本用法

// 传统写法
function greet(name) {
  name = name || 'Guest';
  return `Hello, ${name}!`;
}

// ES6 默认参数
function greet(name = 'Guest') {
  return `Hello, ${name}!`;
}

console.log(greet()); // "Hello, Guest!"
console.log(greet('John')); // "Hello, John!"

1.2 复杂默认值

// 使用函数作为默认值
function getDefaultName() {
  return 'Guest_' + Date.now();
}

function greet(name = getDefaultName()) {
  return `Hello, ${name}!`;
}

// 参数之间的引用
function createUser(
  name = 'Guest',
  age = 18,
  email = `${name.toLowerCase()}@example.com`
) {
  return { name, age, email };
}

2. rest 参数(剩余参数)

2.1 基本用法

// 收集剩余参数
function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15

// 与其他参数结合
function printInfo(title, ...items) {
  console.log(title);
  items.forEach(item => console.log(`- ${item}`));
}

printInfo('Shopping List', 'Apple', 'Banana', 'Orange');

2.2 实际应用场景

// 1. 函数重载
function handleEvent(eventName, ...handlers) {
  handlers.forEach(handler => {
    element.addEventListener(eventName, handler);
  });
}

// 2. 构建查询字符串
function buildURL(baseURL, ...params) {
  const queryString = params
    .map(param => `${param.key}=${param.value}`)
    .join('&');
  return `${baseURL}?${queryString}`;
}

// 3. 日志记录
function logger(level, ...messages) {
  const timestamp = new Date().toISOString();
  console.log(timestamp, level, ...messages);
}

3. name 属性

3.1 基本用法

// 函数声明
function sayHello() {}
console.log(sayHello.name); // "sayHello"

// 函数表达式
const sayBye = function() {};
console.log(sayBye.name); // "sayBye"

// 箭头函数
const greet = () => {};
console.log(greet.name); // "greet"

3.2 特殊情况

// bind 创建的函数
const boundFunction = sayHello.bind(null);
console.log(boundFunction.name); // "bound sayHello"

// 对象方法
const obj = {
  sayHi() {}
};
console.log(obj.sayHi.name); // "sayHi"

// class 中的方法
class Person {
  constructor() {}
  sayName() {}
}
console.log(new Person().sayName.name); // "sayName"

4. 箭头函数

4.1 基本语法

// 基本形式
const add = (a, b) => a + b;

// 单个参数可以省略括号
const double = x => x * 2;

// 无参数需要括号
const getTime = () => Date.now();

// 多行代码需要大括号和 return
const calculate = (x, y) => {
  const sum = x + y;
  const product = x * y;
  return { sum, product };
};

4.2 特性和限制

4.2.1 没有自己的 this

// 传统函数中的 this 问题
const counter = {
  count: 0,
  start: function() {
    setInterval(function() {
      this.count++; // this 指向 window
    }, 1000);
  }
};

// 箭头函数解决方案
const counter = {
  count: 0,
  start: function() {
    setInterval(() => {
      this.count++; // this 指向 counter 对象
    }, 1000);
  }
};

4.2.2 不能访问 arguments

// 传统函数
function sum() {
  return Array.from(arguments).reduce((a, b) => a + b, 0);
}

// 箭头函数替代方案
const sum = (...args) => args.reduce((a, b) => a + b, 0);

4.2.3 不能用作构造函数

// 传统构造函数
function Person(name) {
  this.name = name;
}
const person = new Person('John');

// 箭头函数不能用作构造函数
const Person = (name) => {
  this.name = name;
};
const person = new Person('John'); // TypeError

4.3 实际应用场景

// 1. 数组方法回调
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);
const evens = numbers.filter(x => x % 2 === 0);

// 2. Promise 链式调用
fetchUser()
  .then(user => fetchUserPosts(user.id))
  .then(posts => processUserPosts(posts))
  .catch(error => console.error(error));

// 3. React 组件
const Button = ({ onClick, children }) => (
  <button onClick={onClick}>
    {children}
  </button>
);

5. 最佳实践

5.1 何时使用箭头函数

// ✅ 适合使用箭头函数的场景
// 1. 简单的计算和转换
const square = x => x * x;

// 2. 回调函数
elements.forEach(el => {
  el.addEventListener('click', () => {
    console.log('Clicked!');
  });
});

// ❌ 不适合使用箭头函数的场景
// 1. 对象方法
const obj = {
  name: 'John',
  greet: () => {
    console.log(this.name); // this 不指向 obj
  }
};

// 2. 原型方法
class Person {
  name = 'John';
  greet = () => {
    console.log(this.name);
  }; // 每个实例都会创建一个新函数
}

5.2 参数默认值最佳实践

// 1. 使用对象解构设置默认值
function createUser({
  name = 'Guest',
  age = 18,
  email = null
} = {}) {
  return { name, age, email };
}

// 2. 避免副作用
let counter = 0;
// ❌ 不好的实践
function increment(step = counter++) {}

// ✅ 好的实践
function increment(step = 1) {
  counter += step;
}