Monday, August 6, 2012

About getElementById

"The best and most supported practice for getting scriptable access to
an element in an HTML page is to use document.getElementById(id). "

A colleague of mine reckons such access will be much slower than
accessing the element directly.

So which is faster?

document.forms.myform.elements.field1

or

document.getElementById(field1);


Direct access will always be faster, here's how the methods work:

getElementById has to recurse through every child element (the approach of
the recursion may vary from browser-to-browser) until it finds an element
that matches the id and then it breaks out of the loop and returns the
element.

Directly accessing the elements using dot notation is less flexible
because it will only work with a specific html structure, but there's no
looping so it's a O(1) complexity algorithm (ie very fast), whereas the
getElementById algorithm gets increasingly complex as the DOM gets more
complicated.

Hope this helps.

Libraries vs Frameworks

  • Libraries slot into your existing architecture and add specific functionality
  • Frameworks give you an architecture (file structure, etc.) that you are meant to follow and, if you do, are intended to handle all common requirements

Friday, April 8, 2011

History of the browser user-agent string

In the beginning there was NCSA Mosaic, and Mosaic called itself NCSA_Mosaic/2.0 (Windows 3.1), and Mosaic displayed pictures along with text, and there was much rejoicing.

And behold, then came a new web browser known as “Mozilla”, being short for “Mosaic Killer,” but Mosaic was not amused, so the public name was changed to Netscape, and Netscape called itself Mozilla/1.0 (Win3.1), and there was more rejoicing. And Netscape supported frames, and frames became popular among the people, but Mosaic did not support frames, and so came “user agent sniffing” and to “Mozilla” webmasters sent frames, but to other browsers they sent not frames.

And Netscape said, let us make fun of Microsoft and refer to Windows as “poorly debugged device drivers,” and Microsoft was angry. And so Microsoft made their own web browser, which they called Internet Explorer, hoping for it to be a “Netscape Killer”. And Internet Explorer supported frames, and yet was not Mozilla, and so was not given frames. And Microsoft grew impatient, and did not wish to wait for webmasters to learn of IE and begin to send it frames, and so Internet Explorer declared that it was “Mozilla compatible” and began to impersonate Netscape, and called itself Mozilla/1.22 (compatible; MSIE 2.0; Windows 95), and Internet Explorer received frames, and all of Microsoft was happy, but webmasters were confused.

And Microsoft sold IE with Windows, and made it better than Netscape, and the first browser war raged upon the face of the land. And behold, Netscape was killed, and there was much rejoicing at Microsoft. But Netscape was reborn as Mozilla, and Mozilla built Gecko, and called itself Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1) Gecko/20020826, and Gecko was the rendering engine, and Gecko was good. And Mozilla became Firefox, and called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.7.5) Gecko/20041108 Firefox/1.0, and Firefox was very good. And Gecko began to multiply, and other browsers were born that used its code, and they called themselves Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.7.2) Gecko/20040825 Camino/0.8.1 the one, and Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.1.8) Gecko/20071008 SeaMonkey/1.0 another, each pretending to be Mozilla, and all of them powered by Gecko.

And Gecko was good, and IE was not, and sniffing was reborn, and Gecko was given good web code, and other browsers were not. And the followers of Linux were much sorrowed, because they had built Konqueror, whose engine was KHTML, which they thought was as good as Gecko, but it was not Gecko, and so was not given the good pages, and so Konquerer began to pretend to be “like Gecko” to get the good pages, and called itself Mozilla/5.0 (compatible; Konqueror/3.2; FreeBSD) (KHTML, like Gecko) and there was much confusion.

Then cometh Opera and said, “surely we should allow our users to decide which browser we should impersonate,” and so Opera created a menu item, and Opera called itself Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.51, or Mozilla/5.0 (Windows NT 6.0; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.51, or Opera/9.51 (Windows NT 5.1; U; en) depending on which option the user selected.

And Apple built Safari, and used KHTML, but added many features, and forked the project, and called it WebKit, but wanted pages written for KHTML, and so Safari called itself Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5, and it got worse.

And Microsoft feared Firefox greatly, and Internet Explorer returned, and called itself Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) and it rendered good code, but only if webmasters commanded it to do so.

