首页 > 解决方案 > 在 this 上定义的方法与在类主体中定义的方法的区别

问题描述

当我通过在构造函数中向类的所有实例添加方法时有什么区别

this.bar = function() {}

而不是在类体中定义函数权

baz() {}

?

class Foo {
  constructor() {
    this.bar = function() {};
  }
  
  baz() {}
}

console.log(Object.prototype.hasOwnProperty.call(new Foo, 'bar')); // true
console.log(Object.prototype.hasOwnProperty.call(new Foo, 'baz')); // false

如果我只是在构造函数中替换this.bazthis.baz,两个测试都返回true

class Foo {
  constructor() {
    this.bar = function() {};
    this.baz = this.baz;
  }
  
  baz() {}
}

console.log(Object.prototype.hasOwnProperty.call(new Foo, 'bar')); // true
console.log(Object.prototype.hasOwnProperty.call(new Foo, 'baz')); // true now

标签: javascriptes6-class

解决方案


当您this.bar = function() { };在构造函数中执行此操作时,您将为每个实例创建一个新函数,并将其分配给bar属性。如果您愿意,这可以让函数关闭构造函数中的某些内容。(如果您使用箭头函数,该函数将关闭this并且super。)

当您在 中声明一个方法时class,您将在该类将分配给实例的原型对象上创建一个函数,并重用该函数。super如果需要访问超类功能,这可以让函数使用。

两者都有自己的位置,具体取决于您在做什么。您可以在这里看到这种差异:

class Foo1 {
    constructor() {
        this.bar = function() {};
    }
}

class Foo2 {
    bar() {}
}

const f1a = new Foo1();
const f1b = new Foo1();
console.log(f1a.bar === f1b.bar); // false

const f2a = new Foo2();
const f2b = new Foo2();
console.log(f2a.bar === f2b.bar); // true

对这个:

this.baz = this.baz;

class Foo {
  constructor() {
    this.bar = function() {};
//             vvvvvvvv−−−−−−−−−−−−−−− reads from the prototype
    this.baz = this.baz;
//  ^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−− writes to the instance

  }
  
  baz() {}
}

那是在原型上查找函数,然后直接在对象上分配它,这就是为什么它在分配后成为自己的属性。


推荐阅读