JavaScript:覆盖在构造函数中为整个类定义的属性 [英] JavaScript: Overwrite property defined in constructor for whole class

查看:21
本文介绍了JavaScript:覆盖在构造函数中为整个类定义的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试覆盖类的功能:

I am trying to overwrite the function of a class:

class MyClass {
  constructor() {
    // more code
  }

  myFunction = function() {
    console.log('not this')
  }
}

// can't change the code above

MyClass.prototype.myFunction = function() {
  console.log('it should print this')
}

new MyClass().myFunction()

但是Babel将上面的内容编译为此:

But Babel compiles the above to this:

class MyClass {
  constructor() {
    // more code

    this.myFunction = function () {
      console.log('not this');
    };
  }
}

// can't change the code above

MyClass.prototype.myFunction = function () {
  console.log('it should print this');
};

new MyClass().myFunction();

因为该函数在原始代码中定义为属性,所以Babel将该定义放入构造函数中.如果我正确理解原型,则仅包含函数,而不是所有属性.因为构造函数是在对象从原型派生之后运行的,所以我不能使用原型来覆盖该函数.

Because the function is defined as a property in the original code, Babel puts that definition in the constructor. If I understand correctly prototype only contains functions, not all properties. Because the constructor runs after the object was derived from the prototype, I can't use the prototype to overwrite that function.

第二次尝试是覆盖构造函数:

My second try was overwriting the constructor:

class MyClass {
  constructor() {
    // more code
  }

  myFunction = function () {
    console.log('not this')
  }
}

// can't change the code above

let oldConstructor = MyClass.prototype.constructor
MyClass.prototype.constructor = function() {
  // call old constructor first, it will set myFunction
  oldConstructor()

  // now overwrite myFunction
  this.myFunction = function () {
    console.log('it should print this')
  }
}

new MyClass().myFunction()

好吧,让我们尝试...使用Babel进行编译,将其保存到test.js并运行:

Well, let's try... Compile with Babel, save it to test.js and run:

~> node test.js
not this

我试图使这个问题尽可能地笼统.有关为何无法在特定情况下更改类的更多背景信息:该类实际上来自我正在使用的库,而我使用的其他程序包也依赖于该库.MeteorJS要求程序包指定其依赖项的确切版本和来源,这就是为什么我不能使用派生的原因:我必须派生每个依赖于此库的包.

I tried to make the question as general as possible. More background information on why I can't change the class in my specific case: The class is actually from a library I'm using and other packages I use depend on that library too. MeteorJS requires packages to specify the exact version and source of their dependencies, which is why I can't use a fork: I would have to fork every package that depends on this library.

推荐答案

事实上,您正在更改您的课程,但是由于

In fact you are changing your class, but it is "not taking" effect because how javascript interpreter looks for information inside its objects. First, properties inside object, then prototype chain.

在第一个示例中,如果删除"本地属性,则更改将生效.示例:

In your first example, if you "remove" local propertie, you change takes effect. Example:

    class MyClass {
  constructor() {
    // more code

    this.myFunction = function () {
      console.log('not this');
    };
  }
}

// can't change the code above

MyClass.prototype.myFunction = function () {
  console.log('it should print this');
};

const obj = new MyClass();
delete obj.myFunction;
obj.myFunction();

https://jsbin.com/gixufadewu/edit?js,console

这篇关于JavaScript:覆盖在构造函数中为整个类定义的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