1 | /* Javascript Object Inheritance Implementation ______ ________ |
||
2 | * (c) 2016 <[email protected]> __ / / __ \/ _/ _/ |
||
3 | * Licensed under MIT. / // / /_/ // /_/ / |
||
4 | * ------------------------------------------------------ \___/\____/___/__*/ |
||
5 | |||
6 | JOII = typeof (JOII) !== 'undefined' ? JOII : {}; |
||
7 | JOII.Compat = {}; |
||
8 | |||
9 | /** |
||
10 | * Finds and returns the name of a JOII-generated object or false if it doesn't |
||
11 | * exist. |
||
12 | * |
||
13 | * @param {Object|Function} e |
||
14 | * @return {String|Boolean} |
||
15 | */ |
||
16 | JOII.Compat.findJOIIName = function(e, selfReferenced) { |
||
17 | var i, r; |
||
0 ignored issues
–
show
|
|||
18 | |||
19 | if (typeof (e) === 'string' || |
||
20 | typeof (e) === 'number' || |
||
21 | typeof (e) === 'undefined' || |
||
22 | e === null |
||
23 | ) { |
||
24 | return false; |
||
25 | } |
||
26 | |||
27 | if (typeof (e.__joii__) !== 'undefined' && e.__joii__ !== null) { |
||
28 | return e.__joii__.name; |
||
29 | } |
||
30 | if (typeof (e.prototype) !== 'undefined' && typeof (e.prototype.__joii__) !== 'undefined') { |
||
31 | return e.prototype.__joii__.name; |
||
32 | } |
||
33 | |||
34 | // prevent infinite loops. Shouldn't need to go more than one deep. |
||
35 | if (selfReferenced) { |
||
36 | return false; |
||
37 | } |
||
38 | |||
39 | // Chrome / FF // IE 11+ |
||
40 | if (typeof (e.__proto__) !== 'undefined' && e.__proto__ !== null) { |
||
41 | r = JOII.Compat.findJOIIName(e.__proto__, true); |
||
42 | if (typeof (r) === 'string') { |
||
43 | return r; |
||
44 | } |
||
45 | } |
||
46 | |||
47 | if (typeof (e) === 'function') { |
||
48 | e = e.prototype; |
||
49 | } |
||
50 | |||
51 | for (i in e) { |
||
52 | if (e.hasOwnProperty(i) === false) continue; |
||
53 | if (typeof (e[i]) === 'function' || typeof (e[i]) === 'object') { |
||
54 | r = JOII.Compat.findJOIIName(e[i], true); |
||
55 | if (typeof (r) === 'string') { |
||
56 | return r; |
||
57 | } |
||
58 | } |
||
59 | } |
||
60 | |||
61 | return false; |
||
62 | }; |
||
63 | |||
64 | /** |
||
65 | * Array.indexOf implementation. |
||
66 | * |
||
67 | * @param {Array} array |
||
68 | * @param {*} elt |
||
69 | * @return {Number} |
||
70 | */ |
||
71 | JOII.Compat.indexOf = function(array, elt) { |
||
72 | |||
73 | if (typeof (array.indexOf) === 'function') { |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
74 | return array.indexOf(elt); |
||
75 | } |
||
76 | |||
77 | var len = array.length >>> 0, |
||
78 | from = Number(arguments[1]) || 0; |
||
79 | |||
80 | from = (from < 0) ? Math.ceil(from) : Math.floor(from); |
||
81 | from = (from < 0) ? from + len : from; |
||
82 | |||
83 | for (; from < len; from++) { |
||
84 | if (from in array && array[from] === elt) { |
||
85 | return from; |
||
86 | } |
||
87 | } |
||
88 | |||
89 | return -1; |
||
90 | }; |
||
91 | |||
92 | /** |
||
93 | * Make a deep copy of an object. |
||
94 | * |
||
95 | * - original by jQuery (http://jquery.com/) |
||
96 | */ |
||
97 | JOII.Compat.extend = function() { |
||
98 | var options, src, copy, copyIsArray = false, clone, |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
99 | target = arguments[0] || {}, |
||
100 | i = 1, |
||
101 | length = arguments.length, |
||
102 | deep = false; |
||
103 | if (typeof target === "boolean") { |
||
104 | deep = target; target = arguments[i] || {}; i++; |
||
105 | } |
||
106 | if (typeof target !== "object" && typeof (target) !== "function") { |
||
107 | target = {}; |
||
108 | } |
||
109 | for (; i < length; i++) { |
||
110 | options = arguments[i]; |
||
111 | if (options !== null && arguments[i] !== undefined) { |
||
112 | |||
113 | if (typeof (options.__joii__) !== 'undefined') { |
||
114 | JOII.CreateProperty(target, '__joii__', options.__joii__); |
||
115 | } |
||
116 | |||
117 | for (var name in options) { |
||
118 | // Do NOT check 'hasOwnProperty' here. The universe will implode. |
||
119 | src = target[name]; |
||
120 | copy = options[name]; |
||
121 | if (target === copy) { continue; } |
||
122 | if (deep && copy && (JOII.Compat.isPlainObject(copy) || (copyIsArray = JOII.Compat.isArray(copy)))) { |
||
123 | if (copyIsArray) { |
||
124 | copyIsArray = false; |
||
125 | clone = src && JOII.Compat.isArray(src) ? src : []; |
||
126 | } else { |
||
127 | clone = src && JOII.Compat.isPlainObject(src) ? src : {}; |
||
128 | } |
||
129 | target[name] = JOII.Compat.extend(deep, clone, copy); |
||
130 | } else if (copy !== undefined) { |
||
131 | target[name] = copy; |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | } |
||
136 | return target; |
||
137 | }; |
||
138 | |||
139 | |||
140 | /** |
||
141 | * Recursively walks through a normal object, and flattens any JOII objects it finds, to prepare them for serialization |
||
142 | * |
||
143 | * @param {Object} current_obj |
||
144 | * @param {Object} obj_base |
||
145 | * @return {Boolean} |
||
146 | */ |
||
147 | JOII.Compat.flattenObject = function(current_obj) { |
||
148 | var obj = null; |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
149 | |||
150 | if (JOII.Compat.isArray(current_obj)) { |
||
151 | obj = []; |
||
152 | } else { |
||
153 | obj = {}; |
||
154 | } |
||
155 | |||
156 | for (var key in current_obj) { |
||
157 | if (current_obj.hasOwnProperty(key) === false) continue; |
||
158 | |||
159 | var currentValue = current_obj[key]; |
||
160 | |||
161 | if (typeof (currentValue) === 'object' && currentValue !== null && 'serialize' in currentValue && typeof (currentValue.serialize) === 'function') { |
||
162 | try { |
||
163 | obj[key] = currentValue.serialize(true); |
||
164 | |||
165 | if (typeof(obj[key]) === 'string') { |
||
166 | // wasn't our serialize method. Try to deserialize back to an object to continue. |
||
167 | obj[key] = JSON.parse(obj[key]); |
||
168 | } |
||
169 | } catch (e) { |
||
170 | // something went wrong with calling the object's serialize method. Fall back to normal crawling. |
||
171 | obj[key] = JOII.Compat.flattenObject(currentValue); |
||
172 | } |
||
173 | } else if (typeof (currentValue) === 'object' && currentValue != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
174 | obj[key] = JOII.Compat.flattenObject(currentValue); |
||
175 | } else { |
||
176 | obj[key] = currentValue; |
||
177 | } |
||
178 | } |
||
179 | |||
180 | return obj; |
||
181 | }; |
||
182 | |||
183 | /** |
||
184 | * Recursively walks through a normal object, and deserializes any JOII objects it finds, |
||
185 | * optionally restoring to a current object while maintaining object references |
||
186 | * |
||
187 | * @param {Object} current_obj |
||
188 | * @param {Object} obj_base |
||
189 | * @return {Boolean} |
||
190 | */ |
||
191 | JOII.Compat.inflateObject = function(current_obj, obj_base) { |
||
192 | var obj = obj_base || null; |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
193 | |||
194 | if (typeof (obj) !== 'object' || obj == null) { |
||
0 ignored issues
–
show
It is recommended to use
=== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
195 | if (JOII.Compat.isArray(current_obj)) { |
||
196 | obj = []; |
||
197 | } else { |
||
198 | obj = {}; |
||
199 | } |
||
200 | } |
||
201 | |||
202 | for (var key in current_obj) { |
||
203 | if (current_obj.hasOwnProperty(key) === false) continue; |
||
204 | |||
205 | var currentValue = current_obj[key]; |
||
206 | |||
207 | if (typeof (currentValue) === 'object' && currentValue !== null && '__joii_type' in currentValue && typeof (currentValue.__joii_type) === 'string') { |
||
208 | var name = currentValue.__joii_type; |
||
209 | // Check for Interface-types |
||
210 | if (typeof (JOII.InterfaceRegistry[name]) !== 'undefined') { |
||
211 | throw 'Cannot instantiate an interface.'; |
||
212 | } |
||
213 | // Check for Class-types |
||
214 | else if (typeof (JOII.ClassRegistry[name]) !== 'undefined') { |
||
215 | var oldValue = obj[key]; |
||
216 | if (typeof (oldValue) === 'object' && oldValue !== null && '__joii__' in oldValue && typeof (oldValue.__joii__) === 'object' && oldValue.__joii__ !== null && oldValue.__joii__.name === name) { |
||
217 | // try to deserialize in place if the object already exists. This avoids breaking object references. |
||
218 | oldValue.deserialize(currentValue); |
||
219 | } else { |
||
220 | obj[key] = JOII.ClassRegistry[name].deserialize(currentValue); |
||
221 | } |
||
222 | } else { |
||
223 | throw 'Class ' + name + ' not currently in scope!'; |
||
224 | } |
||
225 | } else if (typeof (currentValue) === 'object' && currentValue != null) { |
||
0 ignored issues
–
show
It is recommended to use
!== to compare with null .
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. ![]() |
|||
226 | obj[key] = JOII.Compat.inflateObject(currentValue, obj[key]); |
||
227 | } else { |
||
228 | obj[key] = currentValue; |
||
229 | } |
||
230 | } |
||
231 | |||
232 | return obj; |
||
233 | }; |
||
234 | |||
235 | |||
236 | /** |
||
237 | * Returns true if the given object is an array. |
||
238 | * |
||
239 | * @param {Object} obj |
||
240 | * @return {Boolean} |
||
241 | */ |
||
242 | JOII.Compat.isArray = function(obj) { |
||
243 | var length = obj.length, |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
244 | type = typeof (obj); |
||
245 | |||
246 | if (type === "function" || (typeof (window) !== 'undefined' && obj === window)) { |
||
247 | return false; |
||
248 | } |
||
249 | if (obj.nodeType === 1 && length) { |
||
250 | return true; |
||
251 | } |
||
252 | return Object.prototype.toString.call(obj) === '[object Array]'; |
||
253 | }; |
||
254 | |||
255 | /** |
||
256 | * Returns true if the given object is a plain object (not an array). |
||
257 | * |
||
258 | * @param {Object} obj |
||
259 | * @return {Boolean} |
||
260 | */ |
||
261 | JOII.Compat.isPlainObject = function(obj) { |
||
262 | var hasOwn = ({}).hasOwnProperty; |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
263 | if (typeof (obj) !== "object" || obj.nodeType || (typeof (window) !== 'undefined' && obj === window)) { |
||
264 | return false; |
||
265 | } |
||
266 | |||
267 | return !(obj.constructor && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")); |
||
268 | }; |
||
269 | |||
270 | /** |
||
271 | * JOII.Compat.CreateObject implementation |
||
272 | * |
||
273 | * @param {Object} o |
||
274 | * @return {Object} |
||
275 | */ |
||
276 | JOII.Compat.CreateObject = function(o) { |
||
277 | |||
278 | if (typeof (Object.create) === 'function') { |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
279 | return Object.create(o); |
||
280 | } |
||
281 | |||
282 | var c = (function() { |
||
283 | function Class() { } |
||
284 | return function(o) { |
||
285 | if (arguments.length != 1) { |
||
286 | throw new Error('JOII.Compat.CreateObject implementation only accepts one parameter.'); |
||
287 | } |
||
288 | Class.prototype = o; |
||
289 | return new Class(); |
||
290 | }; |
||
291 | })(); |
||
292 | |||
293 | return c(o); |
||
294 | }; |
||
295 | |||
296 | /** |
||
297 | * Function.bind implementation. "bind" is part of ECMA-262, 5th edition |
||
298 | * and therefore not available in all browsers. This polyfill is needed |
||
299 | * to emulate the functionality of Function.bind |
||
300 | * |
||
301 | * @param {Function} fn |
||
302 | * @param {Object} context |
||
303 | * @return {Function} |
||
304 | */ |
||
305 | JOII.Compat.Bind = function(fn, context) { |
||
306 | if (typeof fn !== "function") { |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
307 | // closest thing possible to the ECMAScript 5 internal IsCallable function |
||
308 | throw new TypeError("Function.prototype.bind - argument #1 must be a function."); |
||
309 | } |
||
310 | |||
311 | // return fn.bind(context); |
||
312 | |||
313 | return function bound() { |
||
314 | return fn.apply(context, arguments); |
||
315 | }; |
||
316 | }; |
||
317 | |||
318 | /** |
||
319 | * http://www.ietf.org/rfc/rfc4122.txt |
||
320 | * |
||
321 | * @return string |
||
322 | */ |
||
323 | JOII.Compat.GenerateUUID = function() { |
||
324 | var s = []; |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
325 | var hexDigits = "0123456789abcdef"; |
||
326 | for (var i = 0; i < 36; i++) { |
||
327 | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); |
||
328 | } |
||
329 | s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 |
||
330 | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 |
||
331 | s[8] = s[13] = s[18] = s[23] = "-"; |
||
332 | |||
333 | return s.join(""); |
||
334 | }; |
||
335 | |||
336 | /** |
||
337 | * Returns an object consisting of name, parameters and body depending on |
||
338 | * the amount of parameters given. |
||
339 | * |
||
340 | * If no name is specified (argument[0] === string), a generated UUID will |
||
341 | * take its place. |
||
342 | * |
||
343 | * @param {Object} args |
||
344 | * @return {Object} |
||
345 | */ |
||
346 | JOII.Compat.ParseArguments = function(args) { |
||
347 | var result = { name: '', parameters: {}, body: {} }; |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
348 | |||
349 | switch (args.length) { |
||
350 | // Zero-arguments. Unlikely, but valid for classes and interfaces. |
||
351 | case 0: |
||
352 | result.name = JOII.Compat.GenerateUUID(); |
||
353 | break; |
||
354 | // One argument. Name or body. |
||
355 | case 1: |
||
356 | if (typeof (args[0]) === 'string') { |
||
357 | result.name = args[0]; |
||
358 | } |
||
359 | if (typeof (args[0]) === 'object') { |
||
360 | result.name = JOII.Compat.GenerateUUID(); |
||
361 | result.body = args[0]; |
||
362 | } |
||
363 | break; |
||
364 | // Two arguments: Name & Body or Parameters & Body |
||
365 | case 2: |
||
366 | if (typeof (args[0]) === 'string') { |
||
367 | result.name = args[0]; |
||
368 | } |
||
369 | if (typeof (args[0]) === 'object') { |
||
370 | result.name = JOII.Compat.GenerateUUID(); |
||
371 | result.parameters = args[0]; |
||
372 | } |
||
373 | result.body = args[1]; |
||
374 | break; |
||
375 | // Three parameters: pass them all. |
||
376 | case 3: |
||
377 | result.name = args[0]; |
||
378 | result.parameters = args[1]; |
||
379 | result.body = args[2]; |
||
0 ignored issues
–
show
|
|||
380 | case 4: |
||
381 | result.name = args[0]; |
||
382 | result.parameters = args[1]; |
||
383 | result.body = args[2]; |
||
384 | result.is_static_generated = args[3]; |
||
385 | } |
||
386 | |||
387 | // Validate the results. |
||
388 | if (typeof (result.name) !== 'string' || |
||
389 | typeof (result.parameters) !== 'object' || |
||
390 | (typeof (result.body) !== 'object' && typeof (result.body) !== 'function')) { |
||
391 | throw 'Invalid parameter types given. Expected: ([[[string], object], <object|function>]).'; |
||
392 | } |
||
393 | |||
394 | return result; |
||
395 | }; |
||
396 | |||
397 | /** |
||
398 | * Some parameters can be passed as a string, object or array of both. This |
||
399 | * function will parse the argument and return an array of actual objects. |
||
400 | * |
||
401 | * @param {*} arg |
||
402 | * @param {Boolean} deep |
||
403 | * @return {Object} |
||
404 | */ |
||
405 | JOII.Compat.flexibleArgumentToArray = function(arg, deep) { |
||
406 | if (typeof (arg) === 'object' && !JOII.Compat.isArray(arg) && typeof (arg[0]) === 'undefined') { |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
407 | return [deep ? JOII.Compat.extend(true, {}, arg) : arg]; |
||
408 | } else if (typeof (arg) === 'function') { |
||
409 | return [deep ? JOII.Compat.extend(true, {}, arg.prototype) : arg.prototype]; |
||
410 | } else if (typeof (arg) === 'object' && JOII.Compat.isArray(arg)) { |
||
411 | var result = []; |
||
412 | for (var i in arg) { |
||
413 | result.push(JOII.Compat.flexibleArgumentToArray(arg[i], false)[0]); |
||
414 | } |
||
415 | return result; |
||
416 | } else { |
||
417 | throw 'Unable to read ' + typeof (arg) + '. Object, function or array expected.'; |
||
418 | } |
||
419 | }; |
||
420 | |||
421 | |||
422 | JOII.Compat.canTypeBeCastTo = function(val, cast_to_type) { |
||
423 | // InstanceOf validator (in case of interfaces & classes) |
||
424 | if (typeof (JOII.InterfaceRegistry[cast_to_type]) !== 'undefined' || |
||
0 ignored issues
–
show
This function should enable strict mode with
use strict .
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors. Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations. We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website. ![]() |
|||
425 | typeof (JOII.ClassRegistry[cast_to_type]) !== 'undefined') { |
||
426 | |||
427 | if (JOII.Compat.findJOIIName(val) !== cast_to_type) { |
||
428 | if (val !== null && (typeof (val.instanceOf) !== 'function' || (typeof (val) === 'object' && typeof (val.instanceOf) === 'function' && !val.instanceOf(cast_to_type)))) { |
||
429 | return false; |
||
430 | } |
||
431 | } |
||
432 | } else { |
||
433 | // Native val validator |
||
434 | if (typeof (JOII.EnumRegistry[cast_to_type]) !== 'undefined') { |
||
435 | var _e = JOII.EnumRegistry[cast_to_type]; |
||
436 | if (!_e.contains(val)) { |
||
437 | return false; // Should we really be validating that it fits inside the enum? |
||
438 | } |
||
439 | } else { |
||
440 | if (typeof (val) !== cast_to_type) { |
||
441 | return false; |
||
442 | } |
||
443 | } |
||
444 | } |
||
445 | // nothing failed, so should be compatible |
||
446 | return true; |
||
447 | }; |
Strict mode is a way to opt-in to a restricted variant of JavaScript. It eliminates some common pitfalls by being less lenient and raising more errors.
Besides, it is also used to fix certain mistakes which made it difficult for JavaScript runtimes to perform certain optimizations.
We generally recommend to only enable strict mode on the function scope and not in the global scope as that might break third-party scripts on your website.