post-css-position

What is a JavaScript Object – an In-Depth and Awesome Introduction in 2019

Many newbies may ask the same question: What is a JavaScript object exactly? Take your time. We are going to talk about this topic in this article.

I should mention the previous articles in the JavaScript Definitive Guide:

The following contents are given:

What is a JavaScript Object?

In the world of JavaScript, everything is an object.

But some objects are not the same as other objects. To distinguish the type of an object, we use the typeof operator to get the type of the object, which always returns a string:

typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'

It can be seen that , numberstringbooleanfunction and undefined are different from other types. Specially, the type of null is object. The type of Array is also object. typeof will not be able to distinguish between nullArray and the object – {}.

Wrapper Object

In addition to these types, JavaScript also provides a wrapper object. People who familiar with Java may have noticed this concept, e.g., int and Integer.

We have wrapper object for numberboolean and string. That’s right, in JavaScript, strings also distinguish between the string type and its wrapper type. The wrapper object is created by the new keyword:

var n = new Number(123); // 123, a new wrapper type is generated
var b = new Boolean(true); // true, a new wrapper type is generated
var s = new String('str'); // 'str', generated a new wrapper type

Although the wrapped object looks exactly the same as the original value, but its type has changed to object! Therefore, the === comparison between the wrapped object and the original value will return false:

typeof new Number(123); // 'object'
new Number(123) === 123; // false

typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false

typeof new String('str'); // 'object'
new String('str') === 'str'; // false

Therefore , do not use the wrapped object! Especially for the string type! ! !

What happens if we don’t write the new keyword when using NumberBoolean and String?

At this point, Number()Boolean and String()is treated as a normal function, converting any type of data to numberboolean and string (note that not its wrapper type):

var n = Number('123'); // 123, equivalent to parseInt() or parseFloat()
typeof n; // 'number'

var b = Boolean('true'); // true
typeof b; // 'boolean'

var b2 = Boolean('false'); // true! 'false' string conversion result is true! Because it is a non-empty string!
var b3 = Boolean(''); // false

var s = String(123.45); // '123.45'
typeof s; // 'string'

Do you feel confusing? This is JavaScript!

To sum up, there are several rules to follow:

  • Do not use new Number()new Boolean()new String() to create wrapper objects;
  • Use parseInt() or parseFloat() to convert any type to number;
  • Use String() to convert to any type to string, or directly call an object’s toString() method;
  • It is usually not necessary to convert any type to boolean before judging. Because a variable can be used directly in conditional statements if (myVar) {...};
  • The typeof operator can determine the type of numberbooleanstringfunction and undefined;
  • Use Array.isArray(arr) to judef an Array;
  • Please use the if statement to judge type of null: if (myVar === null) {...};
  • Determine whether a global variable exists or not: typeof window.myVar === 'undefined';
  • Determines whether a variable in a function exists or not: typeof myVar === 'undefined'.

Finally, careful readers may point out that does any object has a toString()method? No, null and undefined do not support this method! This is true, except for the two special cases, although the null type also disguise itseflt as object.

Someone may encounter SyntaxError when calling the toString() method on the number:

123.toString(); // SyntaxError

In this case, special treatment is required:

123..toString(); // '123', Two dots!
(123).toString(); // '123'

Don’t ask why, this is the fun of JavaScript code!

Date

In JavaScript, the Date object represents date and time.

To get the current time of the system, use:

var now = new Date();
now; // Mon Aug 19 2019 14:12:43 GMT+0800
now.getFullYear(); // 2019, year
now.getMonth(); // 7, month, note that the month range is 0~11, 7 means August
now.getDate(); // 19, means number 19
now.getDay(); // 1, for Monday
now.getHours(); // 14, 24-hour clock
now.getMinutes(); // 12, minutes
now.getSeconds(); // 43, seconds
now.getMilliseconds(); // 781, milliseconds
now.getTime(); // 1566195163781, timestamp in number

Note that the current time is the time that the browser gets from the native operating system, so it is not necessarily accurate. Because the user can set the current time of his/her operating system to any value.

If you want to create a Date object with a specified date and time , you can use:

var d = new Date(2015, 5, 19, 20, 15, 30, 123);
d; // Fri Jun 19 2015 20:15:30 GMT+0800 (CST)

You may have observed a very, very puzzled behaviour, where the month range of JavaScript is represented by an integer from 0 to 11. 0 means January, 1 means February, and so on. So to indicate June, we are passing in 5

IMPORTANT: The month value of a Date object starts from 0.

The second way to create a specified date and time is to parse a string that conforms to the ISO 8601 format:

var d = Date.parse('2015-06-24T19:49:22.875+08:00');
d; // 1435146562875

But it returns a timestamp instead of a Date object. Fortunately, a timestamp can be easily converted to a Date object:

var d = new Date(1435146562875);
d; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
d.getMonth(); // 5

The string passed to Date.parse() uses the actual month 01~12, and the month value obtained by getMonth() after conversion to the Date object is 0~11.

Time Zone

The Date time represented by the object is always displayed in the time zone of the browser, but we can display both the local time and the adjusted UTC time:

Var d = new Date(1435146562875);
d.toLocaleString(); // '2015/6/24 7:49:22 pm, local time (Beijing time zone +8:00), the displayed string is related to the format set by the operating system
d.toUTCString(); // 'Wed, 24 Jun 2015 11:49:22 GMT', UTC time, 8 hours difference from local time

So how to perform time zone conversion in JavaScript? In fact, as long as we pass a timestamp (type of number), we don’t have to worry about time zone conversion. Any browser can correctly convert a timestamp to local time.

What is the timestamp?

The timestamp is an auto-incrementing integer that represents the number of milliseconds from the moment at 0:00 on January 1, 1970 of the GMT time zone. Assuming that the time of the computer where the browser is located is accurate, then the timestamp numbers generated by the computer at any time in the world are the same. So the timestamp can accurately represent a time and has nothing to do with the time zone.

So, we only need to pass the timestamp, or read the timestamp from the database, and then let JavaScript automatically convert it to local time.

To get the current timestamp, you can use:

'use strict';
console.log(new Date().getTime());

RegExp

String is the most common type of data structure involved in programming. And the need to manipulate strings is almost ubiquitous. For example, how to determine whether a string is a legitimate email address or not? It is possible to programmatically extract substrings before and after the @ symbol, and then determine whether the substrings are words or domain names. But this mechanism is not only troublesome, but also difficult to reuse.

Regular expression is a powerful weapon for matching strings. Its design idea is to define a rule for a string in a descriptive language. Any string that conforms to the rule is considered to be “matched”. Otherwise, the string is illegal.

So the way we determine if a string is a valid email is:

  1. Create a regular expression that matches Email;
  2. Use this regular expression to match the user’s input to determine whether it is legal.

Because regular expressions are also represented by strings, we first need to understand how characters are used to describe characters.

In a regular expression, if you give a character directly, it is an exact match. Use \d to match a number character 0~9\w can match a letter character or a number character. So that:

  • '00\d' can match '007' but cannot match '00A';
  • '\d\d\d' can match '010';
  • '\w\w' can match 'js';

The . symbol can match any character, so:

  • 'js.' can match 'jsp''jss''js!' and so on.

In a regular expression, to match a variable-length character, use * to match any number of characters (including 0); use + to match at least one character; use ? to match 0 or 1 character; use {n} to match n characters; and use {n,m} to match n-m characters.

Look at a complex example: \d{3}\s+\d{3,8}.

Let’s interpret it from left to right:

  1. \d{3} means matching 3 digits, for example '010';
  2. \s can match a space (also includes Tab), so \s+ means at least one space, such as matching ' ''\t\t' etc.;
  3. \d{3,8} represents 3-8 digits, for example '1234567'.

Taken together, the above regular expression can match the phone number with the area code separated by any space.

If you want to match '010-12345'? Since '-' is a special character, in the regular expression, '\' escaping is used, so the above expression becomes \d{3}\-\d{3,8}.

However, it still doesn’t match '010 - 12345', because there are spaces. So we need more complicated matching methods.

Advanced RegExp

To make a more precise match, you can use the [] symbol to represent a range of characters, such as:

  • [0-9a-zA-Z\_] can match a digit, letter or underscore;
  • [0-9a-zA-Z\_]+ matches strings that have at least one digit, letter or underscore, such as 'a100''0_Z''js2015' and the like;
  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]* can match strings beginning with a letter, a underscore, or a $, followed by any number of digits, letters, underscores or $, which is the variable name allowed by JavaScript;
  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19} controls the length of strings to 1-20 characters (1 character in front + 19 characters in the back).

A|B can match A or B, so (J|j)ava(S|s)cript can match 'JavaScript''Javascript''javaScript' or 'javascript'.

