📜 ⬆️ ⬇️

ECMAscript 5: Strict Mode, JSON, and so on

I have previously analyzed the functionality of objects and properties of ECMAScript 5 . This is a huge new aspect of the language and it deserves special consideration.

There are a number of other new features and APIs that also need attention. The most significant of which are strict mode and native support for JSON .

Strict regime


Strict mode is a new feature in ECMAScript 5 that allows a program or function to be executed in a “strict” operational context. Strict context prevents certain actions from being performed and throws more exceptions (also providing the user with more information, and supporting the coding paradigm pyramid down).
')
While ECMAScript 5 is backward compatible with ECMAScript 3, all the “features” of ECMAScript 3 that are “not recommended” are now used are simply disabled (or throw exceptions) in strict mode.

Strict mode helps in several aspects at once:
Most of the strict mode information can be found in the ES5 specification [PDF] on page # 223.

It should be noted that strict ECMAScript 5 mode is different from the strict mode available in Firefox (which can be enabled via about: config, javascript.options.strict parameter). The strict mode of ES5 blocks a completely different set of potential errors (while the existing strict mode of Firefox tries to monitor the observance of some recommendations for writing good code, but no more).

How do you enable strict mode?

Simply. Insert this statement above the program to enable it for the whole script:
"use strict" ;

* This source code was highlighted with Source Code Highlighter .


Or, place this statement within a function to enable strict mode only within its context.
function imStrict(){
"use strict" ;
// ... your code ...
}

* This source code was highlighted with Source Code Highlighter .


Notice the syntax used to enable strict mode (I like it!). This is just a single statement string that contains the value of “use strict”. No new syntax for defining strict mode is introduced. This is a huge plus. This means that you can enable strict mode in your scenario - today - and it will, at worst, without side effects in older browsers.

As you can see from the examples here and in the previous article , there are almost no new syntax additions or language changes in the ECMAScript 5 specification. This means that you can write your ES5 scripts in such a way that they can degrade correctly for obsolete clients - which was not possible with ECMAScript 4. The way strict mode is supported is a vivid illustration of this point in practice.

And the elegant aspect of defining strict mode within a function is that you can now define your JavaScript library completely in strict mode without affecting the code outside.
// Non-strict code...

( function (){
"use strict" ;

// Define your library strictly...
})();

// Non-strict code...


* This source code was highlighted with Source Code Highlighter .

Many libraries already use the aforementioned methodology (wrapping the entire library with an anonymous function, which is then performed), and they are very easy
will be able to take advantage of strict regime.

So what will change when you put the script in strict mode? A lot of things.

Variables and properties

Attempt to assign foo = "bar"; where the variable 'foo' has not been defined, it will fail. Previously, this code would assign a value to the foo property of a global object (for example, window.foo), now it will only throw an exception. This will definitely eliminate some annoying errors.

Any attempt to change a property whose “writable” attribute is set to false, deleting a property whose “configurable” attribute is set to false, or adding a property to an object whose “extensible” attribute is set to false will end in error (these attributes were discussed earlier ). In normal mode, no error will be thrown when any of these actions are taken, they will only silently fail.

Deleting a variable, function, or parameter will result in an error.

var foo = "test" ;
function test(){}

delete foo; // Error
delete test; // Error

function test2(arg) {
delete arg; // Error
}

* This source code was highlighted with Source Code Highlighter .

Defining a property more than once, in one object literal, will throw an exception.
// Error
{ foo: true , foo: false }

* This source code was highlighted with Source Code Highlighter .


eval

Virtually any attempt to use the name 'eval' is prohibited - and this is an opportunity to assign the function eval to a variable or an object property.
// All generate errors...
obj.eval = ...
obj.foo = eval;
var eval = ...;
for ( var eval in ... ) {}
function eval(){}
function test(eval){}
function (eval){}
new Function( "eval" )

* This source code was highlighted with Source Code Highlighter .


In addition, attempts to introduce new variables through eval will be blocked.
eval( "var a = false;" );
print( typeof a ); // undefined


* This source code was highlighted with Source Code Highlighter .


Functions

Attempting to rewrite the argument object will result in an error:
arguments = [...]; // not allowed

* This source code was highlighted with Source Code Highlighter .

Defining multiple arguments with the same name will result in an error.
function (Foo, Foo) {} // error

* This source code was highlighted with Source Code Highlighter .


Access to arguments.caller and arguments.callee will now throw an exception. Thus, any anonymous functions that you want to link to will need to be named, for example, like this:
setTimeout( function later(){
// do stuff...
setTimeout( later, 1000 );
}, 1000 );


* This source code was highlighted with Source Code Highlighter .

The arguments and caller properties of other functions no longer exist - and the ability to define them is prohibited.
function test(){
function inner(){
// Don't exist, either
test.arguments = ...; // Error
inner.caller = ...; // Error
}
}

* This source code was highlighted with Source Code Highlighter .

Finally, a long-standing (and very annoying) error has been fixed: Cases where null or undefined are forced to become a global object. Strict mode now prevents this from happening, and throws an exception instead.
( function (){ ... }).call( null ); // Exception

* This source code was highlighted with Source Code Highlighter .


with () {}

In strict mode, the with statements are in the Bose - in fact, they even look like syntax errors. Although this operator was certainly misunderstood and possibly used incorrectly, I am not sure that this is enough to be affected by such a record.

