es6

1、let
基本用法
         ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。(例如大括号之内,for循环体内)




不存在变量提升
         let不像var那样,会发生“变量提升”现象。//局部就是局部,不能变为全局 
console.log("ES5:");
var a = [];
for (var i = 0; i < 10; i++) {
var c = i;
a[i] = function () {
console.log(c);
};
};
a[5](); //9




//ES6
console.log("ES6:");
var b = [];
for (var j = 0; j < 10; j++) {
let d = j;
b[j] = function () {
console.log(d);
};
};
b[5](); //5


暂时性死区
         只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。//作用域内一切都是以let为准
var a = 100;
{
console.log(a); //undefined
let a = 100;
console.log(a); //100
}


不允许重复声明
         let不允许在相同作用域内,重复声明同一个变量。
// 模块之间不影响,可以重复声明
{
var a = 100;
var a = 200;
console.log(a);//200
}
{
let a = 300;
console.log(a);//300
}
// 模块内部不允许用let命令重复声明
{
var a = 1;
let a = 2;
console.log(a);//报错
}
2、块级作用域
 为什么需要块级作用域?
         ES5只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。
         
第一种场景,内层变量可能会覆盖外层变量。
var time = new Date();




function fun() {
console.log(time);
if (false) {
var time = "Hello World!";
};
};
fun(); //undefined,因为fun函数里面有定义time,因此会去找time,但是因为没有进入if判断语句,time就找不到,因此就是undefined,把外层变量覆盖了。可以理解为fun是入口,一进去就要输出time,但是time没有定义。
        
 第二种场景,用来计数的循环变量泄露为全局变量。
var string = "Hello World!";




for (var i = 0; i < string.length; i++) {
console.log(string[i]);
};




console.log("循环结束");
console.log(i); //12,即使跳到外面


ES6的块级作用域
         let实际上为JavaScript新增了块级作用域。
<script type="text/javascript">
console.log("ES5:");




function fun() {
var num = 100;
if (true) {
var num = 200;
};
console.log(num);
};




fun(); //200
</script>
<script type="text/traceur">
console.log("ES6:");




function fun() {
let num = 100;
if (true) {
let num = 200;
};
console.log(num);
};




fun(); //100
立即执行函数:
要在函数体后面加括号就能立即调用,则这个函数必须是函数表达式,不能是函数声明。
函数表达式 var fnName = function () {…};使用function关键字声明一个函数,但未给函数命名,最后将匿名函数赋予一个变量,叫函数表达式,这是最常见的函数表达式语法形式。
在function前面加!、+、 -甚至是逗号等到都可以起到函数定义后立即执行的效果,而()、!、+、-、=等运算符,都将函数声明转换成函数表达式,消除了javascript引擎识别函数表达式和函数声明的歧义,告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。
console.log("ES5:");
function fun() {
console.log("I am outside!");
};




(function () {
if (false) {
function fun() {
console.log("I am inside!");
};
};




fun();  //I am inside! 因为是立即执行函数,里面的fun函数不管是false还是true,都是会提取出来立即执行,覆盖外面的fun函数
}());
</script>
<script type="text/traceur">
console.log("ES6:");
function fun() {
console.log("I am outside!");
};




(function () {
if (false) {
function fun() {
console.log("I am inside!");
};
};




fun();  //I am inside! es6中代码块是独立的,里面的fun函数代码块不会影响到外面,因此输出的是外面的fun函数结果
}());
3、const命令
const也用来声明变量,但是声明的是常量。
一旦声明,常量的值就不能改变。
不可重复声明


块级作用域:
if (true) {
const Pi = 3.14159265;
};
console.log(Pi); //Pi is not defined


暂时性死区:
if (true) {
console.log(Pi); //undefined
const Pi = 3.14159265;
};


const对象:
const person = {};
person.name  = "Zhangsan";
person.age   = 30;




console.log(person.name);
console.log(person.age);
console.log(person);




person = {}; //person is read-only,可以改变增加对象的属性,但是不能重新赋值


