【问题标题】:What is the difference (if any) between the different function declarations within JavaScript objects?JavaScript 对象中不同的函数声明之间有什么区别(如果有的话)?
【发布时间】:2020-07-14 09:15:00
【问题描述】:

我有一个 JavaScript 对象:

var methods = {

  classStyle() {
    console.log('Class style function');
  },

  traditionalStyle: function() {
    console.log('Traditional style function');
  },

  arrowStyle: () => {
    console.log('Arrow style function');
  }

};

methods.classStyle();
methods.traditionalStyle();
methods.arrowStyle();

输出如预期:

(index):70 Class style function
(index):74 Traditional style function
(index):78 Arrow style function

我的问题是:

  1. 这些不同的声明方法有什么区别吗?
  2. 这取决于个人喜好吗?还是内部运作方式发生变化?
  3. 在使用不同的样式时有什么注意事项吗?

【问题讨论】:

标签: javascript ecmascript-6


【解决方案1】:

“类风格函数”(速记方法)与常规函数非常相似。唯一的区别是它不能用作构造函数(即用new 调用),因此它没有prototype 属性。箭头函数见Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?。简而言之,箭头函数不会绑定自己的thisarguments,也不能与new 一起使用。

这取决于个人喜好吗?还是内部运作方式发生变化?

在 ES6+ 中,没有理由在对象中使用传统的函数语法,因为速记方法语法更简单、更安全,因为如果您不小心尝试将方法用作构造函数,则会出错。至于箭头函数,只有在不需要使用this访问对象时才可以使用。

【讨论】:

  • @maerics 不,因为this 与动态调度一起工作,这与箭头函数非常不同。它们实际上是三种不同的东西。
  • "class-style" 也可以在函数表达式不能使用的地方使用super.foo,箭头取决于父作用域是否允许super.foo
  • @loganfsmyth 它有任何实际用途吗?一个普通的对象无论如何都没有父类,除非你用Object.setPrototypeOf()手动设置它。
  • 你当然也可以用__proto__ 声明一个对象字面量。无论哪种方式,对象都以父级结尾,super.foo 工作正常。这可能不常见,但差别很大。
【解决方案2】:

正如前面提到的,作为补充,first 和 second 并不相同。一个主要区别是它们的可用位置和方式。看到这个 sn-p,你会看到创建对象时方法定义可用,但函数声明不可用。

这意味着当您使用传统样式定义时,您不能在对象的其他地方使用它,它将是未定义的。类风格将可用,这是一个巨大的差异。

methods = {
  classStyle() {

    //console.log('class this is', this);
    return 'class';
  },

  traditionalStyle: function() {
    //console.log('traditional this is', this);
    return 'tradition';

  },

  arrowStyle: () => {
    console.log('arrow this is', this);
  },

  testFn() {
    console.log('class is', this.classStyle);
    console.log('traditionnal is', this.traditionnalStyle);
  },

  get classProp() {
    return this.classStyle();
  },

  get traditionnalProp() {
    return this.traditionnalStyle();
  }

};



methods.testFn();
console.log(methods.classProp);
console.log(methods.traditionnalProp);

【讨论】:

    【解决方案3】:

    arrowStyle由于箭头函数的不同而不同。有关this 的差异,请参见下文:

    var methods = {
    
      classStyle() {
        console.log('class this is', this);
      },
    
      traditionalStyle: function() {
        console.log('traditional this is', this);
      },
    
      arrowStyle: () => {
        console.log('arrow this is', this);
      }
    
    };
    
    methods.classStyle.call(5);
    methods.traditionalStyle.call(5);
    methods.arrowStyle.call(5);

    【讨论】:

    • 另见@Michał Perłakowski 发布的链接
    猜你喜欢
    • 2011-04-27
    • 2011-09-20
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多