The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

JE::Types - JavaScript types and objects

This is just documentation, not a module.

DESCRIPTION

The various JavaScript types and objects are represented by classes in JE. Each class provides whichever methods listed below apply.

If you are creating your own object classes in Perl for JavaScript to use, you can subclass JE::Object, but you don't have to, in which case you ought to implement the prop, delete, method, typeof, class, id, primitive, prototype and to_object methods; otherwise TypeErrors may occur unexpectedly.

UPGRADING VALUES

When a value is passed to the prop and method methods of objects, and to various other functions, it will be "upgraded" to a Perl object representing a JavaScript value. This is done by the upgrade method of the global object.

If the value to be upgraded is a blessed reference, it is left alone (we assume you know what you are doing). Otherwise the conversion is as follows:

  From            To
  -------------------------
  undef           undefined
  array ref       Array
  hash ref        Object
  code ref        Function
  '0'             number
  other scalar    string

WARNING: The 'upgrading' of simple scalars (strings/numbers) and regexps is still subject to change.

WHICH CLASSES ARE WHICH

Each built-in JavaScript class or primitive type is a Perl class underneath. Here is the (not yet) complete list of object classes:

  JavaScript   Perl
  -----------------
  Object          JE::Object
  Function        JE::Object::Function
  Array           JE::Object::Array
  String          JE::Object::String
  Boolean         JE::Object::Boolean
  Number          JE::Object::Number
  Date            JE::Object::Date
  RegExp          JE::Object::RegExp
  Error           JE::Object::Error
  RangeError      JE::Object::Error::RangeError
  ReferenceError  JE::Object::Error::ReferenceError
  SyntaxError     JE::Object::Error::SyntaxError
  TypeError       JE::Object::Error::TypeError
  URIError        JE::Object::Error::URIError
  

And here are the primitive types:

  string          JE::String
  number          JE::Number
  boolean         JE::Boolean
  null            JE::Null
  undefined       JE::Undefined

And I might also mention a couple of special cases:

  Global          JE
  Math            JE::Object::Math
  

METHODS

Each class provides whichever of the following methods are applicable. If an object does not support a particular method, a TypeError will be thrown when JavaScript code (indirectly) tries to call that method. (For instance, 'some_string'() will attempt to call the call method of JE::String, thus resulting in a TypeError).

prop($name)
prop($name, $new_value)

Gets or sets a property. Setting a property returns the new value. The new value will be converted to a JS value automatically if it is not one already. (See "UPGRADING VALUES".) The return value will be a Perl undef if the property does not exist. See also the prop({ ... }) usage below.

keys

Returns a list of the names of enumerable properties. This is a list of Perl strings, not JE::Strings.

delete($name)
delete($name, $even_if_its_undeletable)

Deletes the property named $name, if it is deletable. If the property did not exist or it was deletable, then true is returned. If the property exists and could not be deleted, false is returned.

If the second argument is given and is true, the property will be deleted even if it is marked is undeletable, if the object supports it.

The return value is a Perl scalar, not a JE::Boolean.

method($name, $arg1, $arg2, ...)

Invokes the specified method through the object. The arguments are automatically upgraded.

value

This returns a value that is supposed to be useful in Perl. The value method of a JE::Object, for instance, produces an array ref.

call(@args)

Runs the code associated with the object if it is a function. The arguments are automatically upgraded.

apply($obj, @args)

Runs the code associated with the object if it is a function. $obj will be passed to the function as its invocant (its 'this' value). The arguments are automatically upgraded.

construct(@args)

This is just like calling a function in JS with the new keyword (which itself calls this method). It calls the constructor, if this function has one (functions written in JS don't have this). Otherwise, an empty object will be created and passed to the function as its invocant. The return value of the function will be returned if it is an object. Otherwise it will be discarded, and the object originally passed to the function will be returned instead (possibly modified).

The rest of these are mostly for internal use:

Class->new($global_obj, @args)

The @args are in the same order that they are passed to the constructor function in JavaScript (for objects, not primitives. For primitive classes, there should be only two arguments, the global object and the value).

Some object classes also provide a hash ref syntax. See each object class's respective man page.

User-defined classes do not need to accept arguments in the same order as those that come with JE. They can do whatever they like.

prop({ ... })

The prop method can be called with a hash ref as its argument. In this case, the prototype chain is not searched, and values are not upgraded. The elements of the hash are as follows:

  name      property name
  value     new value
  dontenum  whether this property is unenumerable
  dontdel   whether this property is undeletable
  readonly  whether this property is read-only

If any of the last three is given, the attribute in question will be set. If value is given, the value of the property will be set, regardless of the attributes.

This is not supported by Arguments objects. It does not work on Array objects when the property name is length or an array index (a non-negative integer below 4,294,967,295). It does not work on strings or String objects if the property name is length.

exists($property_name)

Returns a boolean indicating whether the property exists and is not inherited from a prototype. Used by Object.prototype.hasOwnProperty. (The in operator checks to see whether the return value of prop is defined.)

To do: Make hasOwnProperty use the exists method. Right now it uses prop with hashref syntax.

To do: Implement this method.

is_readonly($property_name)

Not supported by the primitive JE classes. This returns a boolean indicating whether a given property is readonly. If it doesn't exist, then the is_readonly method of the object's prototype is called with the same arguments. If there is no prototype, false is returned. This is used internally by JE::Object's prop method.

is_enum($property_name)

Not supported (yet) by the primitive JE classes. This returns a boolean indicating whether a given property is enumerable. This is used by Object.prototype.propertyIsEnumerable.

typeof

Returns a Perl string containing the type of the object. Used by the JS typeof operator.

class

This applies to object classes only (though is going to change, so that primitives can pretend to be objects). It returns a Perl string containing the type of object. This is only used by the defoult JavaScript toString method. If you create your own object class without subclassing JE::Object, you should still provide the class method, so that this JS code will still work:

  YourClass.prototype.toString = Object.prototype.toString;
  (new YourClass).toString();
id

This returns a unique id for the object or primitive, used by the JavaScript === operator. This id is unique as a string, not as a number.

The JE primitive classes provide a unique string beginning with the data type. The JE::Object and its subclasses return the memory address of the object itself. If you subclass JE::Object, you should not have to implement this method, unless you have multiple objects that you would like JS to consider the same object.

Note that the id 'num:nan' is treated specially. It is never considered equal to itself.

primitive

Returns true or false.

prototype
prototype ( $obj )

This applies to objects only, not to primitives. This method returns the prototype of the object, or undef if there is no prototype. If $obj is specified, the prototype is set to that object first. The prop method uses this method, as does JE::Object->new.

to_primitive($preferred_type)
to_boolean
to_string
to_number
to_object

These each perform the appropriate type conversion. $preferred_type, which is optional, must be either 'string' or 'number'.

Calling to_string or to_number on a object is not exactly the same as calling to_primitive('string') or to_primitive('number'), because the argument to to_primitive is merely a suggestion.

The last four methods in this list should not be overridden by subclasses of JE::Object.

global

Returns a reference to the global object.

OVERLOADED OPERATORS

All classes overload the "" (stringification) operator. See each class's respective man page (both primitives and objects) for more info on overloaded ops.

SEE ALSO

JE and all the modules listed above under "WHICH CLASSES ARE WHICH".