I'm getting a bizarre error in Chrome... check out the screenshot below.
I define record using object literal syntax.
I try setting the "id" property and get the exception.
I've tried both :
record['id'] = 'wtf';
and also
record.id = 'wtf';
I use this type of syntax all over the place in my script.... what could be going on here ?
Is this a bug in Chrome ?
EDIT :
I've solved the problem for now, but I'm still not sure why this is happening.
I moved the definition of record to occur outside of the if block. Anyone know what could be occurring ? I thought all variable declarations were scoped to the function and therefore this shouldn't be an issue.
The problem is most likely that dl is less than or equal to zero, so the statement that initializes record doesn't get executed. From your indentation, it looks like you intended for both statements to be part of the if block, but with no braces, the record['id'] = 'wtf'; statement gets executed no matter what.
By moving the variable initialization outside the if statement, you forced it to happen in any case and moved the assignment inside the if block (which, I'm assuming is what you wanted).
Probably a better way to solve it is adding braces like this:
if (dl > 0) {
var record = {};
record.id = 'wtf';
}
Unless you really do want to initialize record in both cases.
You are correct about variable declarations being scoped to the function, but the assignment doesn't happen until you get to that point in the code. record was in scope, but it still had its default value of undefined because you hadn't assigned anything to it yet.
Works for me, no reason it shouldn't work. Are you sure it's referring to that exact line? what if you alert(record) before you set it? Have you tried to debug it yet?
Related
Why is SonarQube giving this error? How should I fix it? Their rule page does not specify the solution,
Remove this useless assignment to local variable "validateAddressRequest".
validateAddress() {
if (this.propertySitusMailingForm.valid) {
let validateAddressRequest: ValidateAddressRequest = new ValidateAddressRequest();
let propertySitusData = new PropertySitusAddress(this.propertySitusMailingForm.value);
validateAddressRequest = convertToValidateRequest(propertySitusData);
this.validationService.validateCall(validateAddressRequest);
}
}
This site says that the error occurs when:
A value is assigned to a variable or property, but either that location is never read later on, or its value is always overwritten before being read. This means that the original assignment has no effect, and could indicate a logic error or incomplete code.
On the first line of the if block, you assign to validateAddressRequest, but then on the third line of the if block, you overwrite validateAddressRequest without having read the previously assigned variable. So the first line is useless.
Declare validateAddressRequest only when calling convertToValidateRequest instead.
const validateAddressRequest = convertToValidateRequest(propertySitusData);
Note that you almost certainly don't need the type annotation - if Typescript knows that convertToValidateRequest returns a ValidateAddressRequest already, there's no need to do so again with the new variable. You can do so if you think it's unclear otherwise, or if you don't have type Intellisense, but it may just be noise.
If you were declaring the variable with let so as to enable assignment to it in the future, keep in mind that it's best to avoid reassignment whenever possible, and it's almost always possible to avoid reassignment. If you need another variable that contains a ValidateAddressRequest, give it a different variable name so that you can use const to declare both variables; that makes the code more understandable at a glance, when a reader can be sure that a particular variable reference isn't ever going to be reassigned.
I have some function defined inside a function, but set to global:
function someFn(someVar) {
var arr = makeArray(someVar);
// global function:
foo = function(bar) {
return arr.indexOf(bar)==-1;
}
}
When I debug with chrome console:
> foo
function (bar){return arr.indexOf(bar)==-1;}
can I get, without changing the source code, the content of arr?
Let's assume I can't just get and execute the commands by which arr was generated, because I don't know the last value of someVar.
The variable has to be somewhere in the memory, because when I call the function, it can be accessed, but what name does it have? I already tried:
> foo.arr
undefined
X-Y problem response; I don't know how you could access arr from the console, but I can give you a few tips to debugging via a breakpoint, even if the code is minified.
Try using Google Chrome, and in Debugger, click the {} icon below the code window. That will pretty-print the script, though the varnames will still be minified. (_a1 = new_43` etc.)
Next is the art of reading minified code; Code minifiers can't change anything that is accessed via a string; the most signature of which are object properties (anything after a .). It also helps that without whitespace, it becomes easier to find a particular sequence of symbols. You could try CTRL-Fing for terms like .indexOf, ==-1, etc. If this is an actual corporate-released library, chances are you can go beyond your little example and refer to things like myCompanyLibrary.dockInstance.locator=.
Once you find that line, you can put a breakpoint there. Good luck!
Is this considered to be a JS bug in IE?
Please check the following function
function select_deselect_all_items(status)
{
select_deselect_items_under_panel(status, $('myPanel'));
panel = $('myPanel');
var items = panel.getElementsByTagName('input');
for (var n = 0; n < items.length; n++) {
item = items[n];
if (item.id.substr(0, 10) == 'myItems_') {
item.checked = status;
select_deselect_items_under_panel(status, $('myPanel'));
}
}
}
Now, this works fine in FF and Chrome, but generate an error in IE. Error is the following:
Error: Unable to get value of the property 'substr': object is null or undefined
I have this function in several places throughout my code (haven't placed it into one js file, unfortunately) and I've already stumbled on this issue. The problem seems to be with item variable. If this is changed to something else, i.e. myWildVarName, things seem to work ok. I debugged the page in IE, and I see that item is an object with certain properties...
So, a bug or a rookie mistake?
Cheers
You do have a mistake in your code, in that you never declare the item variable and thus fall prey to the Horror of Implicit Globals.
My guess is that you have something on your page that has either the name or id "item", and so that's becoming a property of window because IE does that (and many other browsers have followed suit). As you probably know, properties of window are globals, and so when you try to assign to the item symbol in your function, you're assigning to that global property. Depending on what item is, IE may be trying to apply "don't actually assign to the object, but assign to its default property instead" logic (because it's allowed to do that if it wants to with host objects) and running into an issue.
Declare your local variable (always a good idea) and the problem should go away.
Update: Now that you've posted the actual error, the rationale above for what's happening may not be spot-on, on but the recommendation (declare the local) remains the same. :-)
IE and some other browsers have the habit of adding a reference in the global scope for each element that has an id, so the likely reason for item to already have a value in IE is that you have an element with id="item".
If you declare the item variable as a local variable in the function, it's not a problem that it exists in the global scope also:
var item;
I prefer to declare one Javascript file for my all website. I am trying to decrease the usage of global variables. My examples at the below, in both case each object has a myName field.
I would like to know when they are initialized?
And In terms of memory and efficiency which one is more effective?
For variable a, is declaring a.myName the same as global "var myName = Rebecca" ?
var a = {
myName : 'Rebecca' ,
sayHello : function() {
console.log(this.myName);
}
};
var b = {
myName : function() {
return 'Rebecca';
},
sayHello : function() {
console.log(this.myName());
}
};
Thanks
I believe these will be initialized identically (i.e. when the code is reached). What's different is what's happening when they are initialized and where the load is placed when their data is actually required.
To me, it would depend a lot on what you were expecting to have in myName. If it were just a string, I'd avoid the function and go with choice a. On the other hand, if there were a great deal of logic involved and that logic might not need to be invoked (for example, if it only gets executed when a user clicks on a button or the application reaches a certain state), I'd go with choice b. As I understand it, the function does consume memory and won't get garbage collected (which is a minus), but it also won't consume CPU resources until it's actually needed (which can be a huge plus).
I'm not sure I understand the question, but I'd say it's not the same. If the only member of a is myName then the two are equivalent (both are occupying the global namespace. But if you have multiple properties, the savings become obvious. From your examples, I think it's clear you understand this, so again I may not understand the question.
They will be initialized when the statements are first encountered. In a, 'Rebecca' is initialized as the value for the myName key. In b, it's just data internal to the myName (anonymous) function. a will be slightly more efficient because it avoids a function call. I also find it more readable in this simple example.
I find the choice to put everything in a single file questionable. In some cases, you want a modular design. And since you're worried about efficiency (albeit perhaps prematurely), note that having one big file can actually hurt performance if pages include code they don't need.
1) They are initialized when the script is processed in the browser, unless you declare the objects in an event handler. In that case the object is created when the event script is executed.
2) In terms of efficiency, a will probably be more efficient. Note though that in the first case you use a.myName and in the second b.myName() to get the value of the property.
3) No. If you assign a value to a property of an object, you always have to get that value through the object. In this case either a.myName or a['myName'].
a doesn't make any sense, because you're logging a function reference. B is the way to go, since you're actually invoking the method, using ().
I just got the following error in a piece of javascript (in Firefox 3.5, with Firebug running)
cannot access optimized closure
I know, superficially, what caused the error. I had a line
options.length()
instead of
options.length
Fixing this bug, made the message go away. But I'm curious. What does this mean? What is an optimized closure? Is optimizing an enclosure something that the javascript interpretter does automatically? What does it do?
I had this issue too when Firebug is running.
It seems to happen sometimes, when an exception is raised (for whatever reason) and when there's a recursive function call somewhere in the call stack. The exception gets re-raised as the mysterious "InternalError: cannot access optimized closure"
Changing the way I define the recursive function, seems to make this issue go away. eg changing from
function foo(bar) {... foo(recursively); ...}
to
var foo = function(bar) {... foo(recursively); ...}
Hope that helps.
It is a bug in Firefox happening with Firebug open:
https://bugzilla.mozilla.org/show_bug.cgi?id=505001
[An earlier answer mentioned this was due to this other bug, which I think is incorrect as that other problem was not related to Firebug.]
Seems like a Firefox bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=496790
A closure is a function with context. If you dynamically create a new function, then you create a closure.
function makeAdder(int num) {
return function(int num2) { return num + num2; }
}
adder = makeAdder(5);
adder(7) // returns (5+7) = 12
adder(2) // returns (5+2) = 7
Here, the closure is the inner function, as returned by makeAdder, along with the '5' that was passed.
The javascript engine might choose to optimize away the function shown above, to make things run faster, never generating or running that code, so it can't be debugged or referenced. Optimizers are supposed to be very careful to ensure there's no impact, so I'd guess this one made a mistake.
http://ludex-marketing.com/blog/2009/12/google-analytics-javascript-error-cannot-access-optimized-closure-in-ga-js/
This can also be caused by a simple race condition. I was just refactoring a 'startup' object that does a few things before the document is ready. As soon as I tried to access a second object defined immediately below the startup object I received this error.
I was under the impression that script execution waited until all of the code was compiled. Clearly that's not the case. Waiting for document ready to call methods on the second object fixed the problem. Also, using this nice 'dump()' function confirms that the second object is only partially defined when the error occurs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
I encountered the same error today. In my case this occurred because I was referencing an object's attribute or function that did not exist or was not available. I'm guessing that since the object was available via a closure that was optimized, firebug could not access metadata on that object and thus the cryptic error message.
This also happened to me today. Firebug error'd at line 2 of this function:
function IsValidDate(objName) {
re = new RegExp('^( +|today|pdate|- *\\d+ *(day(s|)|week(s|))+ *$', 'i');
if (re.test(objName.value)) return 2;
return (chkdate(objName));
}
When I added "var " before the declaration of "re" in line 1, the error went away.
There is an exception being raised somewhere else in your code within the function that has this error. It could be as simple trying to access a variable that doesn't exist.
I think we need to get a Firebug dev in here to answer why it doesn't give a more specific error as to where in the closure that raised the exception to prompt the error.
You pasted options.length(), but it is not what prompted the error. What caused the error is the fact that your bug was inside a closure.
function(){
array.length()
}
that gives the error