They are the same in the result, but they have different abilities. Is there any way to identify between them so that I can restrict the user(of a function) to use only template literal as an argument?
You mean something like an imaginary isFromTemplateLitteral boolean?
function(string){
if(string.isFromTemplateLitteral()){
// console.log("YES!")
}
}
No can do.
Because the string was passed to the function using reference in the memory stack for it. So even before the function body starts running, string is already a normal string. A primitive with type string.
There is no way to know how it has been constructed (template litteral, concatenation, simple/double quotes, etc.) or where it really comes from (user input, harcoded text, regular expression match, etc).
No, not really... just like you can't really differentiate 5 and 4 + 1.
Related
I am trying to create my own javascript simple template function
I want to create a html page that will look like this
<p>
{{HELLO_WORLD}}
<br />
{{MY_NAME_IS}}
</p>
and than with javascript to replace anything that is in {{}}
with a json var that will look like this
{HELLO_WORLD: "Hello World!", MY_NAME_IS: "My name is"}
I am a little confused about the right method to do this.
the point is to make a multilanguage web site, that way I load the json for the desired language.
thank's.
JavaScript supports regular expression-based find-and-replace, with functions for the replacement. So you can do this:
myInputString.replace( /\{\{([^\}]*)\}\}/g, function( s, v ) { return myJSON[v] } );
To explain:
replace takes 2 arguments. The first is a regular expression object. In this case we build one inline using JavaScript's /expression/flags syntax. It looks for 2 opening braces (which need to be escaped because they have special meaning in regular expressions) followed by any characters which are not a closing brace, followed by 2 closing braces. The g means "global", so that it will match all cases rather than just the first one.
When a match is found, the function will be called. The first argument (I called it s) is the full matched string (like "{{abc}}"), the second (I called it v) is set to the first bit in brackets (like "abc").
In real code, you should add error checking (variables which don't exist), and possibly convert to lowercase / whatever.
Full details on replace are here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
I have a div that contains a settings icon that is a html miscellaneous symbol
<span class="settings-icon">⚙</span>
I have a jasmine test that checks the div contents to makes sure that it is not changed.
it("the settings div should contain ⚙", function() {
var settingsIconDiv = $('.settings-icon');
expect(settingsIconDiv.text())
.toContain('⚙');
});
It will not pass as it is evaluated as its glyph symbol of a gear icon ⚙
How to I decode the glyph in order to pass the test?
To get actual character from Unicode to compare it to a literal in HTML you can use String.fromCharCode() e.g.
.toContain(String.fromCharCode(9881))
You should check against the string '⚙' or, if you do not how to enter it in your code, the escape notation \u2699. There are other, clumsier ways to construct a string containing the character, but simplicity is best.
No matter how the character is written in HTML source code (e.g., as the reference ⚙), it appears in the DOM as the character itself, U+2699. In JavaScript, a string like ⚙ is just a sequence of seven Ascii characters (though you can pass it to a function that parses it as an HTML character reference, or you can assign it e.g. to the innerHTML property, causing HTML parsing, but this is rather pointless and confusing).
To match the browser behavior (because you don't know how it is encoded in html or in text) i would try the following
.toContain($("<span>⚙</span>").text()) instead of .toContain('⚙').
That way it should match how it is stored in the dom.
The String.fromCharCode(9881); mentioned by Yuriy Galanter will definitely also work reliable. But because dom engine and the js engine are two different parts, that could behave differently, i would test with both techniques.
I have a piece of code in jsp:
String temp=new SimpleDateFormat("MMddyyyy").format((java.sql.Date)ppdates.get(authShown));
out.print(temp);
<select id="pcol<%=i%><%=weekNo%><%=au%>" onChange="pSelectedAuth(<%=i%>,<%=weekNo%>,<%=au%>,<%=currentEmployee%>,<%=temp%>)">
This prints 06042012 on the screen.
Now, my javascript functions are below:
function pSelectedAuth(formID,weekNo, index, currentEmployee,startDate){
alert(formID+":"+weekNo+":"+index+":"+currentEmployee+":"+startDate);
onchange, this alert shows 1623050
Does anyone has any idea how to get my 06042012 back?
You're not doing anything to quote your arguments (that is — you're not wrapping them in '...' or "..."), so they're being interpreted as JavaScript expressions. In JavaScript source-code, 06042012 is interpreted as a base-8 integer (because of the leading 0), so it denotes 1623050.
To fix this, be sure to wrap your JavaScript strings in '...' or "..." (as well as to properly escape any internal quotation-marks, backslashes, newlines, special characters, </, and so on). That way, you'll have '06042012' or "06042012", which JavaScript will interpret as a string, like you want.
The null character or null-terminator (\0) is to be used to terminate a contiguous sequence of characters. I find that in C, I can add the character into a string at a random position and the string will be cut off from that point. For example:
char * s = "Hello\0World";
will result in s being equal to the string "Hello". In JavaScript, however, this is not the case:
var s = "Hello\0World";
The above won't work as expected. s will be equal to the string "HelloWorld".
Why doesn't this work?
JavaScript does not use NULL terminated strings, while C does.
Javascript strings are stored by keeping track of the characters and the length separately instead of trying to assume that a NULL marks the end of the string.
The C string still points to an address in memory where "Hello\0World" is stored, only that most string handling functions considers 0 end of string. For some functions you must pass a string length argument, but most simply read until they find the null byte. In memory the string is actually "Hello\0World\0".
A JavaScript engine cannot determine string length by looking for a null byte, since you in such a case wouldn't ever be able to have a nullbyte inside a string. There's probably something about that in the specs. The engine must instead storing the length of the string separately, and then read that many characters from memory whenever you access the string.
And how to properly parse and store the size of buffers is something scripting languages usually try to hide from the user. That's half the purpose of scripting, to not require the programmer to worry about adding 0 to created character buffers and or storing string length separately so that string handling functions don't print a bunch of random characters outside your buffer looking for a nullbyte...
So exactly how does a JavaScript string behave? I don't know, it's probably up to the engine to describe its properties in depth. As long as you interface with the object like the specification says, it can be implemented in whatever manner, using structs for buffer and length, using a translation character for 0, using a linked list of characters, etc...
In Javascript a NULL byte in a String is simply a NULL byte in a string.
If you want truncate the string
var s = "Hello\0World".split("\0").shift();
but in this case I think it not need to disturb the null byte :)
The JSON spec says that JSON is an object or an array. In the case of an object,
An object structure is represented as a pair of curly brackets
surrounding zero or more name/value pairs (or members). A name is a
string. ...
And later, the spec says that a string is surrounded in quotes.
Why?
Thus,
{"Property1":"Value1","Property2":18}
and not
{Property1:"Value1",Property2:18}
Question 1: why not allow the name in the name/value pairs to be unquoted identifiers?
Question 2: Is there a semantic difference between the two representations above, when evaluated in Javascript?
I leave a quote from a presentation that Douglas Crockford (the creator of the JSON standard) gave to Yahoo.
He talks about how he discovered JSON, and amongst other things why he decided to use quoted keys:
....
That was when we discovered the
unquoted name problem. It turns out
ECMA Script 3 has a whack reserved
word policy. Reserved words must be
quoted in the key position, which is
really a nuisance. When I got around
to formulizing this into a standard, I
didn't want to have to put all of the
reserved words in the standard,
because it would look really stupid.
At the time, I was trying to convince
people: yeah, you can write
applications in JavaScript, it's
actually going to work and it's a good
language. I didn't want to say, then,
at the same time: and look at this
really stupid thing they did! So I
decided, instead, let's just quote the
keys.
That way, we don't have to tell
anybody about how whack it is.
That's why, to this day, keys are quoted in
JSON.
You can find the complete video and transcript here.
Question 1: why not allow the name in the name/value pairs to be unquoted identifiers?
The design philosophy of JSON is "Keep it simple"
"Quote names with "" is a lot simpler than "You may quote names with " or ' but you don't have to, unless they contain certain characters (or combinations of characters that would make it a keyword) and ' or " may need to be quoted depending on what delimiter you selected".
Question 2: Is there a semantic difference between the two representations above, when evaluated in Javascript?
No. In JavaScript they are identical.
Both : and whitespace are permitted in identifiers. Without the quotes, this would cause ambiguity when trying to determine what exactly constitutes the identifier.
In javascript objects can be used like a hash/hashtable with key pairs.
However if your key has characters that javascript could not tokenize as a name, it would fail when trying it access like a property on an object rather than a key.
var test = {};
test["key"] = 1;
test["#my-div"] = "<div> stuff </div>";
// test = { "key": 1, "#my-div": "<div> stuff </div>" };
console.log(test.key); // should be 1
console.log(test["key"]); // should be 1
console.log(test["#my-div"]); // should be "<div> stuff </div>";
console.log(test.#my-div); // would not work.
identifiers can sometimes have characters that can not be evaluated as a token/identifier in javascript, thus its best to put all identifiers in strings for consistency.
If json describes objects, then in practise you get the following
var foo = {};
var bar = 1;
foo["bar"] = "hello";
foo[bar] = "goodbye";
so then,
foo.bar == "hello";
foo[1] == "goodbye" // in setting it used the value of var bar
so even if your examples do produce the same result, their equivalents in "raw code" wouldn't. Maybe that's why?? dunno, just an idea.
I think the right answer to Cheeso's question is that the implementation surpassed the documentation. It no longer requires a string as the key, but rather something else, which can either be a string (ie quoted) or (probably) anything that can be used as a variable name, which I will guess means start with a letter, _, or $, and include only letters, numbers, and the $ and _.
I wanted to simplify the rest for the next person who visits this question with the same idea I did. Here's the meat:
Variable names are not interpolated in JSON when used as an object key (Thanks Friedo!)
Breton, using "identifier" instead of "key", wrote that "if an identifier happens to be a reserved word, it is interpreted as that word rather than as an identifier." This may be true, but I tried it without any trouble:
var a = {do:1,long:2,super:3,abstract:4,var:5,break:6,boolean:7};
a.break
=> 6
About using quotes, Quentin wrote "...but you don't have to, unless [the key] contains certain characters (or combinations of characters that would make it a keyword)"
I found the former part (certain characters) is true, using the # sign (in fact, I think $ and _ are the only characters that don't cause the error):
var a = {a#b:1};
=> Syntax error
var a = {"a#b":1};
a['a#b']
=> 1
but the parenthetical about keywords, as I showed above, isn't true.
What I wanted works because the text between the opening { and the colon, or between the comma and the colon for subsequent properties is used as an unquoted string to make an object key, or, as Friedo put it, a variable name there doesn't get interpolated:
var uid = getUID();
var token = getToken(); // Returns ABC123
var data = {uid:uid,token:token};
data.token
=> ABC123
It may reduce data size if quotes on name are only allowed when necessary