const数组:
const arr = [];
console.log(arr);
console.log(arr.length);
console.log("------");
arr.push("Hello world!");
console.log(arr);
console.log(arr.length);
console.log("------");
arr.length = 0;
console.log(arr);
console.log(arr.length);
console.log("------");




// 错误用法,不能采用重新赋值的方法,要增加元素只能push
arr = ["Hello Everyone!"]; 


const对象冻结:采用了对象冻结,就不能在后来增加和改变属性,要有属性,只能在赋值的时候设置
const person = Object.freeze({});
person.name  = "Zhangsan";
person.age   = 30;




console.log(person.name); //undefined
console.log(person.age); //undefined
console.log(person); //Object






const person = Object.freeze({
name: "Zhangsan",
age : 30
});




console.log(person.name); //Zhangsan
console.log(person.age); //30
console.log(person); //Object


跨模块常量:
const声明的常量只在当前代码块有效。
如果想设置跨模块的常量,应该怎么办呢?以下是指在不同的js文件中的写法
// module.js
export const intVariantName = 100;
export const FloatVariantName = 3.14159165;
export const charVariantName = "variantValue";




// use.js
import * as variant from './module';
console.log(variant.intVariantName); //100
console.log(variant.FloatVariantName); //3.14159165
console.log(variant.charVariantName); //variantValue




// otherUse.js
import { FloatVariantName, charVariantName } as variant from './module';
console.log(variant.FloatVariantName); //3.14159165
console.log(variant.charVariantName); //variantValue




// OnlyInt.js
import intVariantName as variant from './module';
console.log(variant.intVariantName); //100


全局对象的属性:
全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js指的是global对象。在JavaScript语言中,所有全局变量都是全局对象的属性。(Node的情况比较特殊,这一条只对REPL环境适用,模块环境必须显式声明成global的属性。)
 ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。
var varName = "varValue";
// 浏览器环境下
console.log(window.varName); //varValue
// Node.js环境下
//console.log(global.varName); //varValue
// 通用环境
console.log(this.varName); //varValue




let letName = "letValue";
console.log(window.letName); //undefined -- use strict
console.log(this.letName); //undefined -- use strict


4、数组的结构赋值
Destructuring
         ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring) 。
let [foo, [[bar], base]] = [1, [[2], 3]];
console.log(foo); //1
console.log(bar); //2
console.log(base); //3




let [, , third] = ["first", "second", "third"];
console.log(third); //third




let [one, , three] = ["One", "Two", "Three"];
console.log(one); //One
console.log(three); //Three




let [head, ...tail] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(head); //0
console.log(tail); //[1, 2, 3, 4, 5, 6, 7, 8, 9]


解构不成功:
var [temp] = [];
console.log(temp); //undefined
var [first, second] = [100];
console.log(first); //100
console.log(second);//undefined


不完全解构
         等号左边的模式,只匹配一部分的等号右边的数组。
let [x, y] = [1, 2, 3];
console.log(x); //1
console.log(y); //2




let [a, [b], c] = [1, [2, 3], 4];
console.log(a); //1
console.log(b); //2
console.log(c); //4


指定默认值
         注意:ES6内部使用严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。
var [temp = "string"] = [];
console.log(temp); //string




var [temp = "string"] = ["tempString"];
console.log(temp); //tempString




var [x = "aaa", y] = ["bbb"];
console.log(x); //bbb
console.log(y); //undefined




var [m, n = "aaa"] = ["bbb"];
console.log(m); //bbb
console.log(n); //aaa




var [p, q = "aaa"] = ["bbb", undefined];
console.log(p); //bbb
console.log(q); //aaa


非遍历解构--报错
var [temp] = 1; //1[Symbol.iterator] is not a function at eval
var [temp] = false; //false[Symbol.iterator] is not a function at eval
var [temp] = NaN; //NaN[Symbol.iterator] is not a function at eval
var [temp] = undefined; //Cannot read property 'Symbol(Symbol.iterator)' of undefined at eval
var [temp] = null; //Cannot read property 'Symbol(Symbol.iterator)' of null at eval