The ^ symbol indicates the beginning of a line. ^\d indicating that strings must begin with a number.

The $ symbol indicates the end of a line. \d$ indicating that strings must end with a number.

You may have noticed that js can also match 'jsp', but ^js$ becomes a whole line match, it will only match 'js'.

Here is a awesome project for learning Regular Expression on GitHub.

Using RegExp in JavaScript

With the preparation knowledge, we can use regular expressions in JavaScript.

JavaScript has two ways to create a regular expression:

The first way is writing  /.../ directly, the second way is using the new RegExp('..') statement to create a RegExp object.

These two methods are the same:

var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');

re1; // /ABC\-001/
re2; // /ABC\-001/

Note that when using the second way, because of escaping of the string, the two backslashes  \\ should be viewed as one \.

First look at how to determine if the regular expression matches:

var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false

The test() method of a RegExp object is used to test if a given string is eligible.

Split String

Splitting a string with a regular expression is more flexible than using a fixed character. See the normal split code:

'a b   c'.split(' '); // ['a', 'b', '', '', 'c']

Well, it can’t recognize consecutive spaces. Try using regular expressions:

'a b   c'.split(/\s+/); // ['a', 'b', 'c']

No matter how many spaces, it can be split normally. Try adding ,:

'a,b, c  d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']

Try adding again ;:

'a,b;; c  d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']

If the user enters a set of tags, remember to use regular expressions to convert the non-standard input into the correct array.

Grouping

In addition to simply judging whether or not to match, regular expressions also have the power to extract substrings. The () representation is the group to be extracted. Such as:

In ^(\d{3})-(\d{3,8})$, two groups are defined separately. And the area code and local number can be extracted directly from the matched string:

var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345'); // ['010-12345', '010', '12345']
re.exec('010 12345'); // null

If a group is defined in a regular expression, you can extract the substring from the RegExp object using the exec() method.

After the match is successful, the exec() method returns an Array. The first element is the entire string matched by the regular expression, and the following strings indicate the substrings that matched the match.

The exec() method returns null when the match fails.

Extracting substrings is very useful. Let’s look at a more complicated example:

var re = /^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$/;
re.exec('19:05:30'); // ['19:05:30', '19', '05', '30']

This regular expression can directly identify legal time. But sometimes, regular expressions can’t perform extremely complex tasks, such as identifying dates:

var re = /^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$/;

For '2-30''4-31' such illegal dates, it is hard to identify for regular expressions. You need to handle this situation by yourself.

Greedy Match

It is important to note that regular matching defaults to greedy matching, which means matching as many characters as possible. For example, match the following number 0:

var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', '']

Because \d+ adopts greedy match and it matches all the following 0 directly. Thus the group 0* can only match the empty string. That’s why the third element of the array is empty.

If you want to use non-greedy match for \d+ (that is, matching as little as possible), add a ? can to it. Thus 0* can match some characters:

var re = /^(\d+?)(0*)$/;
re.exec('102300'); // ['102300', '1023', '00']

Global search

JavaScript regular expressions also have a few special flags, the most common one is g which represents a global match:

var r1 = /test/g;
// Equivalent to:
var r2 = new RegExp('test', 'g');

A global match allows the exec() method to be performed multiple times to search for a matching string. When specifying the g flag, each time we runs exec(), the regular expression itself updates the lastIndex property, indicating the last index that was matched recently:

var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;

// Use global match:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10

re.exec(s); // ['VBScript']
re.lastIndex; // 20

re.exec(s); // ['JScript']
re.lastIndex; // 29

re.exec(s); // ['ECMAScript']
re.lastIndex; // 44

re.exec(s); // null, until the end still does not match

Global matches are similar to search, so they can’t be used with /^...$/, since /^...$/ will only match at most once.

Regular expressions can also specify the i flag to indicate that case is ignored. And the m flag indicates that multiple line matches are performed.

Summary of RegExp

Regular expressions are very powerful and it is impossible to finish them in a short section. To make a clear statement of all the contents of RegExp, you can write a book. If you often encounter problems with regular expressions, you may need a reference book for regular expressions.

Exercise 1

Try writing a regular expression that verifies the email address.

'use strict';

// TODO: Write a RegExp here!
var re = /.../;

