【问题标题】:simulating javascript function with arrow function用箭头函数模拟javascript函数
【发布时间】:2016-08-06 22:02:43
【问题描述】:

我想知道是否有可能以某种方式将 javascript 箭头函数“绑定”到其作用域的原型实例。

基本上,我想使用箭头函数从原型中获取实例变量。我知道这不能仅通过箭头函数来完成,但我很好奇是否可以在分配它之前将此箭头函数绑定到实例范围。类似的想法:

String.prototype.myFunction = (() => {
    console.log(this.toString());
}).naiveBindNotionICantDescribe(String.prototype);

相当于:

String.prototype.myFunction = function() {
    console.log(this.toString());
};

我很好奇,因为我想看看 javascript 箭头函数是否可以完全取代 javascript 函数,如果你对它们足够了解并且对它们很聪明,或者如果没有关键字“function”的话,有些事情是绝对不可能完成的,甚至以聪明的方式。

这是我的意思的一个例子:

/* anonymous self-contained demo scope. */
{
    /**
     * example #1: using function to reach into instance variable via prototype 
     * anonymous scope.
     */
    {
        String.prototype.get1 = function() {
            return this.toString();
        };
        console.log('hello'.get1());
    }

    /** 
     * example 2: what I want to do but can't express in a way that works.
     * This does not work.
     * anonymous scope.
     */
    {
        String.prototype.get2 = () => {
            return this.toString();
        };

        console.log('hello'.get2());  
    }  
}

这是可能的吗,或者是函数绝对需要访问实例变量并且没有办法绕过这个?

明显的解决方案

  1. wrapper magicBind(感谢 Thomas)

代码:

var magicBind = (callback) => function() { 
    return callback(this);
};
String.prototype.get = magicBind((self) => {
    return self.toString();
});
console.log('hello'.get());
  1. 从“胖箭头”到“函数”的函数转换器,(受 Thomas 的回答启发)

代码:

Function.prototype.magicBind2 = function() {
    var self = this;

    return function() {
        return self(this);
    }
};

String.prototype.get2 = ((self) => {
    return self.toString();
}).magicBind2();

console.log('hello'.get2());
  1. 第一个没有显式使用“函数”的解决方案,将“函数”构造函数称为 (() => {}).constructor 以避免使用“函数”或“函数”一词。

代码:

var regex = /\{([.|\s|\S]+)\}/m;

String.prototype.get = (() => {}).constructor(
    (() => {
        return this;
    }).toString().match(regex)[0]
);

console.log('hello, world'.get());

到目前为止,这两种解决方案都允许隐藏“function”关键字,同时允许访问本地范围。

【问题讨论】:

  • 只有 1 个问题:为什么要用粗箭头语法版本替换每个函数?你想失去兼容性吗?
  • 胖箭头没有自己的thisarguments-object。所以你不能用胖箭头完全替换函数。海事组织。它们的主要目的是充当回调函数。
  • 我想了解是否可以这样做。我正在考虑javascript是否可以在没有“function”关键字的情况下存在。是的,兼容性很糟糕,但是如果您了解它们之间的关系并且可以相互表达,您可以通过编写自己的解析器轻松地将箭头函数转换为函数(反之亦然)。
  • @Dmitry — No. bind/apply/call/etc 对箭头函数没有影响。
  • @Dmitry 您在粗箭头内看到/使用的this 是一个闭包,您将this 变量从周围的上下文中封闭起来。它与实际的(胖箭头)函数调用无关。 arguments 也是如此。

标签: javascript functional-programming


【解决方案1】:

没有。词法绑定this 值是箭头函数的point

它们不是函数声明和函数表达式的一般替代品。

【讨论】:

  • 从技术上讲,这不是胖箭头函数的重点。这只是开发后期添加的一个功能。它们的主要目的是作为函数的语法糖,但它们主要用于您想要在回调中访问父对象的地方。
  • 那么你是说这是不可能的,还是说这不是它们应该被使用的方式。
  • 不可能。如果不是,我会说“是的,但你不应该”。
【解决方案2】:

我希望做一些魔术,包括将实例作为参数传递给箭头函数,并使用这个实例“self”代替“this”。类似于 hastebin.com/baxadaxoli.coffee 但没有“功能”的东西。例如,在赋值期间传递“self”而不通过一些 magicBind 操作创建函数。

var magicBind = (callback) => function (...args) {
    'use strict';
    return callback(this, args);
}

var log = (self, args) => {
  console.log('this: %o args: %o', self, args);
};

String.prototype.log = magicBind( log );

'hello'.log();

足够的魔法? ;)

编辑:但是,你为什么坚持使用粗箭头。即使你必须跳过循环来实现你想要的。只是从你的 .min.js 文件中刮掉几个字符

/* logget 更合适,

console.log() 没有返回值的函数的结果是没有意义的;如果该函数的唯一目的是调用 console.log() 本身,那就更少了 */

【讨论】:

  • 我自己也得出了类似的结论:hastebin.com/fanowawebi.coffee,除了我努力避免将名称放入其中,而不是按照我最初想要的方式明确设置原型。如果 JavaScript 中内置了这样的构造,那么您可以将任何粗箭头转换为“函数”而不使用“函数”。实际上,我认为这正是我想要的:hastebin.com/mikipuwupe.coffee,尽管措辞很奇怪,尤其是 self(this) 部分。这样它的行为类似于绑定,而不是外部函数。
  • 我仍然很好奇不使用“function”是否真的不可能,但是有了这个,您可以在实现中将“function”关键字隐藏起来,并在必要时恢复它。
  • 不,不是。这就是这个问题的所有答案的重点。胖箭头没有(他们自己的)这个对象。这根本不像bind()。绑定将一个传递的 this-object 锁定到位,而此代码将传递的 this-object 在每个函数调用上作为函数参数传播到某个回调。但是,你为什么要坚持这样做呢?不需要写function 可能一开始看起来不错,直到你意识到你必须改写(...).magicBind2(),再加上你的代码变得复杂,你限制了你的可能性
  • 我知道。我很好奇“magicBind”的实现是否已经以不同的名称存在,或者可以从不使用“function”的现有函数派生。如果没有首先创建一种将胖箭头转换为函数的方法,就像在现有解决方案中所做的那样,那么确实是不可能的(之后,只要您将实现隐藏起来,关键字 function 就不再是“必要的”(并且您的代码本身不包含关键字function))。
【解决方案3】:

我知道这不能仅通过箭头函数来完成,但我很好奇 如果还可以将此箭头函数绑定到实例 分配之前的范围。

确实,它可以单独完成,但您可以将 this 设置为所需的值...通过将其包装在普通函数中:

String.prototype.get2 = function() {
  return (() => this.toString())();
};
console.log('hello'.get2());

但到那时,箭头功能就变得多余了。

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-30
    • 2017-04-18
    • 2019-10-21
    • 2022-01-21
    相关资源
    最近更新 更多