最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - this.set is not a function - Stack Overflow

programmeradmin8浏览0评论

I have code like this:

var ws2812 = {};


ws2812.set = function(r,g,b){
    $.get( "/light?r="+r+"&g="+g+"&b="+b, function( data ) {
        console.log("Light set to:"+"/light?r="+r+"&g="+g+"&b="+b);
    })
};

ws2812.speech = function(word){
    switch(word){
        case "czerwone":
            this.set(255,0,0);
        break;
        case "zielone":
            this.set(0,255,0);
            break;
        case "niebieskie":
            this.set(0,0,255);
            break;
        case "białe":
            this.set(255,255,255);
            break;
        default:
            this.set(0,0,0);
            break;

    }
}

When running ws2812.speech(""); inside console, everything works. However, when paired with the Annyang library, I get this:

Uncaught TypeError: this.set is not a function 
ws2812.speech @ script.js:29  
b.annyang.init.d.onresult @ annyang.min.js:6

What's wrong?

[edit]

The mand is added like this:

annyang.addCommands({"ustaw *term światło":ws2812.speech});

Specifically, inside annyang, this line fails:

f[h].callback.apply(this,m)

Is replacing this with ws2812 the only way to work around this?

I have code like this:

var ws2812 = {};


ws2812.set = function(r,g,b){
    $.get( "/light?r="+r+"&g="+g+"&b="+b, function( data ) {
        console.log("Light set to:"+"/light?r="+r+"&g="+g+"&b="+b);
    })
};

ws2812.speech = function(word){
    switch(word){
        case "czerwone":
            this.set(255,0,0);
        break;
        case "zielone":
            this.set(0,255,0);
            break;
        case "niebieskie":
            this.set(0,0,255);
            break;
        case "białe":
            this.set(255,255,255);
            break;
        default:
            this.set(0,0,0);
            break;

    }
}

When running ws2812.speech(""); inside console, everything works. However, when paired with the Annyang library, I get this:

Uncaught TypeError: this.set is not a function 
ws2812.speech @ script.js:29  
b.annyang.init.d.onresult @ annyang.min.js:6

What's wrong?

[edit]

The mand is added like this:

annyang.addCommands({"ustaw *term światło":ws2812.speech});

Specifically, inside annyang, this line fails:

f[h].callback.apply(this,m)

Is replacing this with ws2812 the only way to work around this?

Share Improve this question edited Jun 14, 2015 at 17:07 Robus asked Jun 14, 2015 at 16:52 RobusRobus 8,2695 gold badges51 silver badges70 bronze badges 1
  • 1 are you passing the unbound speech function as a callback? Please include the code that fails in your example. – zzzzBov Commented Jun 14, 2015 at 16:58
Add a ment  | 

1 Answer 1

Reset to default 2

ws2812.speec is defined as a static function. So this keyword inside it refers to itself (function scope), not the object ws2812 you want.

To fix it, either of these quick choices can be made:


Choice#1 > Call the static function ws2812.set properly

So your code bees:

ws2812.speech = function(word){
    switch(word){
    case "czerwone":
        ws2812.set(255,0,0);
    break;
    case "zielone":
        ws2812.set(0,255,0);
        break;
    case "niebieskie":
        ws2812.set(0,0,255);
        break;
    case "białe":
        ws2812.set(255,255,255);
        break;
    default:
        ws2812.set(0,0,0);
        break;

    }
}

However, there are some possibilities that this keywords referenced in other parts in the rest of the code may also suffer from this issue. You may need to go check it.


Choice#2 > Convert to prototype functions

This way you can retain this keywords, but the functions are no longer static. You need to instantiate an instance object of ws2812 to use.

So your declarations bees:

var ws2812 = function(){};


ws2812.prototype.set = function(r,g,b){
    $.get( "/light?r="+r+"&g="+g+"&b="+b, function( data ) {
        console.log("Light set to:"+"/light?r="+r+"&g="+g+"&b="+b);
    })
};

ws2812.prototype.speech = function(word){
    switch(word){
    case "czerwone":
        this.set(255,0,0);
    break;
    case "zielone":
        this.set(0,255,0);
        break;
    case "niebieskie":
        this.set(0,0,255);
        break;
    case "białe":
        this.set(255,255,255);
        break;
    default:
        this.set(0,0,0);
        break;

    }
}

Then use it via instance of object instead:

var myWs2812 = new ws2812();
myWs2812.speech('hello world!'); // inside it, should call this.set properly

Choice#3 > Bind 'this' object when calling

In case you insist you don't want to modify the implementation of this ws2812. It's okay to leave it and bind this object when using it instead.

So when you call ws2812.speech, you need to use function.prototype.call and pass in ws2812.set as this.

ws2812.call( ws2812.set, 'hello world!' );

However, this doesn't look much semantic and it may cause confusions in the future use for people who will maintain this code.


I'll leave it for you to decide which would be the best way for you to go.

发布评论

评论列表(0)

  1. 暂无评论