@wy
2018-03-09T08:40:50.000000Z
字数 4655
阅读 581
javascript
可以使用let、const关键字声明变量,而不推荐使用var声明变量
var声明变量的问题:
var存在很多问题,let横空出世。
let允许创建块级作用域,let声明的变量只在它所在的代码块内有效
{let test = 10;var foo = 1;}console.log(test) // ReferenceError: miaov is not defined.console.log(foo) // 1
在if中使用:
if(false){let test = 10; // 只在这个代码块内有效,形成了块级作用域var foo = 1;}console.log(test) // ReferenceError: miaov is not defined.console.log(foo) // undefined
在for中使用,i只能在循环体内使用,循环体外会报错:
for (let i = 0; i < 10; i++) {// ...}console.log(i); // ReferenceError: i is not defined
const声明变量同let声明变量一样,在块级作用域有效。不同的是,const用来声明常量,一旦声明赋值后,变量不能被重新赋值:
const test = 123;test = 10;console.log(test); // Uncaught TypeError: Assignment to constant variable.
如果赋的值是引用类型,那么可以通过变量来修改引用类型的值:
const test = {};test.a = 1;test.b = 2;console.log(test); // {a: 1, b: 2}
总结let和const:
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。通过这种方式可以避免在对象赋值时产生中间变量。
function test(){return [1,2,3,4];}var [a,b] = test();console.log(a,b); // 1,2
test函数执行后,返回的是一个数组。取数组前两个值分别存在变量中,根据解构赋值的规则,在左侧声明变量,放在中括号中,会把右边数组中的值一一对应赋值给左边的变量。
function test(){return {a:1,b:2,c:3};}var {a,b} = test();console.log(a,b); // 1,2
test函数执行后,返回的是一个对象。分别取出对象中属性为a和b的值,根据解构赋值的规则,在左侧声明变量,放在大括号中,变量名要和属性名保持一致。
function test({a,b}){console.log(a,b);}test({a:1,b:2,c:3})
在形参中定义变量,得到实参对象指定的属性。
可以给变量设置默认值和另声明一个变量
var {a:otherVar,b,d='默认值'} = {a:1,b:2,c:3};console.log(d); // 默认值console.log(otherVar); // 1console.log(a); // Uncaught ReferenceError: a is not defined
使用=给变量赋一个默认值,如果右边对象中没有与之对应的属性,则按默认值来。
使用:重新声明一个变量,会把匹配到的a的值赋给新的变量otherVar,此时在外面使用时候,不能使用a。
也可以连着一起使用:
var {a,b,d:foo='默认值'} = {a:1,b:2,c:3};console.log(foo); // '默认值'
模板字符串(template string)是增强版的字符串,用反引号(`)标识。
定义字符串
var str = `<li>hello</li>`
在模板字符串中拼写HTML结构,无需考虑回车换行。
在模板字符串中要渲染某个变量的值,可以写在占位符${}中
var message = 'hello';var str = `<li>${message}</li>`
打印出:
"<li>hello</li>"
${}中可以写入任意的表达式(表达式是可以被求值的代码),例如:
var message = 'hello';var str = `<li>${message}${1+1}${1 > 2 ? true : false}${[1,2,3].map(function(item){return item*2})}</li>`
但不能在${}中写入if和for这样的语句。
在ES6中,箭头函数就是函数的一种简写形式,允许使用“箭头”(=>)定义函数。
之前声明函数:
function foo(){return 1;}
改造为箭头函数:
let foo = () => 1;
上面使用“箭头”(=>)定义的函数,左侧的()包裹函数的形参,如果定义的函数没有形参或者多个形参,一定要使用括号:
// 没有参数,要使用()let test = () => 1;// 多个参数,要使用()let foo = (a,b) => a + b;let bar = (a,b,c) => a + b + c;
如果形参只有一个,可以省略括号:
let foo = a => a;
“箭头”(=>)的右侧是函数体代码,会在函数执行后作为函数的返回值,不需要显示的使用return
let foo = (a,b) => a + b;console.log(foo(1,2)); // 3
以上的简写方式,使代码变得非常简洁,忍不住再来个例子:
let arr = [1,2,3];let newArr = arr.map(item => item * 2);console.log(newArr); // [2,4,6]
有多行代码,可以写在一对{}中,手动调用return返回值:
let foo = (a,b) => {console.log(a)console.log(b)return a + b;}
当要返回的是对象时,又不想手动调用return,记得加上()保证是一个对象整体,而不被误以为是函数体:
var obj = () => ({a:1,b:2})console.log(obj()); // {a:1,b:2}
箭头函数内的this,绑定定义时所在的作用域的this,并不是在调用时候决定this的指向。
document.onclick = function (){setTimeout(function (){console.log(this); // 定时器执行的函数,在非严格模式下this指向window},1000)}
如果要在setTimeout中使用点击时的元素,通常需要存一个变量。
document.onclick = function (){var that = this;setTimeout(function (){console.log(that); // that变量存的就是触发事件的元素},1000)}
如果使用箭头函数,一切讲变得非常简单:
document.onclick = function (){setTimeout( () => {console.log(this);},1000)}
箭头函数是在事件处理函数中定义,事件处理函数this指向的是触发事件的元素,所以这个this,也就是触发事件的元素。
使用箭头函数的特性:
允许在形参声明时,写入默认值,说明这个值是可选的。
传统做法:
/*参数:a是必填项b可选的*/function fn(a,b){b = b || 10;return a + b;}
以上的方式是参数b如果没传入的话,值就为10;
这样写会有一个问题,假如传到函数的参数为0,则b的值依然为10,正确的应该是0才对,因为||运算符左边不成立,就返回右边的值,左边为0则不成立,就返回10了。
ES6中,允许给函数参数默认值:
function fn(a,b=10){return a + b;}
在形参中直接写上b=10即可。
扩展运算符和Rest操作符都指的是...,根据上下文的语境不同,解析方式也不同。
将一个数组转为用逗号分隔的参数序列。
var arr = [1,2,3,4];console.log([...arr]); // [1,2,3,4]
把数组的每一项扩展到另一个数组中。
也可以从数组中找到最大值:
var arr = [1,2,3,4];console.log(Math.max(...arr)); // 会依次把数组的每一项传入到函数中
扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象中,相当于浅复制。
var arr = {a:1,b:2,c:3};console.log({...arr});
利用对象的属性是唯一的特性,后面定义的覆盖前面的属性,可以修改一个属性的值:
var arr = {a:1,b:2,c:3};console.log({...arr,a:'修改了'});
在使用解构赋值时,会把剩余的值,放在一个数组中:
var arr = [1,2,3,4];var [a,...b] = arr;console.log(a); // 1console.log(b); // [2,3,4]
如果是对象,会把剩余的属性放在新对象中:
var o = {a:1,b:2,c:3};var {a,...d} = o;console.log(a); // 1console.log(d); // {b:2,c:3}
在函数的形参中使用,会把剩余的形参都放在数组中:
function fn(a,...b){console.log(a); // 1console.log(b); // [2,3,4]}fn(1,2,3,4)
Rest操作符可取到arguments,把实参传入到一个数组中,而不是arguments类数组中:
function fn(...b){console.log(b); // [1,2,3,4]}fn(1,2,3,4)
注意,Rest操作符只能写在参数的最后,不能写在开头或中间,否则会报语法错误:
function fn(a,...b,c){console.log(a); //console.log(b);console.log(c)}fn(1,2,3,4); // Uncaught SyntaxError: Rest parameter must be last formal parameter
变量名和属性名相同,可直接写入变量名:
var a = 10;var b = 20;var o = {a,b}console.log(o); // {a:10,b:20}
定义函数可省略function关键字
var o = {fn(){}}
相当于:
var o = {fn: function () {}}
以上属于个人理解,如有偏差欢迎指正学习,谢谢。