Search

11/23/2009

Primitive Datatype Wrapper Objects

from javascript the definitive guide, 3.13 Primitive Datatype Wrapper Objects

 
>>> s = 'hello'
"hello"
>>> typeof s
"string"
>>> t = new String('hello')
hello 0=h 1=e 2=l 3=l 4=o
>>> typeof t
"object"

When we discussed strings earlier in this chapter, I pointed out a strange feature of that datatype: to operate on strings, you use object notation. For example, a typical operation involving strings might look like the following:

var s = "These are the times that try people's souls.";
var last_word = s.substring(s.lastIndexOf(" ")+1, s.length);

If you didn't know better, it would appear that s was an object and that you were invoking methods and reading property values of that object.

What's going on? Are strings objects, or are they primitive datatypes? The typeof operator (see Chapter 5) assures us that strings have the datatype "string", which is distinct from the datatype "object". Why, then, are strings manipulated using object notation?

The truth is that a corresponding object class is defined for each of the three key primitive datatypes. That is, besides supporting the number, string, and boolean datatypes, JavaScript also supports Number, String, and Boolean classes. These classes are wrappers around the primitive datatypes. A wrapper contains the same primitive data value, but it also defines properties and methods that can be used to manipulate that data.

JavaScript can flexibly convert values from one type to another. When you use a string in an object context i.e., when you try to access a property or method of the string JavaScript internally creates a String wrapper object for the string value. This String object is used in place of the primitive string value. The object has properties and methods defined, so the use of the primitive value in an object context succeeds. The same is true, of course, for the other primitive types and their corresponding wrapper objects; you just don't use the other types in an object context nearly as often as you use strings in that context.

Note that the String object created when you use a string in an object context is a transient one; it allows you to access a property or method, and then it is no longer needed, so it is reclaimed by the system. Suppose s is a string and the length of the string is determined with a line like this:

var len = s.length;

In this case, s remains a string; the original string value itself is not changed. A new transient String object is created, which allows you to access the length property, and then the transient object is discarded, with no change to the original value s. If you think this scheme sounds elegant and bizarrely complex at the same time, you are right. Typically, however, JavaScript implementations perform this internal conversion very efficiently, and it is not something you should worry about.


Primitives as objects
It's possible to instantiate these wrapper objects; this is a bad idea, as it doesn't give you any benefit:

var s = new String('abc');
var n = new Number(5);
var b = new Boolean(true);

Avoid doing this.

沒有留言: