Javascript indexOf behaves differently on server side compared to client side? - javascript

Our site runs javascript on .asp and the indexOf function is not behaving as I would expect. See example below (some vars changed for the same of the example. All types are the same however):
var SID = "foo";
var getCookie = "foo##%##bar##%##bloo"
var cookieArr = getCookie.split("##%##");
if(cookieArr.indexOf(SID)!=-1){
console.log("found") //found
} else {
console.log("not found") //not found
}
This works correctly in the console however when run on the server it returns "Object doesn't support this property or method" on the if statement line.
I notice that changing the check to 'cookieArr[0].indexOf(SID)!=-1' resolves to true on the serverside however this is obviously no good as I'm telling it where to look.
If this is a known behaviour, what solution should I use instead to search an array for the presence of a value?
Edit:
Going to use below dirty workaround for now but would still be interested if anyone knows why the above doesn't work
function checkArrForString(str,arr){
for(x=0;x<arr.length;x++){
if(arr[x]==str){
return x;
}
}
return -1;
}

Related

How to convert a string parameter into Object type in JavaScript?

I am making a function in the Data-Type "Object",
Code:
Object.exists = function(obj){
if(typeof(obj)==="object"){
return true;
}else{
return false;
}
}
Its purpose is to check whether an object exists or not. Everything works fine if the object entered exists, but if I try to check an object which does not exist(I am trying to develop a function and am currently checking it), it throws an error. The code to check and the error msg:
Object.exists(demo); //Note: demo is not an object
//Error:
Uncaught ReferenceError: demo is not defined
at <anonymous>:1:15
and if I try to add demo in quotes, then it does not work and shows false even if I try to add an existing object. If I try
if(typeof(obj)==="object"){
return true;
}else{
return false;
}
}
the code above without the function and the object doesn't exist, no error is thrown.
So I tried to work out my dumb brain and thought that can I use eval(), but I don't think so. Is there any other way I can convert the parameter(even if it is a string) into an object for the if statement?
I just found out the answer,
used eval() and it worked!
The code:
Object.exists = function(obj){
var type = eval("typeof("+obj+")");
console.log(type);
}
When you try an object which exists, it logs object, but if you try anything other, it logs it's type.

Checking if function uses an if statement

Is there a method or way in JavaScript that I can check if assert if a function returns a value through the use of an if statement?
So this:
function(val) {
if (val) return "it is true";
return "it is false";
}
versus this:
function(val) {
var str = 'it is ';
return str += val;
}
I've been looking around and can only find articles related to Java or other languages. Thanks in advance.
EDIT: I'm writing tests to assert whether or not a function (written by a user) utilizes an if statement. Hope that clarifies that a bit!
First I'd like to mention that such checks shouldn't be used in code, in which I mean that proper code should never check whether an if-statement is used inside a function. Whether a value is returned from it or not, this shouldn't be checked or tested.
But, to get back on topic. I'm not quite sure whether this is possible out of the box. I do however have a solution that you might be able to use to achieve something similar to your goals.
You can convert a given function to it's string representation. Take a look at the following example:
// Define a function
var myFunction = function() {
return 1 + 3;
};
// Print the function, as a string
console.log(myFunction.toString());
This code will print the string representation of the function in the console, so that will be function() { return 1 + 3; }. Some environments, such as the Firefox return a compiled version of the function which would look like function() { return 4; } but that doens't really have any effect on our use.
Using this method you'll be able to check whether the given function contains an if-statement. Such code would look like this:
// Define a function
var myFunction = function() {
return 1 + 3;
};
// Check whether the given function contains an if-statement
if(myFunction.toString().indexOf('if') > -1) {
console.log('This function does contain an if-statement');
} else {
console.log('This function does not contain an if-statement');
}
This method isn't ideal for your situation but it might point you in the right direction. Please note that this method isn't a rock-solid solution, at least not in this state. The usage of 'if' as a string (or something else) in a function would also cause the code above to say that the function contains an if-statement. Also, this doesn't explicitly check whether a value is returned from inside of an if-statement.
If you'd like to ensure the things mentioned above (that a real if-statement is used, in which a value is returned from it) you might have to modify the above code to make it smarter if this string-based method suits your needs. Then, I'd highly recommend to write a fancy wrapper around it to make it easier in use.

Unexpected Javascript for-loop behavior inside Chrome

So I am getting incredible weird java script behavior inside a chrome tab. The page is behind a login so I can't post it but can someone explain exactly what is happening???
for(var z in ""){ console.log(z) }
contains
//undefined
hmm...
var key = ""
for(var i in key){ console.log(i) }
contains
//undefined
Object.getOwnPropertyNames(key)
//["length"]
Object.getOwnPropertySymbols(key)
//[]
window[key]
//undefined
At first I thought this was one of those JS behaviors and was ready to submit it to JSWTF but the behavior runs properly in another chrome tab:
for(var i in ""){ console.log('ran',i) }
//undefined
How did a value get assigned to a blank string?
Where is it?
What is the for loop doing?
edit: The same page in firefox returns expected behavior in console. I have not tested other browsers
You have an ES6 shim on the original page which adds the function contains() to the String prototype. You can do this yourself by doing something like:
String.prototype.contains =
function(e) {
return this.indexOf(e) > -1;
};
The ES6 function ultimately standardized on is includes(), so you'll probably see that function name change in the future when a developer updates the shim.

