I've hated JScript for over a decade. When I first got into web development, ASP was the method of choice for Windows environments. Almost all the examples of code online and in books were written in VBScript. But there were those "special few" who believed that ASP pages should be written with JScript – some strange version of JavaScript. As if it made them feel more like a real programmer, and less of scripter. But let's face it, anything "they" could do in JScript, I could do in VBScript. Aside from try catch blocks, there really wasn't much difference in the languages.
And now that it is literally of no importance, as almost no one is writing ASP pages at this time, I've run across an actual technical reason to justify my disdain for JScript.
A while back I had to make some updates to a very old web application written in ASP using JScript. The application had a function where it did a search for people in Active Directory and displayed the results along with some essential attributes about the people. The search worked fine, but they wanted a new attribute to be displayed. The organization this supported stored an additional phone number about each user in active directory, which was useful to employees and partners. This phone number was stored in the Active Directory attribute called otherTelephone – which is a multivalued attribute. In our case, each person had only one otherTelephone number defined, so I knew I could always pull the first one. This is where this is a located in AD:
I updated the existing code, only to find that the otherTelephone attribute was not being displayed. I pulled the AD search and display code into a separate page to start troubleshooting the problem, but still couldn't find any way to make it work. I've since replicated the problem in my home lab, and here's the code:
<%@ LANGUAGE="jscript" %> <% var oConn = Server.CreateObject("ADODB.Connection"); oConn.Provider = "ADsDSOObject"; oConn.Open(); var oCmd = Server.CreateObject("ADODB.Command"); oCmd.ActiveConnection = oConn; oCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree"; var oResult = oCmd.Execute(); while (oResult.EOF == false) { Response.Write("<hr />"); Response.Write(oResult.Fields("givenname") + " " + oResult.Fields("sn") + "<br />"); Response.Write(oResult.Fields("mail") + "<br />"); Response.Write(oResult.Fields("telephoneNumber") + "<br />"); var otherPhone = oResult.Fields("otherTelephone").Value; if (otherPhone != null) { Response.Write(otherPhone[0] + "<br />"); } oResult.MoveNext(); } %>
This code generates the following:
John Smith
john.smith@company.com
555-111-1112
undefined
Jane Smith
jane.smith@company.com
555-111-1111
undefined
The code isn't correctly reading the value from the otherTelephone attribute in AD. If you think that there's something wrong with the code, here's the same code that I rewrote in VBScript.
<%@ LANGUAGE="vbscript" %> <% Set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open Set objCmd = CreateObject("ADODB.Command") objCmd.ActiveConnection = objConn objCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree" Set objResult = objCmd.Execute While Not objResult.EOF Response.Write("<hr />") Response.Write(objResult.Fields("givenname") & " " & objResult.Fields("sn") & "<br />") Response.Write(objResult.Fields("mail") & "<br />") Response.Write(objResult.Fields("telephoneNumber") & "<br />") otherPhone = objResult.Fields("otherTelephone").Value If IsNull(otherPhone) = False Then Response.Write(otherPhone(0) & "<br />") End If objResult.MoveNext Wend %>
This code generates the following:
John Smith
john.smith@company.com
555-111-1112
x7777
Jane Smith
jane.smith@company.com
555-111-1111
x8888
And wouldn't you know it – it works just as it should in VBScript. Suck it JScript.
At the end of the day, rewriting the entire ASP page that I was updating to use VBScript wasn't an option. Remember, the code I've listed here is just part of the original page. The answer to the problem was to add a VBScript function to the existing JScript page. The code for that is listed below and renders the same HTML as the full VBScript code.
<%@ LANGUAGE="jscript" %> <script language="vbscript" runat="server"> Function readOtherTelephone(otherTelephone) If IsArray(otherTelephone) Then readOtherTelephone = otherTelephone(0) Else readOtherTelephone = Null End If End Function </script> <% var oConn = Server.CreateObject("ADODB.Connection"); oConn.Provider = "ADsDSOObject"; oConn.Open(); var oCmd = Server.CreateObject("ADODB.Command"); oCmd.ActiveConnection = oConn; oCmd.CommandText = "<LDAP://DC=company,DC=org>;(&(objectCategory=person)(cn=*smith));givenname,sn,mail,telephoneNumber,otherTelephone;subtree"; var oResult = oCmd.Execute(); while (oResult.EOF == false) { Response.Write("<hr />"); Response.Write(oResult.Fields("givenname") + " " + oResult.Fields("sn") + "<br />"); Response.Write(oResult.Fields("mail") + "<br />"); Response.Write(oResult.Fields("telephoneNumber") + "<br />"); var otherPhone = oResult.Fields("otherTelephone").Value; Response.Write(readOtherTelephone(otherPhone) + "<br />"); oResult.MoveNext(); } %>
JScript is inferior. End of story.