如何创建一个原型函数,将另一个原型函数绑定为语法糖(并保留实例的上下文)?

时间:2013-11-18 14:28:27

标签: javascript prototype syntactic-sugar

我已经声明了原型函数A.a,但是想通过其他函数提供一些语法糖,例如A.sayHiA.sayBye。问题是绑定上下文,因为我当然希望它指向实例但在我声明原型时无法访问它。

function A() {
    this.txt = 'so';
};

A.prototype.a = function (txt) {
    alert(txt + ' ' + this.txt);
}

A.prototype.sayHi = A.prototype.a.bind(A, 'hi');

A.prototype.sayBye = A.protoype.a.bind(A.prototype, 'bye');

当我new A().sayHi().sayBye();时,我收到“hi undefined”和“bye undefined”的警报。当然,我可以做到

A.prototype.sayHi = function() {
    this.a('hi');
}; 

但那太丑了:)

有没有一种方法可以保留实例的上下文(以便this.txt等于'so')而无需编写函数?

3 个答案:

答案 0 :(得分:2)

绑定不是你想要的。

Bind旨在创建一个包装this指针的函数(调用Bind时必须存在),以避免编写大量临时函数,如

var that = this;
callMeBack(function() { that.callback(); });

(即以上变为)

callMeBack(this.callback.Bind(this));

它可以用于部分应用/限制currying,但在你的情况下,你试图调用Bind时没有this。您绝对不希望构造函数或其原型对象为this,您希望它是实际对象,但在运行此代码时不存在。

你的最后一个例子是完全正确的。


离题:我不认为它是丑陋的 - 它是明确的,明确的,高度惯用的Javascript。也许是一个轻浮的啰嗦。如果您觉得这很难看,那么您可能还没有习惯使用Javascript。习惯于作为一流数据使用,例如:

var A = function() { ... };

而不是

function A { ... }

前者是Javascript对后者的意思。养成将功能视为另一种数据类型的习惯,将帮助您“获得”Javascript并看到其固有的美感。并且会产生副作用,当你为node.js编程时,你不会被“丑陋”的冒犯所冒犯:)

答案 1 :(得分:1)

您可以尝试少量更改a功能

function A() {
    this.txt = 'so';
};

A.prototype.a = function (txt) {
    return function(){
        alert(txt + ' ' + this.txt);
        return this;
    }
}

A.prototype.sayHi = A.prototype.a("Hi")

A.prototype.sayBye = A.protoype.a('bye');

答案 2 :(得分:0)

这对你有用吗?

function runtimeContextBinder(func){
    var args = Array.prototype.slice.call(arguments, 1);
 return function(){
   func.apply(this,args);
 }
}

function A() {
    this.txt = 'so';
};

A.prototype.a = function (txt) {
    alert(txt + ' ' + this.txt);
}

A.prototype.sayHi = runtimeContextBinder(A.prototype.a,'hi');

A.prototype.sayBye = runtimeContextBinder(A.prototype.a, 'bye');

我在这里做的是在函数上创建一个闭包,然后在实例的上下文中执行。