ES6实训报告

ES6实训报告

let和const的用法?

var关键字的缺点

以往在JavaScript中,定义变量通常使用的var关键词,由于JavaScript的变量提升机制,导致var变量无论在何处声明,都会被提升到当前作用域的顶部。

例如:

function getNumber(isNumber) {
  if (isNumber) {
    var num = "7";
  } else {
    var notNum = "not number!";
    console.log(num);
  }
}
getNumber(false);

以上的代码在函数体中使用var声明了变量num和notNum,由于变量提升机制,变量提升到当前作用域的顶部,控制台报错变量未定义。

变量提升后代码:

function getNumber(isNumber) {
  var num;
  var notNum;
  if (isNumber) {
    num = "7";
  } else {
    notNum = "not number!";
    console.log(num);
  }
}
getNumber(false);

由此可见,当传入参数为false时,num变量未被复制,因此控制台输出undefined

与此同时,var关键字声明的变量可以重复赋值,但在某些情况下会造成一些问题,例如:

function Sum(arrList) {
  var sum = 0;
  for (var i = 0; i < arrList.length; i++) {
    var arr = arrList[i];
    for (var i = 0; i < arr.length; i++) {
      sum += arr[i];
    }
  }
  return sum;
}
var arr = [1, 2, 3, 4, 5];
document.write(Sum(arr));

上述代码如果运行,将会卡死。因为在两层for循环中,我们使用了同一变量i进行赋值,代码在执行过程中,第二层的for循环会覆盖外层变量i的值,导致i的值重复赋值为1,程序进入死循环状态。

使用 var 关键字定义的变量只有两种作用域,全局作用域和函数作用域,两者均不是块结构,会造成变量声明的提升。这可能出现下面这种问题:

function func() {
  for (var i = 0; i < 5; i++) {}
  document.write(i); // 5
}
func();

运行上述代码后,你会发现页面上会显示 5。我们虽然是在 for 循环中定义的 i 变量,但由于变量被提升到 for 语句之上,所以退出循环后,变量 i 并没有被销毁,我们能够在循环外获取它的值。

因此在ES6语法中新增let关键字和和const关键字,来弥补var关键字的不足之处。

let关键字的使用

解决变量提升机制问题

let的作用域是块,解决了变量提升到作用域顶部的问题。

function getNumber(isNumber) {
  if (isNumber) {
    let num = "7";
  } else {
    let notNum = "not number!";
    console.log(num);
  }
}
getNumber(false);

执行如上代码:控制台报错num变量不存在。

原因:let关键字声明的变量作用域是一个块,在上述代码中,num所在作用域是if{}花括号块中,因此在else{}块中无法访问到num变量。

解决变量重复声明问题

虽然 let 关键字声明的变量可以重新赋值,但是它与 var 关键字有所不同,let 关键字不能在同一作用域内重新声明,而 var 可以。

例如:

let i = 5;
let i = 6;
console.log(i);

控制台报错:i变量已经被定义。

然而在不同作用域内:

function Sum(arrList) {
  var sum = 0;
  for (let i = 0; i < arrList.length; i++) {
    var arr = arrList[i];
    for (let i = 0; i < arr.length; i++) {
      sum += arr[i];
    }
  }
  return sum;
}
var arr = [1, 2, 3, 4, 5];
document.write(Sum(arr));

此时代码正常运行,因为i的作用域在不同作用域块中。因此在for循环中比较适合使用let关键字

解决非块级作用域的问题

var关键字定义变量,只有两种作用域:

  • 函数作用域
  • 全局作用域

而这两种作用域都是非块级作用域

let关键字定义的变量是块级作用域,避免了变量提升。

function func() {
  for (let i = 0; i < 5; i++) {}
  console.log(i);
}
func();

在上段代码中控制台报错:i is not defined

因为let声明的变量i作用域仅在for循环的块中,当循环结束时i即被销毁。因此在for循环之外不能访问到变量i

const关键字的使用

在ES6中,提供了关键字const用于声明一个只读的变量,变量一旦声明,值就不会被改变,如果反复赋值则会报错。并且需要在定义时就对变量进行初始化。

对于 const 关键字定义的变量值,不可改变在于两个方面:

  1. 值类型:

    值类型是指变量直接存储的数据:

    const num = 20;
    

    此处的num变量就是值类型,因为定义num变量的关键字是const,因此变量num的值是不可变的

  2. 引用类型:

    引用类型是指变量存储数据的引用,而数据是放在数据堆中,比如,用 const 声明一个数组:

    const arr = ["一", "二", "三"];
    

    此时,如果尝试修改数组,同样会报错。但是可以通过数组下标来对数组进行修改。

    因为数组中保存的是数组的引用,并不是数组中的值。只要引用的地址不发生变化,程序就不会报错。

    const arr = ["一", "二", "三"];
    arr[0] = "四";
    arr[1] = "五";
    arr[2] = "六";
    
    console.log(arr);
    

