Javascript Invalid left-hand side in assignment - javascript

In an attempt to add queue type functionality to nodejs's Buffer class, I have constructed the following function:
Buffer.prototype.popleft = function(n) {
tRet = this.slice(0,n);
this = this.slice(n,this.length-1); // error here
return tRet;
};
however, this code yields the following error:
"ReferenceError: Invalid left-hand side in assignment"
I know that the issue is with the assignment of 'this' within the function, what I dont know is better way of accomplishing this same type of logic.
EDIT:
Ended up writing an object around the Buffer as shown below:
sPort.vBuffer = {}
sPort.vBuffer.buff = new Buffer(0);
sPort.vBuffer.off = 0;
sPort.vBuffer.expect = -1;
sPort.vBuffer.ReadChr = function() {
this.off ++;
return this.buff[this.off - 1];
};
sPort.vBuffer.ReadUInt32LE = function() {
this.off += 4;
return this.buff.readUInt32LE(this.off - 4);
}
sPort.vBuffer.ReadInt32LE = function() {
this.off += 4;
return this.buff.readInt32LE(this.off - 4);
}
sPort.vBuffer.Write = function(aData) {
this.buff = Buffer.concat([this.buff.slice(this.off),aData])
this.off = 0;
};

You can't assign to this. You can assign to a copy of it, but in your case it looks like that won't do any good.
According to the Node documentation, Buffer instances cannot be resized. Now, whether that's because Node simply provides no APIs to do that, or because of some set of internal implementation assumptions/dependencies, I don't know. There sure doesn't look like any way to alter the length of a Buffer instance.
You could use .copy to shift the contents, and then fill the last position(s) with some dummy value (null or undefined I guess).

Related

Repeating Value and Replacing Value with JS

Newbie in JS here. I'm having trouble replacing and repeating the value from the function. Here's the code:
function Phone(ring) {
this.ring = ring;
}
function updateRing(newRing) {
this.newRing = ring;
}
var samsung = new Phone('Chim');
samsung.ring(2); // Needs to compute to "Chim, Chim"
var htc = new Phone('Dada');
htc.ring(3); // Needs to compute to "Dada, Dada, Dada"
htc.updateRing('Riri');
htc.ring(1); // Needs to compute to "Riri"
For the repeat value for the first function, I tried using this.repeat but it didn't work inside the Phone function.
For the updateRing function, I couldn't get the code to replace the this.ring.
I stripped down all the useless code I had written. Thanks in advance for any help.
You can repeat strings with string.repeat()
let a = "ring"
console.log(a.repeat(2))
But to get the comma separator to work cleanly you can make a disposable array and join() is with a comma.
let ringString = Array(3).fill("ring").join(", ")
console.log(ringString)
For the others, you probably want to use classes, which are pretty easy, but don't run on IE without a ployfill. Or prototypes, which can be a little confusing at first. Here's an example using prototypes to define methods on your Phone object:
function Phone(ring) {
// changed to ring_tone too prevent clash with this.ring method
this.ring_tone = ring;
}
// you need to define these on the prototype to you can use `this`
Phone.prototype.updateRing = function(newRing) {
// don't need to define a this.newRing, just update the ring
this.ring_tone = newRing;
}
Phone.prototype.ring = function(n) {
return new Array(n).fill(this.ring_tone).join(', ')
}
var samsung = new Phone('Chim');
console.log(samsung.ring(2)); // Needs to compute to "Chim, Chim"
var htc = new Phone('Dada');
console.log(htc.ring(3)); // Needs to compute to "Dada, Dada, Dada"
htc.updateRing('Riri');
console.log(htc.ring(1)); // Needs to compute to "Riri"
1) You're calling samsung.ring as a function, even though it's just an instance variable of Phone.
2) The reason why this.repeat didn't work is because repeat isn't a method of "this," which refers to Phone.
Try this instead:
var samsung = new Phone('Chim');
samsung.ring.repeat(2);
var htc = new Phone('Dada');
htc.ring.repeat(3);
Maybe try this:
class Phone {
constructor(sound) {
this.sound = sound;
}
ring(number) {
var i;
for (i = 0; i < number; i++) {
console.log(this.sound + ", ");
}
}
updateRing(newSound) {
this.sound = newSound;
}
}
var samsung = new Phone('Chim');
samsung.ring(2);
samsung.updateRing('Riri');
samsung.ring(1);
Codepen - https://codepen.io/anon/pen/MGRJOB?editors=0010

After Effects Script - Expression Controller Coordinates

