将"use strict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,
则无效,整个脚本以"正常模式"运行。如果不同模式的代码文件合并成一个文件,这一点需要特别注意。
"use strict"//严谨模式
var i = 1;
var str=" var i = 5;";
eval(str);
console.log();//在严谨模式下 只会输出第一定义i的变量,不会被str所影响
function f(){
"use strict";
console.log(this);//这个指向obj
function time(){
this.name="obj";
console.log(this);//window在严格模式下就是undefined 报错
}
time();
}
var obj ={};
obj.f = f;
obj.f();
"use strict"
var num = 2;//严格模式下 定义变量必须加var 不加var 不给你用
function show(){
"use strict"
var num = 1;//严格模式下 禁止 函数内的变量变成全局
console.log(num)
}
show();
console.log(num)
{
let a = 10;//a只属于这个块({})里面外面不可以用
var b = 1;
}
console.log(a)//undefined 报错
console.log(b)//1
for循环的计数器,就很合适使用let命令。
// for循环的计数器,就很合适使用let命令。
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i)
};
}
arr[2]();
//let 块作用域 for循环相当于 独立的一块
arr[1] = function () {
console.log(i)
};
arr[2] = function () {
console.log(i)
};
arr[3] = function () {
console.log(i)
};
arr[4] = function () {
console.log(i)
};
console.log(foo);
console.log(bar);
var foo = 2;//提升变量后 输出的时候没有赋值 所以 是undefined
let bar = 2;//let 不存在变量提升
var tmp = 123;
if (true) {
//tmp = 'abc';//报错 死区
let tmp;// let 必须在对顶部
tmp = 'abc';
console.log(tmp);//输出abc
}
console.log(tmp);//输出123
(function () {
let a = 10;//let 不能重复定义 只能有一个
var a = 1;//定义报错
console.log(a);
})()
// let实际上为JavaScript新增了块级作用域。
function f1() {
let n = 5;
if (true) {
let n = 10;//let限定在if这一块里面 其他无妨无效
}
console.log(n);
}
f1()//输出5
//const声明一个只读的常量。一旦声明,常量的值就不能改变。
const PI = [];//设置常量 无法修改
//PI = 3;//修改报错
PI[0]=123;
console.log(PI)
// ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
let [a, b, c] = [1, 2, 3];//数组方法 定义变量
console.log(a) // 1
console.log(b) // 2
console.log(c) // 3
let [var1, ...var2] = [1, 2, 3, 4];//...var2代表多个
console.log(var1);
console.log(var2);
-------------------------------------------------------------------
let [x = 1, y = x] = [];
console.log(x,y)//输出1 1
let [x = 1, y = x] = [2];
console.log(x,y)//输出2 2 定义了x=2
let [x = 1, y = x] = [1, 2];
console.log(x,y)//输出1 2
let [x = y, y = 1] = [];//报错
console.log(x,y)//因为x = y 的时候y还没有赋值
// 解构不仅可以用于数组,还可以用于对象
var { bar,foo } = { foo: "aaa", bar: "bbb" };
foo // "aaa"
bar // "bbb"
console.log(foo,bar);
var obj={
name:"abc",
arr:[1,2,3,4],
json:{
name:"json",
}
}
var {name,arr,json} = obj;
console.log(name,arr,json);
var [a,b,c,d] = obj.arr//a,b,c,d 相当于obj里面数组的1,2,3,4
console.log(a,b,c,d)
// 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
function show (a,b){
var b=b||0;
console.log(a+b);
}
show(5,6);
// ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
function show (a=2,b=1){
console.log(a+b);
}
show(5);
// 参数默认值可以与解构赋值的默认值,结合起来使用。
function show([a,b,c]){//相当于把数组里面的值传进去
console.log(a+b+c);
}
var arr = [1,2,3]
show(arr);
var arr=[5,6,21,8,7,1,5];//...arr等于arr数组里面的5,6,21,8,7,1,5 抽出来
console.log(Math.max(...arr));
一个需要注意的地方是,如果参数默认值是一个变量,则该变量所处的作用域,
与其他变量的作用域规则是一样的,即先是当前函数的作用域,然后才是全局作用域。
var x = 1;
function f(x, y = x) {
console.log(y);
}
f(2)//传2 x=2
-----------------------------------
let x = 1;
//x等于1 y=x
function f(y = x) {
let x = 2;
//y=1
console.log(y);
}
f();
ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。
rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
var arr=[5,6,21,8,7,1,5];//...arr等于arr数组里面的5,6,21,8,7,1,5 抽出来
console.log(Math.max(...arr));
// 替代数组的apply方法
// 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
console.log(Math.max(...arr))
// ES5的合并数组
var arr =[1,2,3];
var arr2=[4,5,6];
var arr3=[7,8,9];
var all=arr.concat(arr2,arr3);
console.log(all);
// ES6的合并数组
var all = [...arr,...arr2,...arr3];
console.log(all);
// ES6允许使用“箭头”(=>)定义函数。=>等于return
var a = 5;
fn = a => a;
console.log(fn(a))
//正常函数写法
function fn(a){
return a;
}
console.log(fn(a))
--------------------------------------------------
fn = (a,b) => {
let c = a+b;
return c;
};
console.log(fn(3,6))
//正常函数写法
function fn(a,b){
var c = a+b;
return c;
}
console.log(fn(3,6))
/* 使用注意点
箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
*/
function Person(){
//输出传进来的数据 arguments 传进来的全部参数
console.log(arguments)
var sum = 0;
for(var value of arguments){
sum += value;
}
console.log(sum)
}
Person(2,3,5,4,5,6)
//箭头函数不可使用arguments
Person = (...arr) => {
var sum = 0;
for(var value of arr){
sum += value;
}
console.log(sum)
}
//指向window
Person(2,3,5,4,5,6)
var obj = {
name:"obj",
show:()=>{
setTimeout(()=>{
console.log(this)//指向window
})
}
}
obj.show()
//=>函数体内的this对象 不能指向本身
var obj = {
name:"obj",
show:()=>{
setTimeout(()=>{
console.log(this)//指向window
})
}
}
obj.show()
//function指向本身
var obj = {
name:"obj",
show:function(){
setTimeout(()=>{
console.log(this)//指向当前的this
})
}
}
obj.show()
var a ="hello";
var b ="冒泡";
//ES5字符串拼接
var str = a+""+b;
//ES6字符串拼接
var str=`${a}${b}`;
var str =`<a href="">${b}a>`;
console.log(str);
//ES5构造函数
//定义类
function Person(name){
this.name=name;
}
//创建原型
Person.prototype.show =function(){
console.log(this.name);
}
var obj =new Person("abc");
obj.show();//调用obj原型 show
//继承
function Son(name,age){
this.age = age
// Person.apply(this,arguments)
Person.call(this,name)
}
Son.prototype = new Person();
var s = new Son("son",18);
s.show()
console.log(s.age)
//ES6构造函数
//1.Class基本语法
class Person{
//构造方法
constructor(name){
this.name = name;
}
//原型方法
show(){
console.log(this.name);
}
}
var obj = new Person("es6");
obj.show()
// 2.Class的继承----------------------------
// Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
class Son extends Person{
constructor(name,age){
super(name);
this.age = age;
// this.name = "abc";
}
show(){
console.log(this.name,this.age)
}
}
var s = new Son("kkk",18);
s.show();
进行Babel转码。这意味着,如果项目要运行,全局环境必须有Babel,也就是说项目产生了对环境的依赖。
另一方面,这样做也无法支持不同项目使用不同版本的Babel。
一个解决办法是将 babel-cli 安装在项目之中。
$ sudo cnpm install babel-cli -g//先安装全局
$ sudo cnpm install babel-preset-es2015//再安装es2015标准
基本用法如下。
# 转码结果输出到标准输出
$ babel text.js//接着输出标准
# 转码结果写入一个文件
# --out-file 或 -o 参数指定输出文件
$ babel example.js --out-file compiled.js
# 或者
$ babel example.js -o compiled.js //转换文件
# 整个目录转码
# --out-dir 或 -d 参数指定输出目录
$ babel src --out-dir lib
# 或者
$ babel src -d lib
配置文件 .babelrc
Babel的配置文件是 .babelrc ,存放在项目的根目录下。使用Babel的第一步,就是配置这个文件。
该文件用来设置转码规则和插件,基本格式如下
{
"presets": ["es2015"],
"plugins": []
}
ES6新特性在Babel下的兼容性列表
ES6特性 兼容性
箭头函数 支持
类的声明和继承 部分支持,IE8不支持
增强的对象字面量 支持
字符串模板 支持
解构 支持,但注意使用方式
参数默认值,不定参数,拓展参数 支持
let与const 支持
for of IE不支持
iterator, generator 不支持
模块 module、Proxies、Symbol 不支持
Map,Set 和 WeakMap,WeakSet 不支持
Promises、Math,Number,String,Object 的新API 不支持
export & import 支持
生成器函数 不支持
数组拷贝 支持