var x; ... x.trim(); Why sometimes it allows but sometimes it makes the rest of the code stop working?

This minor issue causes me 5 hours to fix. Finally I figured out. See this code:
<script language="JavaScript" type="text/javascript">
var x;
.... // a lot of codes here
var k=x.trim();
</script>
The above code made the whole app stop working!
I remembered that I used to do like that before but got no problem.
So, about var x; ... x.trim();, Why sometimes it allows but sometimes it makes the rest of the code stop working?
And what is the best code practice for it?
You can do like this:
if(typeof x === 'undefined'){
// your get an error message
}
else
{
var k=x.toString().trim();
}
Using strict equality operator === above is good idea there because in JS, you can name a variable as undefined too:
var undefined = "something";
So using === makes sure that you are really checking against undefined value for a variable.
trim is a function of String. Refer MDN - String.trim().
So when you apply it to an integer, it fails and throws error, causing you code to stop work
Example
try{
var a = 1;
console.log(a.trim());
}
catch(ex){
console.log(ex);
}
You can try to convert number to string using .toString() and then apply .trim()
try{
var a = 1;
console.log(a.toString().trim());
}
catch(ex){
console.log(ex);
}
I would expand Rajesh's answer. He's right, when you try to call a method that does not exist, a TypeError is thrown. The easiest and fool-proof approach would be to use try/catch to ensure that the rest of the code would be executed as it should. But it's likely that even if it does, you don't get the result you want.
I believe the best way to do would be to wrap the value you're having into String object. It's as easy as
var k = String(x).trim();
It does several important things:
Converts the value of x, whatever it be, into a string, i.e. when you check its type, it's always 'string' and is always an instance of the String object.
Ensures that the resulting value has the method trim which does what it should.
Doesn't throw any error, so the rest of the code is executed.
There may be several pitfalls. If x is undefined, null, NaN or an object, the result of String(x) would be, correspondingly, 'undefined', 'null', 'NaN', or '[object Object]'. If x is an array, it's a specific case, and the value would be the same as if you call x.join(','), for example
x = [1, 2, 3];
var k = String(x).trim; // k is now '1,2,3'
So always keep in mind what types you're dealing with.
Just as with String, you can cast variables to other types, but naïvely converting anything into a Number, a String or an Array is considered a very bad practice. You should always be somewhat sure what type you're working with.

How does a browser know that an element has changed without a setter method, but just by assignment with '='?

How is it possible, that the browser can refresh the input element (or any other element), when I assign the value without a setter method, but just by normal assignment:
<script type="text/javascript">
document.getElementById("element_id").value = 'value';
</script>
Is there a native event, or is this a Javascript event? I would expect something like:
function setAttribute(value) {
model.value = ...
fireEvent();
}
But I can also set the attribute only without setter.
So where is this "event" fired (hidden somewhere in the assignment with '=') so that the browser knows that a refresh is needed?
Greetings
The JS engine is free to detect this however it wants. It could be a simple if (dest instanceof DOMElement) { special handling } or it could be an extremely complex process. It's just a simple assignment in JS land. In implementation land, it can do anything it wants as long as the end effect is correct.
In other words, it just looks like a simple assignment. Behind the scenes, it is most certainly more.
In Javascript you can have custom getters and setters for object properties:
var obj = {
get prop () { alert("Getting prop!"); return 4; }
set prop (newValue) { alert("Setting prop to " + newValue); }
}
obj.prop = obj.prop + 1;
So here, the last line triggers both alerts.
Like Corbin says, the actual JS/DOM implementation of the browser can do whatever it wants. Javascript is text that is interpreted (or compiled) into something that runs in a virtual machine. What the text means, and what effects it has when interpreted - is up to the interpreter.
It's late and silly-time, so to demonstrate, a very lousy "parser/interpreter" written in javascript... It only allows one kind of statement and has no syntax checking (or much of anything else). But who knows - it still might give a (very simplified) idea of what's going on when the browser interprets an actual script:
var myscript1 = "value = 3";
var myscript2 = "othervalue = 5";
var variables = {};
// Hey ho, let's run our two "scripts":
parser(myscript1);
parser(myscript2);
function parser(script)
{
// Super-simple lexer:
var tokens = script.split(" ");
// Rudimentary error checking:
if (tokens.length != 3 || tokens[1] != "=")
{
alert("syntax error!");
}
var variable = tokens[0];
var value = parseInt(tokens[2], 10);
// Execute our only allowed operation:
setVariable(variable, value);
}
function setVariable(name, value)
{
// Store our value (e.g. for later use in our script - if our interpreter
// actually allowed doing anything except assigning values to variables:
variables[name] = value;
// ... and do something with it:
alert(name + " was set to " + value + "!");
}
Our "language" doesn't have function calls or events, but our "interpreter" can do whatever it wants with the "scripts" given to it. As Corbin said, it looks like simple assignment, but behind the scenes (in the setVariable function), it is most certainly more (well, in this case, a bit more - triggering an alert).

Categories