admin管理员组

文章数量:1317906

I am trying to set the direction dynamically but something is not working. I do not get an error.

function moveSelection(keyPressed) {
    var group = canvas.getActiveGroup(),
    obj = canvas.getActiveObject();

    if(!group && !obj) {return;}

    var direction = '',
        sign = '',
        operators = {
            '+': function(a, b) { return a + b },
            '-': function(a, b) { return a - b },
        };
    switch(keyPressed) {
        case 37:
            direction = 'left';
            sign = '-';
        break;
        case 38:
            direction = 'top';
            sign = '-';
        break;
        case 39:
            direction = 'right';
            sign = '+';
        break;
        case 40:
            direction = 'bottom';
            sign = '+';
        break;
    }

    if(group){
        group.set({
            direction : operators[sign](group.get(direction), 1)
        });
        canvas.renderAll();
    } else {
      obj.set({
        direction : operators[sign]( obj.get(direction),1 )
      });
      canvas.renderAll();
    }
}

But when i change the code to the following then it works fine.. What is wrong? Thank you:

obj.set({
    'left' : operators[sign]( obj.get(direction),1 )
});

I am trying to set the direction dynamically but something is not working. I do not get an error.

function moveSelection(keyPressed) {
    var group = canvas.getActiveGroup(),
    obj = canvas.getActiveObject();

    if(!group && !obj) {return;}

    var direction = '',
        sign = '',
        operators = {
            '+': function(a, b) { return a + b },
            '-': function(a, b) { return a - b },
        };
    switch(keyPressed) {
        case 37:
            direction = 'left';
            sign = '-';
        break;
        case 38:
            direction = 'top';
            sign = '-';
        break;
        case 39:
            direction = 'right';
            sign = '+';
        break;
        case 40:
            direction = 'bottom';
            sign = '+';
        break;
    }

    if(group){
        group.set({
            direction : operators[sign](group.get(direction), 1)
        });
        canvas.renderAll();
    } else {
      obj.set({
        direction : operators[sign]( obj.get(direction),1 )
      });
      canvas.renderAll();
    }
}

But when i change the code to the following then it works fine.. What is wrong? Thank you:

obj.set({
    'left' : operators[sign]( obj.get(direction),1 )
});
Share Improve this question edited Oct 22, 2013 at 17:17 kangax 39.2k13 gold badges100 silver badges135 bronze badges asked Oct 13, 2013 at 23:29 Lucky SoniLucky Soni 6,8883 gold badges39 silver badges58 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 12

TLDR

Use obj.set(direction, ...).

But why?

I've been bitten by this few times myself. Even after knowing that it's not supposed to work :)

But this is how Javascript works:

In your snippet, the "direction" in object literal is interpreted as "direction" property:

obj.set({
  direction : operators[sign]( obj.get(direction),1 )
});

just like foo in this object literal:

var foo = 'x';
var obj = { foo: 'bar' };

creates a property named "foo" rather than property named "x" (which foo variable "contains").

It might seem a little weird, since you're not writing:

var obj = { 'foo': 'bar' };

where foo is written as a string literal rather than an identifier. But to Javascript (up to ECMAScript 5), it doesn't really matter. The only difference is that using identifier notation, you can only represent properties that are also valid... identifiers.

So these, for example, are invalid as identifiers:

{
  'foo-bar': 'baz',
  '5leafs': 123,
  'or.with': 'dots'
}

which is why we have to write them as string literals.

This confusion might also e from the fact that bracket notation in Javascript does allow to create dynamic properties:

var foo = 'x', obj = { };
obj[foo] = 'bar';

This creates a property named "x" rather than "foo". Whereas if we performed assignment via dot notation:

obj.foo = 'bar';

it would create a property named "foo".

So this is, arguably, Javascript limitation, since we can't have both object literals AND dynamically-evaluated properties:

obj.foo         // does NOT evaluate
obj[foo]        // evaluates

({ foo: ... })  // does NOT evaluate
?               // evaluates

So why did I mention ECMAScript 5 before?

Because in ECMAScript 6 (an uping standard), we're likely to have so-called "puted property names", where you'll be able to dynamically evaluate property name in an object literal like so:

var foo = 'x';
var obj = { [foo]: 'bar' };

obj.foo; // undefined
obj.x; // 'bar'

I'm really looking forward to this one.

本文标签: javascriptFabricjsUnable to set properties dynamicallyStack Overflow