Changes made in strict mode ECMAScript 5 are undoubtedly diverse (from imposing stylistic preferences, for example, deleting with statements, to correcting bad language errors, such as the ability to redefine properties in object literals). It will be interesting to see how people will begin to adapt to these innovations and how these innovations will change the development of JavaScript.

I would like to note that I’m pretty sure that jQuery is already compatible with ES5 strict mode. As soon as the implementation of this language becomes available (so that this statement can be verified), I will gladly switch jQuery to work exclusively in strict mode.


Json


The second important feature of the language is the addition of native JSON support to the language itself.

I insisted on this step for a long time , and I am very happy to see it finally in the specification.

In the near future, PLEASE begin the migration of your JSON applications to json2.js from Crockford. It is fully compatible with the ECMAScript 5 specification and gracefully switches to the native (faster!) Implementation, if it exists.

Actually, I committed a jQuery change yesterday to use the JSON.parse method, if it exists, especially since this method is now finally specified.

There are two main methods for processing JSON: JSON.parse (which converts a JSON string to a JavaScript object) and JSON.stringify (which converts a JavaScript object to a serialized string).

JSON.parse (text)

Converts a serialized JSON string to a JavaScript object.
var obj = JSON.parse( '{"name":"John"}' );
// Prints 'John'
print( obj.name );


* This source code was highlighted with Source Code Highlighter .


JSON.parse (text, translate)

Uses the translation function to convert values ​​or delete them completely.
function translate(key, value) {
if ( key === "name" ) {
return value + " Resig" ;
}
}

var obj = JSON.parse( '{"name":"John","last":"Resig"}' , translate);
// Prints 'John Resig'
print( obj.name );

// Undefined
print( obj.last );

* This source code was highlighted with Source Code Highlighter .


JSON.stringify (obj)

Converts a JavaScript object to a serialized string.
var str = JSON.stringify({ name: "John" });
// Prints {"name":"John"}
print( str );


* This source code was highlighted with Source Code Highlighter .


JSON.stringify (obj, ["white", "list"])

Serializes only the specified "white list" of properties.
var list = [ "name" ];
var str = JSON.stringify({name: "John" , last: "Resig" }, list);
// Prints {"name":"John"}
print( str );


* This source code was highlighted with Source Code Highlighter .


JSON.stringify (obj, translate)

Serializes the object using the broadcast function.
function translate(key, value) {
if ( key === "name" ) {
return value + " Resig" ;
}
}

var str = JSON.stringify({ "name" : "John" , "last" : "Resig" }, translate);
// Prints {"name":"John Resig"}
print( str );

* This source code was highlighted with Source Code Highlighter .


JSON.stringify (obj, null, 2)

Adds the specified number of spaces in the output, evenly.
var str = JSON.stringify({ name: "John" }, null , 2);
// Prints:
// {
// "name": "John"
// }
print( str );


* This source code was highlighted with Source Code Highlighter .


JSON.stringify (obj, null, "\ t")

Uses the specified string to perform a tab.
var str = JSON.stringify({ name: "John" }, null , "\t" );
// Prints:
// {\n\t"name": "John"\n}
print( str );


* This source code was highlighted with Source Code Highlighter .


Also, several new universal methods have been added to some of the basic objects, but, frankly, they are not so interesting. The results for String, Boolean, and Number are equivalent to the query .valueOf (), and the result for Date is equivalent to calling .toISOString ().
// Yawn...
String.prototype.toJSON
Boolean.prototype.toJSON
Number.prototype.toJSON
Date.prototype.toJSON

* This source code was highlighted with Source Code Highlighter .


.bind ()


A welcome addition to the language is the built-in .bind () method for implementing the context of the function (in fact, identical to the implementation of .bind in the Prototype.js library).

Function.prototype.bind (thisArg, arg1, arg2 ....)

Sets the 'this' value of the specified function to the specified object — and passes any specified parameters to the function.
var obj = {
method: function (name){
this .name = name;
}
};

setTimeout( obj.method.bind(obj, "John" ), 100 );

* This source code was highlighted with Source Code Highlighter .

Considering how long this function (and its equivalents) exists in different libraries, this is a welcome addition to the language.

Date


Dates are now capable of both parsing and outputting themselves in ISO format. Thank.

The Date Constructor now tries to analyze the date first, as if it were formatted according to the ISO standard, and only then goes to other formats that it understands.

Additionally, date objects now have a new .toISOString () method that displays the date in ISO format.
var date = new Date( "2009-05-21T16:06:05.000TZ" );

// Prints 2009-05-21T16:06:05.000TZ
print( date.toISOString() );

* This source code was highlighted with Source Code Highlighter .


.trim ()


The native, built-in .trim () method is now enabled for strings. Works identically to all other trim methods - but with the potential to possibly work faster.

Stephen Levitan discussed the trim method in more detail.

Array


Extensions for JavaScript arrays seem finally formally defined. They include the following methods: indexOf, lastIndexOf, every, some, forEach, map, filter, reduce, and reduceRight.

Additionally, a new Array.isArray method has been added, providing functionality very similar to the following:
Array.isArray = function ( array ) {
return Object.prototype.toString.call( array ) === "[object Array]" ;
};


* This source code was highlighted with Source Code Highlighter .


Overall, I think ECMAScript 5 makes an interesting proposal. This is not a huge leap that ECMAScript 4 has promised, but it is a series of great improvements that reduces the number of obvious mistakes, making the language safer and faster. I look forward to when some implementations become publicly available.

Source: https://habr.com/ru/post/60282/


All Articles