除了绑定之外,任何其他上下文解析的解决方案都在承诺中

Any other solution for context resolution this in promises except bind

本文关键字:解决方案 承诺 上下文 绑定 其他 任何      更新时间:2023-09-26

在这种情况下,当我需要知道我在哪个类而不使用bind时,任何横向解决方案

function Customer() {}
Customer.prototype.say = function() {
    console.log("I'm " + this.constructor.TYPE);
};
Customer.TYPE = 'customer';
function Product() {}
Product.prototype.say = function() {
    console.log("I'm " + this.constructor.TYPE);
};
Product.TYPE = 'product';
var customer = new Customer();
var product = new Product();
//cleaner interface
Promise.resolve()
    .then(customer.say) //I'm undefined
    .then(product.say) //I'm undefined

//works but looking for a solution using cleaner interface like above
//any lateral thinking
Promise.resolve()
    .then(customer.say.bind(customer)) //I'm customer
    .then(product.say.bind(product))  //I'm product

我正在寻找基于非绑定的解决方案,任何基于横向思维的想法?

这是一个SDK我正在开发,所以想给一个更干净的界面和使用的客户端。

你基本上有三个选择:

  1. bind,你说过你不想要。

  2. 像这样的包装器函数:

    .then(function(r) { return customer.say(r); })
    

    …在ES2015中可以像这样:

    .then(r => customer.say(r))
    
  3. 修改你的对象,使它们不再使用从原型继承的函数,而是使用实例特定的函数,在实例上关闭:

    ES5及更早版本:

    var Customer = function() {
        var me = this;
        me.say = function() {
            console.log("I'm " + me.constructor.TYPE);
        };
    };
    
    在ES2015 +

    var Customer = function() {
        this.say = () = {
            console.log("I'm " + this.constructor.TYPE);
        };
    };
    

    这样你最终会创建更多的函数对象,但是函数中的代码将被JavaScript引擎重用。

TC39委员会有一个提案,为一个操作符定义JavaScript,做你想做的(基本上是bind,但语法更干净),但它只是在阶段0,所以不太可能在ES2017。

几点思考:

1)不要使用原型/类。他们会一次又一次地制造这样的问题。相反,使用模块模式。由于每次"方法"都在闭包中创建,因此它们被有效地绑定:
function Customer() {
    function say() {}
    return {
        type: 'product',
        say
    }
}

2)提供一个构造来构建一个基于原型的对象层次结构,其中所有的方法都是预先绑定的。注意,这去掉了原型的唯一优点:稍微减少内存消耗。

3)大胆一点,使用babel提供的::符号:(:: customer.say)不可否认,并没有那么好,而且这个命题目前有点过时,所以它甚至可能不会正式进入语言。