And then Google built Chrome, and Chrome used Webkit, and it was like Safari, and wanted pages built for Safari, and so pretended to be Safari. And thus Chrome used WebKit, and pretended to be Safari, and WebKit pretended to be KHTML, and KHTML pretended to be Gecko, and all browsers pretended to be Mozilla, and Chrome called itself Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13, and the user agent string was a complete mess, and near useless, and everyone pretended to be everyone else, and confusion abounded.

Courtesy : Aaron Andersen

Monday, January 24, 2011

How JavaScript Timers Work

At a fundamental level it's important to understand how JavaScript timers work. Often times they behave unintuitively because of the single thread which they are in. Let's start by examining the three functions to which we have access that can construct and manipulate timers.

* var id = setTimeout(fn, delay); - Initiates a single timer which will call the specified function after the delay. The function returns a unique ID with which the timer can be canceled at a later time.
* var id = setInterval(fn, delay); - Similar to setTimeout but continually calls the function (with a delay every time) until it is canceled.
* clearInterval(id);, clearTimeout(id); - Accepts a timer ID (returned by either of the aforementioned functions) and stops the timer callback from occurring.

In order to understand how the timers work internally there's one important concept that needs to be explored: timer delay is not guaranteed. Since all JavaScript in a browser executes on a single thread asynchronous events (such as mouse clicks and timers) are only run when there's been an opening in the execution. This is best demonstrated with a diagram, like in the following:




There's a lot of information in this figure to digest but understanding it completely will give you a better realization of how asynchronous JavaScript execution works. This diagram is one dimensional: vertically we have the (wall clock) time, in milliseconds. The blue boxes represent portions of JavaScript being executed. For example the first block of JavaScript executes for approximately 18ms, the mouse click block for approximately 11ms, and so on.

Since JavaScript can only ever execute one piece of code at a time (due to its single-threaded nature) each of these blocks of code are "blocking" the progress of other asynchronous events. This means that when an asynchronous event occurs (like a mouse click, a timer firing, or an XMLHttpRequest completing) it gets queued up to be executed later (how this queueing actually occurs surely varies from browser-to-browser, so consider this to be a simplification).

To start with, within the first block of JavaScript, two timers are initiated: a 10ms setTimeout and a 10ms setInterval. Due to where and when the timer was started it actually fires before we actually complete the first block of code. Note, however, that it does not execute immediately (it is incapable of doing that, because of the threading). Instead that delayed function is queued in order to be executed at the next available moment.

Additionally, within this first JavaScript block we see a mouse click occur. The JavaScript callbacks associated with this asynchronous event (we never know when a user may perform an action, thus it's consider to be asynchronous) are unable to be executed immediately thus, like the initial timer, it is queued to be executed later.

After the initial block of JavaScript finishes executing the browser immediately asks the question: What is waiting to be executed? In this case both a mouse click handler and a timer callback are waiting. The browser then picks one (the mouse click callback) and executes it immediately. The timer will wait until the next possible time, in order to execute.

Note that while mouse click handler is executing the first interval callback executes. As with the timer its handler is queued for later execution. However, note that when the interval is fired again (when the timer handler is executing) this time that handler execution is dropped. If you were to queue up all interval callbacks when a large block of code is executing the result would be a bunch of intervals executing with no delay between them, upon completion. Instead browsers tend to simply wait until no more interval handlers are queued (for the interval in question) before queuing more.

We can, in fact, see that this is the case when a third interval callback fires while the interval, itself, is executing. This shows us an important fact: Intervals don't care about what is currently executing, they will queue indiscriminately, even if it means that the time between callbacks will be sacrificed.

Finally, after the second interval callback is finished executing, we can see that there's nothing left for the JavaScript engine to execute. This means that the browser now waits for a new asynchronous event to occur. We get this at the 50ms mark when the interval fires again. This time, however, there is nothing blocking its execution, so it fires immediately.

Let's take a look at an example to better illustrate the differences between setTimeout and setInterval.
setTimeout(function(){
/* Some long block of code... */
setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
/* Some long block of code... */
}, 10);

These two pieces of code may appear to be functionally equivalent, at first glance, but they are not. Notably the setTimeout code will always have at least a 10ms delay after the previous callback execution (it may end up being more, but never less) whereas the setInterval will attempt to execute a callback every 10ms regardless of when the last callback was executed.

There's a lot that we've learned here, let's recap:

* JavaScript engines only have a single thread, forcing asynchronous events to queue waiting for execution.
* setTimeout and setInterval are fundamentally different in how they execute asynchronous code.
* If a timer is blocked from immediately executing it will be delayed until the next possible point of execution (which will be longer than the desired delay).
* Intervals may execute back-to-back with no delay if they take long enough to execute (longer than the specified delay).

All of this is incredibly important knowledge to build off of. Knowing how a JavaScript engine works, especially with the large number of asynchronous events that typically occur, makes for a great foundation when building an advanced piece of application code.

Courtesy : John Resig's Blog.

Sunday, December 12, 2010

Native Apps vs Web Apps

The Issues Native Apps Web Apps
Internet access Not required Required, except for rare apps with offline capability
Installation/updates Must be deployed or downloaded Hit refresh
User interface Native apps are responsive and functional Browsers can be clunky, but new advancements in JavaScript like jQuery Mobile are catching up fast
Device compatibility Platform-dependent, hardware-dependent Platform-agnostic, content can be reformatted with CSS to suit any device
Animation/Graphics Fast and responsive Web apps are getting closer, but will probably always lag
Streaming media Few problems with audio and video. Flash works, but only if the device supports it Flash works where supported. Browser-based audio and video are getting there, but still beset by compatibility headaches. Give it a year or two
Fonts Tight control over typefaces, layout Almost on par, thanks to advancements in web standards. Give it six months
Is my content searchable? Not on the web By default
Sharable/Tweetable? Only if you build it in Web links are shared freely. Social APIs and widgets allow easy one-click posting
Discussion and collaboration Only if you build it, and it’s more difficult if data is disparate Discussion is easy, all data is stored on a server
Access to hardware sensors Yes, all of them: camera, gyroscope, microphone, compass, accelerometer, GPS Access through the browser is limited, though geolocation is common
Development Specific tools required for some platforms (like Apple’s). You have to build a new app for each target platform Write once, publish once, view it anywhere. Multiple tools and libraries to choose from
Can I sell it? Charge whatever you want. Most app distributors take a slice, up to 30% Advertising is tolerated, subscriptions and paywalls less so. No distribution costs beyond server fees
Distribution Most app stores require approval. And you gotta wait No such hassle
Outside access to your content No, the reader must download your app Yep, just click a link
Advertising Control over design (though limited in iAds) and rate More choices for design, plus access to web analytics. Rates vary widely

Thursday, December 9, 2010

Frameworks for developing mobile web apps

Smart Phones are the future of the next gen web. There’s a lot of buzz with the new mobile web frameworks and mobile platforms. There’s also a lot of confusion and vague terms being thrown around that are causing people to misunderstand what each of these tools do.I did a small research to understand some of them and to clear doubts i had.

Types of Mobile Apps :
  • Native Apps - written using Android SDK Java(for android phones) , Cocoa Objective-C (for IOS/IPhone).
  • Web Apps - written using Sencha Touch or JQuery Mobile frameworks (in normal web technologies Js/Html/css)
  • Web Apps which look like Native Apps - wrapped using Titanium or Phonegap frameworks which can access some of the mobile devices native APIs using javascript
We have many frameworks for developing native and web apps. Interestingly , we have some more frameworks for converting(wrapping) webapps to native apps.These wrapper frameworks provide some Javascript native APIs through which a "web app" has access to the mobile phone functions such as Geolocation, Accelerometer Camera, Contacts, Database, File system, etc .

Developing Native apps and Web apps in mobiles have their pros and cons. Lets discuss about each of the type below :

Native Apps

A native app is defined as the software specifically written to run on a device’s operating system and machine hardware, and typically needs to be rewritten for different devices.A native app runs on your device.All of it’s resources are installed locally on your machine.A native app uses platform and language specific API’s native to that device.A native app has access to local resources while a mobile web app cannot.

We have to write a native app in Java Android sdk for android based devices and upload them to android app market. If we need to make that app for Iphone , then we need to write the same in Objective-c(cocoa) to run it in IOS and upload it to apple appstore.The same applies for symbian, blackberry and other OS s too. Unless you are a Backend(Java/Obj-c) developer , you wont be much interested in this.

Web apps

The future of the Mobile Web is likely to be dominated by cross-platform browser-based mobile web sites - rather than apps built specifically for iPhone, Android, or any other platform.
A mobile web app is not the same as a mobile native app. A mobile web app runs in your browser.Think of a mobile web app as a website like facebook.com or Twitter.com. Almost all of the app’s resources are remote, stored on some server somewhere. Sure there might be some local storage happening but at the end of the day it’s a website application. Check out for more differences here.

A Web app is typically coded in a browser-rendered language such as HTML,CSS combined with JavaScript. Direct control over the application’s distribution and cost advantages are usually the main reasons for launching a Web application. For webdevelopers,its very easy to build them and requires no app store approval.
Frameworks like Sencha Touch and JQuery Mobile can give native look for the webapps.The difference between the capabilities of Web-based and native mobile apps is narrowing rapidly with the invent of these frameworks.

Sencha Touch and jQuery Mobile

These are mobile web frameworks. You can use these technologies to create web-based mobile apps. Both of these projects run in javascript.

Sencha Touch, the first HTML5 mobile JavaScript framework that allows you to develop mobile web apps that look and feel native on iPhone and Android touchscreen devices. Sencha Touch is a cross-platform library aimed at next generation, touch-enabled, devices. With Sencha Touch you write an object-oriented javascript application that generates HTML markup.Higher learning curve than most other web frameworks but best one for writing high level web applications.

JQuery Mobile (1.0 Alpha 2) is built on the famous JQuery requires JQuery 1.4.4. JQuery Mobile uses the very best HTML 5 and CSS 3 features to provide the best possible experience in the most-capable browsers.JQuery Mobile aims to be more mature and as much cross browser as possible.The following quote describes best of it.

“A unified user interface system across all popular mobile device platforms, built on the rock-solid jQuery and jQuery UI foundation. Its lightweight code is built with progressive enhancement, and has a flexible, easily themeable design.”

JQuery Mobile (like jQuery )adds interactivity and styling to ‘classic’ declarative HTML, probably generated on the mobile site’s server side.

Sencha Touch (like ExtJS) is more of a programmatic approach, where a mobile app is written almost entirely in Javascript, and creates the majority of the HTML itself on the client when executed.

Sencha Touch seems very sophisticated and use it if we had to build a complex feature rich web app. But Jquery mobile supports more devices & platforms and has less learning curve.In future it might include many rich features.So i support JQuery.

PhoneGap and Titanium


Titanium is a cross platform technology that goes beyond the mobile and currently supports iPhone, Android devices, desktop applications, Windows and Mac, with plans to support the BlackBerry in the near future.The idea behind the Titanium platform is that you write your applications with web technologies like javascript APIs and html, and when you want to test your application, Titanium will compile your code in a native application. Which mean that you can in fact write one application for the iPhone and Android in titanium and the framework will compile it for those platform separately.

Titanium doesn’t compile HTML and JavaScript into native applications (as some people might think) but instead acts as a JS API that links to pre-compiled native objects. What’s the difference? Well a Titanium app will not have the performance of a fully native app nor does it give you full access to the all native API elements.

PhoneGap serves as a wrapper for the browser. PhoneGap opens a webkit view in a native application. So your html and css is shown exactly how it will look in the real application. Titanium can do the exact same thing via “webViews” but Titanium takes it a step further by offering a slew of native APIs for Cocoa/Android Touch outside the browser.

PhoneGap and Titanium are not similar to Sencha Touch and jQuery Mobile.Both allow you to distribute native or native-like apps. A lot of people think that Titanium and PhoneGap are in competition with Sencha Touch and jQuery Mobile. But its wrong , they are used as wrappers.
Both don’t need to “build support” for Sencha Touch or jQuery Mobile. Why? Because the devices they support come with browsers. Remember, Sencha Touch and jQuery Mobile run in the browser. Since both PhoneGap and Titanium allow you to run things in a given device’s browser, they already have support for Sencha Touch and jQuery Mobile.

You can use Sencha Touch and jQuery Mobile inside both PhoneGap and Titanium. If you decide your html/js to be cool as a native app, you can use either PhoneGap or Titanium to wrap a browser around your app and put it in the app store or marketplace. This is where the confusion comes. Putting your Sencha Touch or jQuery Mobile apps in a native wrapper doesn’t make it a native app. It makes it appear as if it is a native app. You might get some extra functionality from PhoneGap or Titanium API’s, but it’s still not necessarily a ‘native’ app. It’s a web app running locally on the device. It’s a great way to use web technologies inside a native-like area.


Friday, November 12, 2010

Duplicate IDs in HTML

IDs should be unique according to the standards and whilst most browsers don't show errors when handed duplicate IDs it would not be a good idea to rely on that always being the case.

Making the ID unique by adding a type name to the ID would work but you need to ask why you need it. Giving an element an id is very useful when the element needs to be found, getElementById is very fast. The reason its fast it that most browsers will build an index of IDs as its loads the DOM. However if you have zillions of IDs that you never actually need to use in something like getElementById then you've incurred a cost that is never paid back.

So Conclusion is even browsers allow us to use duplicate IDs ,its not a good practice to use. And getElementById() should also give appropriate result , so better to avoid it.

Thursday, May 20, 2010

The Mysterious JavaScript 'This' Keyword.

The this keyword

One of the most powerful JavaScript keywords is this. Unfortunately it is hard to use if you don't exactly know how it works.

Below I explain how to use it in event handling.
Later on I'll add some information about other uses of this.

Owner

The question that we'll discuss for the remainder of the page
is: What does this refer to in the function doSomething()?

function doSomething() {
this.style.color = '#cc0000';
}

In JavaScript this always refers to the “owner” of the function
we're executing, or rather, to the object that a function is a method of.
When we define our faithful function doSomething() in a page, its owner
is the page, or rather, the window object (or global object) of JavaScript. An onclick
property, though, is owned by the HTML element it belongs to.

This "ownership" is the result of JavaScript's object oriented approach.
See the Objects as associative arrays page for some more information.


------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          --------------------                          |
|          | onclick property |                          |
|          --------------------                          |
|                                                        |
----------------------------------------------------------

If we execute doSomething() without any more preparation the this
keyword refers to the window and the function tries to change the style.color of the window. Since the
window doesn't have a style object the function fails miserably and produces JavaScript errors.

Copying

So if we want to use this to its full extent we have to take care that the function that uses it
is "owned" by the correct HTML element. In other words, we have to
copy the function to our onclick property.
Traditional event registration takes care of it.

element.onclick = doSomething;

The function is copied in its entirety to the onclick property (which now becomes
a method). So if the event handler is executed this refers to the HTML element and its
color is changed.

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

The trick is of course that we can copy the function to several event handlers. Each time this
will refer to the correct HTML element:

------------ window --------------------------------------
|                                                        |
|                                                        |
|                                                        |
|   ----------------                                     |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------          |            |
|                                           |            |
|   -----------------------                 |            |
|   | another HTML element| <-- this        |            |
|   -----------------------     |           |            |
|               |               |           |            |
|          -----------------------          |            |
|          |copy of doSomething()|  <-- copy function    |
|          -----------------------                       |
|                                                        |
----------------------------------------------------------

Thus you use this to the fullest extent. Each time the function is called,
this refers to the HTML element that is currently handling the event, the HTML
element that "owns" the copy of doSomething().

Referring

However, if you use
inline event registration

<element onclick="doSomething()">

you do not copy the function! Instead, you refer to it, and the difference is crucial.
The onclick property does not contain the actual function, but
merely a function call:

doSomething();

So it says “Go to doSomething() and execute it.” When
we arrive at doSomething() the this keyword once again refers to the global
window object and the function returns error messages.

------------ window --------------------------------------
|                                          / \           |
|                                           |            |
|                                          this          |
|   ----------------                        |            |
|   | HTML element | <-- this         -----------------  |
|   ----------------      |           | doSomething() |  |
|               |         |           -----------------  |
|          -----------------------         / \           |
|          | go to doSomething() |          |            |
|          | and execute it      | ---- reference to     |
|          -----------------------       function        |
|                                                        |
----------------------------------------------------------

The difference

If you want to use this for accessing the HTML element that is handling the event,
you must make sure that the this keyword is actually written into the onclick property.
Only in that case does it refer to the HTML element the event handler is registered
to. So if you do

element.onclick = doSomething;
alert(element.onclick)

you get

function doSomething()
{
this.style.color = '#cc0000';
}

As you can see, the this keyword is present in the onclick method.
Therefore it refers to the HTML element.

But if you do

<element onclick="doSomething()">
alert(element.onclick)

you get

function onclick()
{
doSomething()
}

This is merely a reference to function doSomething(). The this
keyword is not present in the onclick method so it doesn't refer to the HTML element.

Examples - copying

this is written into the onclick method in the following cases:

element.onclick = doSomething
element.addEventListener('click',doSomething,false)
element.onclick = function () {this.style.color = '#cc0000';}
<element onclick="this.style.color = '#cc0000';">

Examples - referring

In the following cases this refers to the window:

element.onclick = function () {doSomething()}
element.attachEvent('onclick',doSomething)
<element onclick="doSomething()">

Note the presence of attachEvent(). The main drawback of the
Microsoft event registration model
is that attachEvent() creates a reference to the function and
does not copy it. Therefore it is sometimes impossible to know which HTML currently handles the event.

Combination

When using inline event registration you can also send this to the function
so that you can still use it:

<element onclick="doSomething(this)">
function doSomething(obj) {
// this is present in the event handler and is sent to the function
// obj now refers to the HTML element, so we can do
obj.style.color = '#cc0000';
}

JavaScript Apply() and Call() Methods

JavaScript 1.3 includes two new methods for the Function object, call() and apply(). The apply() method is a variation on the call() method. The apply() method lets you pass the parameters from one method to the other in a different way than the call() method does it. The call() method requires the full list of parameters.

The apply method allows you to call a function and specify what the keyword this will refer to within the context of that function. The thisArg argument should be an object. Within the context of the function being called, this will refer to thisArg. The second argument to the apply method is an array. The elements of this array will be passed as the arguments to the function being called. The argArray parameter can be either an array literal or the deprecated arguments property of a function.

The apply method can be used to simulate object inheritance as in the following example. We first define the constructor for an object called Car which has three properties. Then the constructor for a second object called RentalCar is defined. RentalCar will inherit the properties of Car and add one additional property of its own - carNo. The RentalCar constructor uses the apply method to call the Car constructor, passing itself as thisArg. Therefore, inside the Car function, the keyword this actually refers to the RentalCar object being constructed, and not a new Car object. By this means,the RentalCar object inherits the properties from the Car object.

Code:
function Car(make, model, year)
{
this.make = make;
this.model = model;
this.year = year;
}

function RentalCar(carNo, make, model, year)
{
this.carNo = carNo;
Car.apply(this, new Array(make, model, year))
}

myCar = new RentalCar(2134,"Ford","Mustang",1998)
document.write("Your car is a " + myCar.year + " " +
myCar.make + " " + myCar.model + ".")

Output:
Your car is a 1998 Ford Mustang.

NOTE: The apply method is very similar to the call method and only differs in that, up until now, you could use the deprecated arguments array as one of its parameters.