ES6 's improved JavaScript "defect" problem _javascript skills

Source: Internet
Author: User
Tags constant

Block-level scopes

ES5 does not have block-level scope, only global scope and function scope, because of this, the scope of the variable is very wide, so a entry function is to create it immediately. This creates the so-called variable ascension.

ES5 's "variable Elevation" feature is often inadvertently caused by a mistake:

1. Inner variables cover outer variables

var tmp = new Date ();
function f () {
console.log (TMP);
if (false) {//execute undefined
var tmp = "Hello World";
}
}

2. Variable leakage, become global variable

var s = ' Hello ';
for (var i = 0; i < s.length i++) {
console.log (s[i]);
Console.log (i); 5

Usually we use closures to solve this problem (such as the Self execution function). Now, based on this problem, ES6 adds block-level scopes, so it's no longer necessary to perform the function itself.

Let and const

ES6 is backwards compatible, while backward compatibility means never changing the behavior of the JS code on the Web platform, so var creates a variable whose scope will still be global scope and function scope. In this way, even with the block-level scope, it is not possible to solve the ES5 "variable elevation" problem. So, here ES6 added two new keywords: let and const.

1.let

Let is the more perfect Var, and it has better scoping rules.

2.const

Const declares a read-only constant. Once declared, the value of a constant cannot be changed, but a const-declared object can have property changes (object Freeze Object.freeze)

Const A = [];
A.push (' Hello '); Executable
a = [' Dave '];//Error

You can also use Object.freeze to freeze objects

const FOO = object.freeze ({});
In normal mode, the following line does not work;
//When strict mode, the Guild complains
Foo.prop = 123;//

Use Let and const:

• The variable is valid only within the block-level scope where the declaration is located

• Variable declaration can be used (temporary Dead zone)

• Cannot define variables repeatedly

• Declared global variables that are not part of the global object's properties

var a = 1;
WINDOW.A//1 let
b = 1;
WINDOW.B//undefined

this keyword

We know that this in the ES5 function points to the scope of the runtime. Like what

function foo () {
settimeout (function () {
console.log (' ID: ', this.id);
}
var id =;
Foo.call ({id:42});//id:21

Here, I declare a function of Foo, whose interior is a delay function settimeout, which prints a this.id every 100ms. We call it through Foo.call ({id:42}) and set the scope for this function. It's really going to wait 100 milliseconds, because this points to the scope of the runtime, so here's this point to the Global Object window, not the function foo. Over here:

• Use call to change the execution context of Foo so that the execution context of the function is no longer window to identify the this point in settimeout

The settimeout method hangs under the Window object, so it points to the scope--window object where the execution occurs.

The code for the timeout call is executed in the global scope, so the value of this in the function points to the window object in strict mode and is undefined--"JavaScript advanced Programming"

To solve this problem, it is often our usual practice to assign this to other variables:

function foo () {var = this;
settimeout (function () {
console.log (' ID: ', that.id);
}
var id =;
Foo.call ({id:42});//id:42

And now ES6 has introduced the arrow function to solve the problem.

Arrow function

An identifier => expression

var sum = (NUM1, num2) => {return num1 + num2;}
Equivalent to
var sum = function (NUM1, num2) {return
num1 + num2;
};

• Parentheses can be omitted if the function has only one argument

• If the function has only one return statement, you can omit the curly braces and returns

• If the function returns an object directly, parentheses must be added outside the object. (Because an empty object {} and an empty block {} look exactly the same.) So you need to wrap the object literal with parentheses. )

For this keyword issue, ES6 defines the scope in which the this binding is defined in the arrow function, not the scope where the runtime is located. Since then, this point has been fixed, thus facilitating the encapsulation of callback functions.

function foo () {var = this;
SetTimeout (() =>{
console.log (' ID: ', that.id);
} 
var id =;
Foo.call ({id:42});//id:42

NOTE: The arrow function this point is not fixed because there is a mechanism within the arrow function that binds this, and the actual reason is that the arrow function does not have its own this. And the arrow function does not have its own this, the inside of this is the outer code block this. This leads to the following:

• cannot be used as a constructor

• You cannot use call (), apply (), bind () to change the point of this

Class and inheritance

Traditional ECMAScript has no concept of class, it describes the concept of prototype chain, and the prototype chain as the main method to implement inheritance. The basic idea is to make a reference type inherit the properties and methods of another reference type using the prototype. The traditional way to implement this behavior is through the constructor function:

function point (x, y) {
this.x = x;
This.y = y;
}
Point.prototype.toString = function () {return
' (' + this.x + ', ' + this.y + ') ';
var p = new Point (1, 2);

Here, the constructor point has a prototype object (prototype) that contains a pointer to point (constructor), and the instance P contains an internal pointer to the prototype object (prop). So the whole inheritance is realized through the prototype chain. The details are visible in my article: Prototype and constructor in JavaScript

Class

ES6 provides a closer approach to the traditional language, introducing the concept of Class (Class) as a template for objects. The class keyword allows you to define classes. But the class is just a prototype based object-oriented pattern of syntactic sugars. The introduction of class, mixed, many people think it is a major flaw, but for me, this is a good grammatical sugar, because the usual prototype chain to inherit the way often can take me around for a while.

Define class class point
{
constructor (x, y) {
this.x = x;
This.y = y;
}
ToString () {return
' (' + this.x + ', ' + this.y + ') ';
}
}
var p = new Point (1, 2);

• The class has a constructor method, which is the default method of the class, which is invoked automatically when the object instance is generated from the new command. A class must have a constructor method, and if not explicitly defined, an empty constructor method is added by default.

The This keyword in the constructor method represents the instance object.

• When defining the "class" method (such as ToString in the example above), you do not need to add a function to the keyword, just put in the definition of the functional. In addition, there is no need for commas between the methods and an error is added.

• Use the new command directly on the class when used, exactly the same as the constructor usage

• All methods of the class are defined above the prototype property of the class

Class's Inheritance--extend

Class can be inherited through the extends keyword, which is much clearer and more convenient than ES5 's inheritance by modifying the prototype chain.

Class ColorPoint extends Point {
constructor (x, y, color) {
super (x, y);//Call Constructor (x, Y) of the parent class
This.color = color;
}
ToString () {return
This.color + ' + super.tostring ();//Invoke the parent class's toString ()
}
}

The super keyword, as a function call (that is, super (... args)), which represents the constructor of the parent class, as an object invocation (that is, Super.prop or Super.method ()), which represents the parent class. Here, it represents the constructor of the parent class, which is used to create the This object of the parent class.

• The subclass must call the Super method in the constructor method, or the new instance will have an error. This is because the subclass does not have its own this object, but instead inherits the this object of the parent class and then processes it. If you do not call the Super method, the subclass will not get the This object.

of modular

Historically, JavaScript has never had a modular system, and it's not possible to split a large program into interdependent small files and assemble them in simple ways, creating a huge barrier to developing large, complex projects. In order to adapt to the development of large-scale modules, the community developed a number of module loading programs, such as CMD and AMD.

ES6 's modular style:

Import {stat, exists, readFile} from ' FS ';

The essence of the above code is to load 3 methods from the FS module, other methods do not load. This kind of load is called "compile-time load", that is, ES6 can complete the module loading at compile time, the efficiency is higher than the load mode of COMMONJS module. Of course, this also leads to the inability to refer to the ES6 module itself, because it is not an object.

The module function is composed of two commands mainly:

Export

To specify the external interface of the module, external interface, must establish one by one correspondence with the variables inside the module.

Writing one
export var m = 1;
Error
export 1;
Writing two
var m = 1;
Export {m};
Error
export m;
Writing triple named
var n = 1;
Export {n as M};

Import

Used to enter the functionality provided by other modules, which accepts an object (expressed in curly braces) that specifies the name of the variable to import from another module (or it can be loaded using the * number as a whole).

string interpolation

In the development of JavaScript, we often need to output templates like this:

function SayHello (name) {return
' hello,my name is ' +name+ ' I am ' +getage;
}
function Getage (age) {return age
;
}
SayHello ("brand")//"Hello,my name is brand I am 18"

We need to use + to connect strings and variables (or expressions). The example is relatively simple, so it seems harmless, but once in a more complex situation, it will appear quite cumbersome inconvenient, this usage also let us take pains. In this respect, ES6 introduces the template string, which can conveniently insert the value of JS into the string.

Template string

For a template string, it:

• Use inverted quotes ' packages;

• Use ${} to output values;

The contents of ${} can be any JavaScript expression, so function calls and arithmetic operations are all legitimate;

• If a value is not a string, it is converted to a string;

• Keep all spaces, newline, and indentation, and output to the result string (you can write multiple lines of string)

• Internal use of inverted quotes and curly braces to escape, escape using backslashes \

For the above example, the template string is written as follows:

function SayHello (name) {return
' hello,my name is ${name} I am ${getage (a)} ';
}
function Getage (age) {return age
;
}
SayHello ("brand")//"Hello,my name is Brandi am 18"

Strict mode

One of the goals of strict mode is to allow faster debugging errors. The best way to help developers debug is to throw a corresponding error when a certain problem occurs (throw errors when certain patterns occur), rather than silently failing or behaving strangely (often in a non strict mode). Code in strict mode throws more error messages and helps developers quickly notice some issues that must be addressed immediately. In ES5, strict mode is optional, but in ES6 many features require strict patterns, a habit that helps us write better JavaScript.

The above mentioned is small set to introduce the ES6 modified JavaScript "defect" problem, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.