数组,对象和字符串解构赋值如何使用?

数组解构赋值

在es6之前,为变量赋值:

let a = 1;
let b = 2;
let c = 3;

在es6后允许写成这样:

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

对象解构赋值

解构不仅可以用于数组,还可以用于对象。

let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
console.log(foo);
console.log(bar);

let { baz } = { foo: 'aaa', bar: 'bbb' };
console.log(baz );// undefined

字符串解构

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"

可以发现此时将hello字符串的单字符赋值给了abcde

字符串模板如何使用?

模板字面量的基本用法

模板字面量:在JavaScript中,字面量代表由一些字符串组成表达式定义的常量。

在ES6之前,使用''""包裹字符串。

在ES6中提高了反引号``来包裹字符串,可以简化解决多行字符串字符串占位符的问题。

多行字符串的处理

当处理多行文字时,在ES6之前,通常使用转义符\n进行转换:

console.log('java/nscript')

但是遇到需要多次换行的字符串,需要手动加入转义符,操作麻烦。

因此在ES6语法中,使用反引号``包裹字符串,定义在字符串中的空格、缩进和换行都会保留,不用认为加入转义符,简化了操作。

字符串占位符

在ES6之前,需要将变量和字符串放在一起输出时,通常采取+来进行拼接,例如:

let a = 2;
let b = 4;
console.log("a = " + a + ", b = " + b + ", sum = " + (a + b));

由上述代码,可以看出该操作麻烦且容易出错。

因此在ES6中可以使用新增的反引号,在字符串中嵌入变量。字符串${变量名}字符串

let a = 2;
let b = 4;
console.log(`a=${a},b=${b},sum=${a+b}`);

将该代码与第一段代码比较,可以发现写法更为简单,易读性更强。

字符串模块调用函数

const sayHello = function () { 
return 'hi 你好';
}; 
let str1 = `${sayHello()} OK Ok`; 
console.log(str1);//hi 你好 OK Ok

展开运算符如何使用?

扩展运算符(...)是ES6新语法,它可以将可迭代对象的参数在语法层面上进行展开。

语法格式:

// 在数组中的使用
let VariableName = [...value];

例如:

  • 将字符串转为数组:

    let str = 'abcd';
    const arr = [...str]
    console.log(arr);//['a', 'b', 'c', 'd']
    
  • 合并数组

    let arr1 = [1,2,3]
    let arr2 = [4,5,6]
    let arr3 = [...arr1,...arr2]
    console.log(arr3) //[1, 2, 3, 4, 5, 6]
    

对象上,我们主要有以下三种操作:

  • 可以使用扩展运算符将一个对象的全部属性插入到另一个对象中,来创建一个新的对象。

    let student = { name: "小白", age: 17, email: "1234@qq.com" };
    let NewObj = { ...student };
    console.log(NewObj);
    
  • 可以使用扩展运算符给对象添加属性。

    let student = { name: "小白", age: 17, email: "1234@qq.com" };
    let NewObj = { ...student, id: 7 };
    console.log(NewObj);
    
  • 可以使用扩展运算符合并两个新对象。

    let studentName = { name: "小白" };
    let studentAge = { age: 17 };
    let NewObj = { ...studentName, ...studentAge };
    console.log(NewObj);
    

剩余参数如何使用?

rest参数又称为剩余参数,用于获取函数的多余参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

rest参数和扩展运算符在写法上一样,都是(...),但是两者的使用上截然不同

扩展运算符就像是 rest 参数的逆运算,主要用于以下几个方面:

  • 改变函数的调用。
  • 数组构造。
  • 数组解构。

rest参数的语法格式:

// 剩余参数必须是函数的最后一个参数
myfunction(parameters, ...rest);

例如:

function add(a,...args){
    console.log(a);//10
    console.log(args);//数组[20,30]
} 

add(10,20,30)

剩余参数和解构配合使用

let students = ['wangwu', 'zhangsan', 'lisi'];
let [s1, ...s2] = students; 
console.log(s1); // 'wangwu' 
console.log(s2); // ['zhangsan', 'lisi']

箭头函数如何使用?

箭头函数,就是用=>来表示函数。箭头函数和普通函数都是用来定义函数的,但是在语法构成上不同,

普通函数语法:

let sum = function (a, b) {
  return a + b;
};
console.log(sum(1, 2));

箭头函数语法:

let sum = (a,b)=>a+b;
console.log(sum(1,2));

箭头函数除了代码简洁以外,还解决了匿名函数的this指向问题。

在箭头函数中,this指向的时该函数所在的作用域所指向的对象,而不是使用所在作用域指向的对象。

而普通法函数的this指向调用该函数的对象。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值