// Test:
var i,
    success = true,
    should_pass = ['someone@gmail.com', 'bill.gates@microsoft.com', 'tom@voyager.org', 'bob2015@163.com'],
    should_fail = ['test#gmail.com', 'bill@microsoft', 'bill%gates@ms.com', '@voyager.org'];
for (i = 0; i < should_pass.length; i++) {
    if (!re.test(should_pass[i])) {
        console.log('Failed: ' + should_pass[i]);
        success = false;
        break;
    }
}
for (i = 0; i < should_fail.length; i++) {
    if (re.test(should_fail[i])) {
        console.log('Failed: ' + should_fail[i]);
        success = false;
        break;
    }
}
if (success) {
    console.log('Passed!');
}

Version 2 can verify and extract the email address with the name:

JSON

JSON is an abbreviation of JavaScript Object Notation, which is a data exchange format.

Before the advent of JSON, everyone used XML to pass data. Because XML is a plain text format, it is suitable for exchanging data over the network. XML itself is not complicated, but with a lot of complicated specifications such as DTD, XSD, XPath, XSLT, etc. Any software developer will feel uncomfortable when handling XML.

Finally, one day in 2002, Douglas Crockford invented JSON, the ultra-lightweight exchange data format.

Douglas have long served as a senior architect at Yahoo, and naturally love JavaScript. The JSON he designed is actually a subset of JavaScript. In JSON, there are several types of data:

  • Number: exactly the same as JavaScript number;
  • Boolean: is the JavaScript true or false;
  • String: is JavaScript string;
  • Null: is JavaScript null;
  • Array: is the Array representation of JavaScript – [];
  • Object: is the { ... } representation of JavaScript .

And any combination of the above.

Moreover, JSON also stipulates that the character set must be UTF-8, indicating that there is no problem with multiple languages.

For unified parsing, JSON strings must be enclosed in double quotes "", and Object keys must be enclosed in double quotes "".

Because JSON is very simple, it quickly became popular in the Web world and became the ECMA standard. Almost all programming languages ​​have libraries that parse JSON. And in JavaScript, we can use JSON directly because JavaScript has built-in JSON parsing.

Turning any JavaScript object into JSON is to serialize the object into a JSON-formatted string so that it can be passed to other computers over the network.

If we receive a string in JSON format, just deserialize it into a JavaScript object, we can use this object directly in JavaScript.

Serialization

Let’s first serialize the object person into a string in JSON format:

'use strict';

var person = {
    Name: 'John',
    Age: 14,
    Gender: true,
    Height: 1.65,
    Grade: null,
    'middle-school': '\"W3C\" Middle School',
    Skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};

To output something nice, you can add parameters and press indented output:

JSON.stringify(person, null, '  ');

result:

{
  "name": "John",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

The second parameter is used to control how to filter the key value of the object. If we only want to output the specified property, we can pass in Array:

JSON.stringify(person, ['name', 'skills'], '  ');

result:

{
  "name": "John",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

You can also pass in a function so that each key-value pair of the object is processed by the function:

function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}

JSON.stringify(person, convert, '  ');

The above code turns all string values ​​into their uppercase form:

{
  "name": "John",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" MIDDLE SCHOOL",
  "skills": [
    "JAVASCRIPT",
    "JAVA",
    "PYTHON",
    "LISP"
  ]
}

If we still want to precisely control how to serialize an object, you can define a toJSON() method that directly returns the JSON data:

var person = {
    name: 'John',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return { // Only output name and age, and change the key:
            'Name': this.name,
            'Age': this.age
        };
    }
};

JSON.stringify(person); // '{"Name":"John","Age":14}'

Deserialization

Given a string in JSON format, we use JSON.parse() to turn it into a JavaScript object:

JSON.parse('[1,2,3,true]'); // [1, 2, 3, true]
JSON.parse('{"name":"John","age":14}'); // Object {name: 'John', age: 14}
JSON.parse('true'); // true
JSON.parse('123.45'); // 123.45

You can also specify a function for JSON.parse() that converts the parsed properties:

'use strict';
var obj = JSON.parse('{"name":"John","age":14}', function (key, value) {
    if (key === 'name') {
        return 'Mr ' + value;
    }
    return value;
});
console.log(JSON.stringify(obj)); // {name: 'Mr John', age: 14}

Using JSON in JavaScript is as simple as that!

Closing Words

You have learned Data, RegExp and JSON. Believe me, you gonna need them in your future development life. And you will thanks yourself for keep learning.

If you have any suggestion or question, leave me a comment!

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *