var是声明全局的变量,作用域是全局,const是声明全局的常量,不能修改,而 let 是块级变量只在当前声明的作用域中生效:
{ var a = 10; let b = 20; } console.log(a); // 打印a的值 console.log(b); // 报错:ReferenceError: b is not defined
// 直接打印a的值,文件中没有声明a
console.log(a);// 报错:Uncaught ReferenceError: a is not defined
因为代码从上往下执行,a并没有声明,所以报错,但var有一个声明提前的情况,看下面代码:
console.log(a); //打印undefine var a = 10;
是不是认为应该会报错,其实不然,因为var有一个声明提前的现象,如果你在调用一个变量时,它在下文有声明时,他做了这样一个事情,相当在你调用前声明了变量名而没有赋值:
var a //等效调用前加上该语句 console.log(a); //打印undefined var a = 10;
注意,var在函数中声明的时局部标量,没var声明的全局变量
function ff(){ var a=1; console.log(a); //1 } ff(); console.log(a); //a is not defined function ff(){ a=1; console.log(a); //1 } ff(); console.log(a); //1
var 在函数内部声明时的变量提前:
// 情况1 var name = 'kingfan'; function foo(){ console.log(name) //打印kingfan; } // 情况2 var name = 'kingfan'; function foo(){ console.log(name) //打印undefined; var name = 'fan'; }; console.log(name) // 打印 kingfan
,var name = 'fan'在函数中声明的是局部变量 // 注意正常情况下,console.log(name)找的是全局 //,但是在局部中又声明了name,这时调用时就不会去找全局的name //,而是声明提前的name=undefined.
而let 声明的就是局部变量就不会出现声明提前的问题:
var pname = 'kingfan'; function f() { console.log(pname); //直接报错:Uncaught ReferenceError: pname is not defined let pname = 'fan'; console.log(pname) } f(); console.log(pname);
var a = 1; var a =2; a = 3; // var 可以对变量重新定义和赋值 let b = 3; b = 4; let b = 5; //报错:Identifier 'b' has already been declared // let声明的变量 只能重新赋值,不能重新定义 const c = 5; c = 6; // 报错,不能修改 const c = 7 //报错不能重新定义
总结:var声明的变量是可以重新定义和赋值,let声明的只能重新赋值,const不能重新定义和赋值修改
在es6中新增了模板字符串拼接:
var name='kingfan'; var age = 18; var msg = `我是${name},今年${age}岁`; console.log(msg) //打印 我是kingfan,今年18岁
ES6允许按照一定的模式,从数组或对象中提取值,对变量进行赋值,这种方式被称为解构赋值。
// 解构数组 var list =[1,2,3,4]; var [a,b,c,d] = list; console.log(a); //1 console.log(b); //2 console.log(c); //3 console.log(d); //4 //解构对象 var obj = { name:'kingfan', age:18, } // 利用key去接收 var {name,age}=obj; console.log(name); //'kingfan' console.log(age); //18 // 利用其它变量名接收 var {name:pname,age:page}=obj; console.log(pname); //'kingfan' console.log(page); //18
构造对象的方式 使用构造函数来创造。与构造函数唯一的不同是类函数名首字母要大写。
<script> class Animal{ //初始化函数,相当python中的init constructor(){ this.type = 'animal' }; say() { console.log('我是动物') }; } // 实例化对象 var dog = new Animal(); // 调用对象属性 console.log(dog.type); // 调用对象方法 dog.say(); </script>
类的继承,使用extens关键字继承父类:
class Peopel extends Animal{ constructor(){ super() // 必须在子类的构造函数中执行父类super方法才能得到this调用对象 } // 子类可以重构父类的方法 say(){ console.log('我是人') } } // 实例化new方法 var p =new Peopel(); // 调用父类的方法 console.log(p.type); // 重构后调用自己得say方法 p.say();
箭头函数有个特点:
- 如果参数只有一个,可以省略小括号
- 如果不写return,可以不写大括号
- 没有arguments变量
- 不改变this指向
- 其中箭头函数中this指向被固定化,不是因为箭头函数内部有绑定this的机制。实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。
可以查看下面两段代码输出的区别:
var person = { name: 'Q1mi', age:18, func:function(){ console.log(this); } } person.func() // person对象 //**************************************** var person = { name: 'Q1mi', age:18, func:()=>{ console.log(this); } } person.func() // window对象
在es6中增加了像python类似的import语法来导入其他js文件来使用。例如现在有2个文件,file1、file2
// file1 let name='kingfan'; let age = 18; // 要确保其他文件导入使用,需要确定你要导出哪些数据给别人使用 export {name,age} //*************************************** // file2 // 指定从file1要导入的数据 import {name,age} from 'file1'
目前很多浏览器不兼容此写法,会报错。