Writing a script for After Effects 2015. Trying to copy coordinate data from a point expression controller to a layer's position data. I can't seem to find a way to point to the Expression Controller values.
for (i = 1; i <= app.project.activeItem.selectedLayers[0].property("Effects").numProperties; i++) {
app.project.items[2].layer(i).property("position").setValue(app.project.activeItem.selectedLayers[0].property("Effects").property(i).value);
}
I've also tried this:
for (i = 1; i <= app.project.activeItem.selectedLayers[0].property("Effects").numProperties; i++) {
app.project.items[2].layer(i).property("position").setValue(app.project.activeItem.selectedLayers[0].property("Effects").property(i).property("Point").value);
}
Any help would be appreciated. I'm hoping I didn't make any typos...
This should get you going. You need a layer with an expression point controler and it needs to be selected. I'm using here the match names of the effects. You can use the names from interface as well. I suggest getting the rd_GimmePropPath script from redefinery.com. Helps me every time.
function main() {
app.beginUndoGroup("XXX");
var curComp = app.project.activeItem; // get the current comp
if (!curComp || !(curComp instanceof CompItem)) {
// doulble check
alert("noComp");
return;
};
var layerwithpointcontroller = curComp.selectedLayers[0]; // the first selected layer
// get the value of the expression controler
var pointvalue = layerwithpointcontroller.property("ADBE Effect Parade")
.property("ADBE Point Control")
.property("ADBE Point Control-0001")
.value;
$.writeln(pointvalue); // take a look at it
var nullobject = curComp.layers.addNull();// add a null
nullobject.position.setValue(pointvalue);// set its position
app.endUndoGroup();
}
main();

Javascript "with" operator removal

I recently ran into some issues with a plugin and outlined the issue in this post: With operator & dashes in object keys and wanted to know if the modifications I've made below cover the scenarios that the with scope blocks would have covered.
I've modified some code to remove the with operator and I'm wondering if I've replicated everything properly in doing so.
Here is the original code:
var test = new Function('$f','$c','with($f){with($c){return{'+ declarations +'}}}'));
Where $f and $c are passed objects (From what I could tell, $f shouldn't ever have a property of $c). The declarations variable is a string that has a colon in it (EX: "value:color") and available within the scope.
Here is my modified code:
var test = function($f, $c, declarations) {
var result = {};
var value = "";
var split = declarations.split(":");
if (split.length < 2) {
throw new Error("Declaration is in an invalid format");
}
if ($f[$c] !== undefined && $f[$c][split[1]]) {
value = $f[$c][split[1]];
}
else if ($c[split[1]]) {
value = $c[split[1]];
}
else if ($f[split[1]]) {
value = $f[split[1]];
}
else {
value = "" + split[1];
}
var key = split[0];
result[key] = value;
return result;
};
Everything appears to work as it did previously, but this modification now handles the use case where the declarations variable could have a dash in it (EX: "value:background-color"). Additionally the declarations variable is passed into the function, to ensure it's defined.

Javascript Object scope

This is a simplification of something that I've come up against in a larger project so I hope it makes sense.
I have two Objects:
FirstObj = {
data : [],
init : function()
{
for(var a = 0; a < 20; a++)
{
this.data[a] = 1;
}
}
};
SecondObj = {
init : function()
{
var cell = FirstObj.data[0];
cell = 0;
}
};
I then call the two init methods and log the results:
(function(){
FirstObj.init();
SecondObj.init();
console.log(FirstObj.data);
})()
Now, I was assuming - based on my basis in Actionscript - that the log would show an Array in which the first item is a 0 and the rest all 1 but the 0 does not seem to stick.
Why does the assignment of the 0 value not succeed here and yet works fine if, instead of cell = 0 I target directly at FirstObj.data[0] = 0.
I'm guessing this is a scope thing and I can work round it but I'm trying to get a proper understanding of how JS actually handles this stuff, especially when lumping code into Objects like this (as an aside, is this a good approach in peoples general opinion?).
Thank for any help.
Numbers in JavaScript are something called primitive value types (alongside strings, booleans null and undefined).
This means, that when you do
var cell = FirstObj.data[0];
You're passing the value in FirstObj.data[0] and not a refernece to it.
What you're doing is like:
var x = 5;
var y = x; // y is now 5
y = 4; // y is 4, x is still 5.
Of course, something like FirstObj.data[0] = 0 should work.
Array indexing returns values in Javascript, not references. It means that once data[0] is assigned to cell, further modification of cell will not affect data[0].
Assigning the array itself would result in the behavior you're looking for:
SecondObj = {
init : function()
{
var cells = FirstObj.data;
cells[0] = 0; // Will also affect data[0].
}
};

Grid not rendering in firefox

I am working with EditableGrid to generate and manipulate column models dynamically. Everything has gone according to the plan, except for just one compatibility issue with Firefox (..yes not IE -_-). I understand this is some sort of Closure issue maybe? I cannot seem to work a way around this. This is where something goes wrong:
EditableGrid.prototype.initializeGrid = function () {
with (this) {
//apply cell validators and inforenderers in headers
var regex = [];
for (var count = 0; count < selectedColumnNames.length; ++count) {
var columnObj = findSelectedColumnObject(selectedColumnNames[count]);
//check if regex is provided
if (!(columnObj[0].validationRegex == "")) {
// add a cell validator
var expression = new RegExp(columnObj[0].validationRegex);
regex[columnObj[0].name] = new RegExp(columnObj[0].validationRegex);
var valObj = GetValidatorObject(expression);
addCellValidator(columnObj[0].name, valObj);
}
}
function GetValidatorObject(regObj){
var obj = {
isValid: function (value) {
return value == "" || (regObj.test(value));
}
};
return new CellValidator(obj);
}
}
The exception it throws is:
ReferenceError: GetValidatorObject is not defined [var valObj =
GetValidatorObject(expression);]
Any ideas?
Thanks to epascarello, the work around was simple, I moved the method of GetValidatorObject out of the scope of with (this). Now it works with FF. When I further digged into the matter, I found avoid using 'with' keyword in JS really interesting. This might clear grey areas.

Categories