javascript,为原型添加功能

时间:2017-07-10 22:32:07

标签: javascript prototype curry

在javascript中,是否可以使用类似咖喱的原型添加函数?

我尝试使用此代码

var helloGoodBye = function (name, fun) {
  return function(message) {
    console.log('hello : ' + name);
    console.log(message);
    console.log('byebye : ' + name);
    return fun(message)
  }                                                                                           
}

var Machine = function (){
  this.state = 'green';
};

Machine.prototype = {
  green: helloGoodBye('green', function (message){
    this.state = 'red';
  }),
  red: helloGoodBye('red', function (message){
    this.state = 'green';
  })
}

var sm = new Machine();

sm[sm.state]('first message');
sm[sm.state]('second message');

我得到了这个输出

"hello state: green"
"first message"
"byebye state: green"
"hello state: green"
"second message"
"byebye state: green"

但这种方式不起作用,可能是因为函数中调用的this.statethis.state生活在全球范围内。

2 个答案:

答案 0 :(得分:2)

是的,您只需要让方法调用接收器对象上的fun回调。使用call

function helloGoodBye(name, fun) {
  return function(message) {
    console.log('hello : ' + name);
    console.log(message);
    console.log('byebye : ' + name);
    return fun.call(this, message);
//            ^^^^^ ^^^^
  }                                                                                           
}

答案 1 :(得分:1)

这是因为this内的func不是您班级的实例。它是全局对象windowhelloGoodBye返回的匿名函数是将this设置为类实例的函数(它是附加到原型的函数)。 func是一个隐藏在闭包中的匿名函数,但它与类本身的实例无关。

使用Function.prototype.call之类的替代方法明确指定this

var helloGoodBye = function (name, fun) {
  return function(message) {
    console.log('hello : ' + name);
    console.log(message);
    console.log('byebye : ' + name);
    return fun.call(this, message); // use the this in this scope which will be the instance of the object
  }                                                                                           
}

var Machine = function (){
  this.state = 'green';
};

Machine.prototype = {
  green: helloGoodBye('green', function(message) {
    this.state = 'red';
  }),
  red: helloGoodBye('red', function(message) {
    this.state = 'green';
  })
}

var sm = new Machine();

console.log(sm);
sm[sm.state]('first message');
sm[sm.state]('second message');