let和const命令
         只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。
let [a, b, c] = new Set(["a", "b", "c"]);
console.log(a); //a
console.log(b); //b
console.log(c); //c




function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
};
var [first, second, third, fourth, fifth, sixth] = fibs();
console.log(sixth); //5


5、对象的解构赋值
解构不仅可以用于数组,还可以用于对象
         对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
var { name, age } = { name: "Conan", age: 28 };
console.log(name); //Conan
console.log(age); //28


解构赋值不用按照顺序:
var { name, age, id } = { id: "007", name: "Conan", age: 28 };
console.log(name); //Conan
console.log(age); //28
console.log(id); //007


变量名和属性名不一致时:
var { name: person_name, age: person_age, id: person_id } = { id: "007", name: "Conan", age: 28 };
console.log(person_name); //Conan
console.log(person_age); //28
console.log(person_id); //007




let object = { first: "Hello", last: "World" };
let { first: firstName, last: lastName} = object;
console.log(firstName); //Hello
console.log(lastName); //World


指定默认值
         默认值生效的条件是,对象的属性值严格等于undefined。
对象解构默认值:
var { x = 3 } = {};
console.log(x); //3




var { x, y = 5 } = { x: 1 };
console.log(x); //1
console.log(y); //5




var { message: msg = "You Are A Person!" } = {};
console.log(msg); //You Are A Person!


对象解构默认值条件:undefined
var { x = 3 } = { x: undefined };
console.log(x); //3




var { y = 3 } = { y: null };
console.log(y); //null


已声明变量的解构赋值,要带有小括号
var x;
({x} = { x: 1 });
console.log(x); //1


现有对象的方法
         对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量


console.log(Math.sin(Math.PI/6)); //0.49999999999999994
let { sin, cos, tan, log } = Math;
console.log(sin(Math.PI/6)); //0.49999999999999994
上面代码将Math对象的正弦、余弦、正切、对数三个方法,赋值到对应的变量上,使用起来就会方便很多。


6、字符串的解构赋值
字符串也可以解构赋值
         字符串被转换成了一个类似数组的对象。
const [ a, b, c, d, e ] = "Hello";
console.log(a); //H
console.log(b); //e
console.log(c); //l
console.log(d); //l
console.log(e); //o


属性解构赋值
         类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
const { length: len } = "Hello";
console.log(len); //5




const { length } = "Hello World!";
console.log(length);//12


7、函数参数的解构赋值
函数的参数也可以使用解构。
function sum([x, y]) {
return x + y;
};




console.log(sum([1, 2])); //3


函数参数的解构也可以使用默认值。
function fun ({x = 0, y = 0} = {}) {
return [x, y];
};




console.log(fun({x: 100, y: 200})); //[100, 200]
console.log(fun({x: 100})); //[100, 0]
console.log(fun({})); //[0, 0]
console.log(fun()); //[0, 0]


function fun ({x, y} = { x: 0, y: 0 }) {
return [x, y];
};


//想要默认值有效,必需设置在前面


console.log(fun({x: 100, y: 200})); //[100, 200]
console.log(fun({x: 100})); //[100, undefined]
console.log(fun({})); //[undefined, undefined]
console.log(fun()); //[0, 0]


8、解构赋值的用途


1)交换变量的值
//ES5
console.log("ES5:");
var a = 100;
var b = 200;
console.log("交换前:");
console.log("a = " + a); //a = 100
console.log("b = " + b); //b = 200
var temp;
temp = a;
a = b;
b = temp;
console.log("交换后:");
console.log("a = " + a); //a = 200
console.log("b = " + b); //b = 100




//ES6
console.log("ES6:");
var x = 100;
var y = 200;
console.log("交换前:");
console.log("x = " + x); //x = 100
console.log("y = " + y); //y = 200
[x, y] = [y, x];
console.log("交换后:");
console.log("x = " + x); //x = 200
console.log("y = " + y); //y = 100


