当前位置: 首页 > 知识库问答 >
问题:

javascript元编程?

卫宏硕
2024-02-26

javascript元编程?

问题来自于codewars The builder of things

要求我们实现一个Thing类,其中一点要求如下所示:

  describe('#can', function(){    describe('jane.can.speak(phrase => `${name} says: ${phrase}!`)', function(){      it('should create a speak method on jane', function(){        const jane = new Thing('Jane');        jane.can.speak(phrase => `${name} says: ${phrase}!`);        expect(jane.speak('hello')).to.equal('Jane says: hello!');      });    });

难点是这里的name的值从哪里找啊?

我想到的一个方案是使用with,但是codewars上使用的是严格模式,不能使用with

class Thing {  // TODO: Make the magic happen  /*    const jane = new Thing('jane');    console.log(jane.name) => 'jane'  */  constructor(name) {    this.name = name;            /*      can        jane.can.speak(phrase => `${name} says: ${phrase}!`)        jane.speak('Hello') => 'jane says: Hello!'      where to find name ? => this    */    this.can = {      speak: (callback) => {          this.speak = (...args) => {              let res;              with(this) {                 res = callback(...args);               };              return res;          }      }    }   }

共有2个答案

廉雅惠
2024-02-26

我有一计:

class Thing {    constructor(name) {        this.name = name;        globalThis.name = name;    }}

当然更好的做法是通过 Proxy 拦截 cangetter,在得到 speak 属性之前设置 globalThis.namespeak 函数调用之后还原 globalThis.name

也有其它做法:

Github gist:

const funcStr = callback.toString()const finalFunc = eval(funcStr)
宗政功
2024-02-26

在JavaScript中,元编程是一种编程范式,其中一部分代码用来控制另一部分代码的行为。在你给出的例子中,元编程是用来在运行时动态地向对象添加属性和方法的。

在你的代码中,你试图通过元编程的方式动态地给对象添加一个speak方法,这个方法可以访问对象的name属性。然而,你遇到了一个问题,那就是在严格模式下,with语句是不允许使用的。

在这种情况下,你可以使用闭包来解决问题。闭包是一种函数,它可以记住并访问其词法作用域,即使它是在这个作用域之外执行的。在你的例子中,你可以创建一个闭包函数来访问this.name

class Thing {  constructor(name) {    this.name = name;    this.can = {      speak: (callback) => {        this.speak = (...args) => {          return callback(this.name, ...args);        }      }    }  }}

这样,当你调用jane.can.speak(phrase => ${name} says: ${phrase}!)时,你实际上是在创建一个新的函数,这个函数可以访问this.name。然后,当你调用jane.speak('hello')时,实际上是在调用这个闭包函数,并传入'hello'作为参数。因此,闭包函数可以访问this.name,并使用它来构建你期望的字符串。

 类似资料:
  • 技术的学习是一个登山的过程。第一章是最为平坦的山脚道路。而从这一章开始,则是正式的爬坡。无论是我写作还是你阅读,都需要付出比第一章更多的代价。那么问题就是,付出更多的精力学习模板是否值得? 这个问题很功利,但是一针见血。因为技术的根本目的在于解决需求。那C++的模板能做什么? 一个高(树)大(新)上(风)的回答是,C++里面的模板,犹如C中的宏、C#和Java中的自省(restropection)

  • 元编程 避免无谓的元编程。 当编写程序库时,不要使核心类混乱(不要使用 monkey patch)。 对于 class_eval 方法,倾向使用区块形式,而不是字符串插值形式。 当使用字符串插值形式时,总是提供 __FILE__ 及 __LINE__,以使你的调用栈看起来具有意义: class_eval 'def use_relative_model_naming?; true; end', __

  • Metaprogramming is a programming technique in which computer programs have the ability to treat other programs as their data. It means that a program can be designed to read, generate, analyze or tran

  • 问题内容: 在IE中,我只能从JavaScript调用element.click()-如何在Firefox中完成相同的任务?理想情况下,我希望有一些跨浏览器同样可以正常工作的JavaScript,但是如果需要,我将为此使用不同的逐浏览器JavaScript。 问题答案: 该文件说:“ 该 _createEvent_方法已被弃用。使用事件构造来代替。 ” 因此,您应该改用以下方法: 并在这样的元素上

  • 我希望根据Get/SetProperty的文档,在Spock测试中重写方法。这在正常的Groovy类中是微不足道的,但在Spock规范中似乎不起作用。 此示例不调用方法。看来斯波克在绕过它。有没有一种方法可以钩入Spock的属性解析机制,或者告诉Spock使用我的重写方法?

  • 问题1 此问题改编自Dave Thomas的屏播Episode 5: Nine Examples of Metaprogramming。 众所周知,RubyLearnin.org的Core Ruby课程已经开办8周了。每周我们都有一个满分10分的测验。8周结束后,学生可以知道他的分数百分比。例如,有一个学生,在过去的8周里,他的得分情况为:5、10、10、10、10、10、10、10。那么,他的得