2)从函数返回多个值
数组:
function fun () {
return [1, 2, 3];
};




var [x, y, z] = fun();
console.log(x); //1
console.log(y); //2
console.log(z); //3


对象:
function fun () {
return {
id  : "007",
name: "Conan",
age : 28
};
};




var { id, name, age } = fun();
console.log(id); //007
console.log(name); //Conan
console.log(age); //28
var { id: person_id, name: person_name, age: person_age } = fun();
console.log(person_id); //007
console.log(person_name); //Conan
console.log(person_age); //28


3)函数参数的定义
// 参数是一组有次序的值
function fun ([x, y, z]) {
//x = 100;
//y = 200;
//z = 300;
};
fun([100, 200, 300]);




// 参数是一组无次序的值
function fun ({id, name, age}) {
//id   = "007";
//name = "Conan";
//age  = 28;
};
fun({id: "007", name: "Conan", age: 28});


4)提取json数据用法
var jsonData={
name: "Conan",
age: 28,
score: {
Chinese: 98,
Math: 148,
English: 107
}
};
console.log(jsonData);




console.log("ES5:");
console.log("Person's Number is:" + jsonData.id);
console.log("Person's Name is:" + jsonData.name);
console.log("Person's age is:" + jsonData.age);
console.log("Person's Chinese score is:" + jsonData.score.Chinese);
console.log("Person's Math score is:" + jsonData.score.Math);
console.log("Person's English score is:" + jsonData.score.English);




console.log("ES6:");
let { id: number, name, age, score: score } = jsonData;
console.log("Person's Number is:" + number);
console.log("Person's Name is:" + name);
console.log("Person's age is:" + age);
console.log("Person's Chinese score is:" + score.Chinese);
console.log("Person's Math score is:" + score.Math);
console.log("Person's English score is:" + score.English);


5)         函数参数的默认值


jQuery.ajax({
 url: '/path/to/file',
 type: 'POST',
 dataType: 'xml/html/script/json/jsonp',
 data: {param1: 'value1'},
 complete: function(xhr, textStatus) {
   //called when complete
 },
 success: function(data, textStatus, xhr) {
   //called when successful
 },
 error: function(xhr, textStatus, errorThrown) {
   //called when there is an error
 }
});

jQuery.ajax = function (url, {
async = true,
beforeSend = function() {},
cache = true,
complete = function() {},
crossDomain = false,
global = true,
// ...more config
}) {
// ... do stuff
};
// 避免了在函数体内部再写 var foo = config.foo || 'default foo'; 这样的语句


function(config){
   var foo = config.foo || 'default foo'
   return foo 
}
其实意思就是,想给foo指定一个值得话,我们就判断参数中的config对象中有没有foo属性,如果有直接赋值给var foo这个变量,否则走后半部分,foo = 'default foo'让foo等于default foo这个字符串
这样写的好处就是,就算调用这个方法不传参数,也能保证foo变量有值,也就是所谓的默认值




但是有了ES6就不用这么麻烦了,直接在参数中就可以赋默认值了,以下是阮一峰老师的标准ES6中是实例




函数参数的解构也可以使用默认值




function move({x = 0, y = 0} = {}) {
  return [x, y];
}




move({x: 3, y: 8}); // [3, 8]
move({x: 3}); // [3, 0]
move({}); // [0, 0]
move(); // [0, 0]


6)遍历map结构
var map = new Map();
map.set("id", "007");
map.set("name", "Conan");




console.log(map);
console.log(typeof(map));




// 获取键名和键值
for (let [key, value] of map) {
console.log(key + " is " + value);
};
// id is 007
// name is Conan

// 获取键名
for (let [key] of map) {
console.log(key);
};
// id
// name

for (let [, value] of map) {
console.log(value);
};
// 007
// Conan


7)输入模块的指定方法
const { SourceMapConsumer, SourceNode } = require("source-map");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值