ES6-10笔记(let&const -- Array)

摘要:
大纲范围范围是指在程序源代码中定义变量的区域,它指定如何查找变量,即确定当前执行的代码对变量的访问权限。JavaScript作用域有两种主要的工作模型:词法作用域(静态作用域)和动态作用域。默认情况下,JavaScript使用词法作用域,即静态作用域。词汇范围由开发人员在编写代码时编写变量和块范围的位置决定。全局范围、功能范围(本地
大纲
ES6-10笔记(let&const -- Array)第1张ES6-10笔记(let&const -- Array)第2张

scope-作用域

作用域是指程序源代码中定义变量的区域,规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

JavaScript作用域共有两种主要的工作模型——词法作用域(静态作用域)和动态作用域。

JavaScript默认采用词法作用域(lexical scoping),也就是静态作用域。

词法作用域是由开发者在写代码时将变量和块作用域写在哪里来决定的。由此出现全局作用域,函数作用域(局部作用域),块状作用域

动态作用域一般由this产生

注:1.如果一个变量或者表达式不在“当前的作用域”,那么JavaScript机制会继续沿着作用域链向上查找直到全局作用域(global或浏览器中的window)如果找不到将不判定为不可被使用。
    2.作用域也会根据代码层次分层,作用域之间形成父子关系,嵌套关系。子作用域可以访问父作用域。通常沿着链式的作用域链查找向上查找,而不能从父作用域引用访问子作用域的变量和引用

全局作用域

所有在全局作用域中声明的变量、函数都会变成window对象的属性和方法

变量在函数或者代码块{}外定义,即为全局作用域。一般可以在页面任何地方访问

var oneName = " Volvo";
// 此处可调用 oneName 变量
function myFunction() {
    // 函数内可调用 oneName 变量
}
if(true){
	//代码块内可调用oneName变量
}

在函数或者代码块{}内未定义的变量也拥有全局作用域。该变量将作为global或者window的属性存在

// 此处可调用 oneName 变量
function myFunction() {
     carName = "Volvo";
    // 函数内可调用 oneName 变量
}
if(true){
	//代码块内可调用oneName变量
}

注:在函数内部或者代码块中没有定义的变量实际上是作为global/window的属性存在,而不是全局变量。该变量是可以被delete掉,而全局变量不可以。因为通过var语句添加的全局变量有一个configcurable属性,默认值为false。可以通过Object.getOwnPropertyDescriptor(window,"...")查看

window对象上的属性在书写时可以省略window.

函数作用域(局部作用域)

在函数内部定义的变量对外是封闭的,从外层无法直接访问函数内部的作用域

function bar() {
  var testValue = 'inner';
}
console.log(testValue);		// 报错:ReferenceError: testValue is not defined

如果想读取函数内部的变量,必须借助return或者闭包

//使用return方式
function bar(value) {
  var testValue = 'inner';
  return testValue + value;
}
console.log(bar('fun'));		// "innerfun"

return 是函数对外交流的出口,而 return 可以返回的是函数,根据作用域的规则,函数bar内部的子函数inner是可以获取函数bar作用域内的变量result

//使用闭包方式
function bar(value) {
  var testValue = 'inner';
  var result = testValue + value;
  function innser() {
     return result;
  };
  return innser();
}
console.log(bar('fun'));	// "innerfun"

块状作用域

在其他编程语言中,块状作用域是很熟悉的概念,但是在JavaScript中不被支持。在ES6中已经有了{}块状作用域。

if(true){
  let a = 1
  console.log(a) //1
}
console.log(a) //a is not defined

注:事实上块状作用域在ES3就已经存在,只是不明显。比如catch块捕获的异常仅在catch块可见

词法作用域(静态作用域)与动态作用域

在javaScript采用词法作用域,执行foo函数,先从foo函数内部查找局部变量value,如果没有,就根据书写的位置,查找上面一层的代码,也就是value等于1,所以结果会打印1

var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2;
    foo();
}
bar();
// 结果是1

这里 bind 已经把作用域的范围进行了修改指向了 { a: 2 },而 this 指向的是当前作用域对象

window.a = 3
function test () {
  console.log(this.a)
}
test.bind({ a: 2 })() // 2
test() // 3

如果要开启动态作用域请借助 bind、with、eval 等。

let&Const

let&Const是ES6之后的语法。let拥有的特性Const都拥有。在ES6之后声明变量有6个方式var,function,let,const,import,class

var命令和function命令声明的全局变量依然是顶层对像(window/global)的成员。但let,const,class命令声明的全局变量,不在属于顶层对象的成员。从ES6开始全局变量将逐步与顶层对象的属性脱钩。

注:let和Const声明的变量去哪了?参考https://juejin.im/post/5c0be11b6fb9a049df23e388#heading-1

let

let声明的变量拥有块级作用域

{
  let a = 1
}
console.log(a); //undefined

let声明的全局变量不是全局对象的属性

不可以通过window变量名的方式访问这些变量,而var声明的全局变量是window的属性,是可以通过window变量名的访问

var a = 1
console.log(window.a); //1
let a = 1
console.log(window.a); // undefined

用let重定义变量会抛出一个语法错误,var可以重复定义。

var a = 1
var a = 2
console.log(a)  //2
let a = 1
let a = 2
// VM131:1 Uncaught SyntaxError: Identifier 'a' has already been declared
//   at <anonymous>:1:1

let声明的变量不会进行变量提升,存在暂时性死区(TDZ)。在死区结束前变量不会初始化,在这个区间即使是使用typeof()也会报错

function test () {
  console.log(a)
  var a = 1
}
test() //undefined
function test () {//TDZ开始
  console.log(a)// Cannot access 'a' before initialization
  typeof(a)// Cannot access 'a' before initialization
  ...
  ...
  let a = 1 //TDZ结束
}
test()
// Uncaught ReferenceError: Cannot access 'a' before initialization

const

Const除了具有let的块级作用域和不会变量,并且它定义的常量,在用const定义变量后,就不能修改。对其修改会抛出异常

const PI = 3.1415;
console.log(PI);
PI = 22;
console.log(PI);
// Uncaught TypeError: Assignment to constant variable.

const声明的变量必须进行初始化,否则会抛出异常Uncaught SyntaxError: Missing initializer in const declaration

const PI
PI = 3.1415
// Uncaught SyntaxError: Missing initializer in const declaration

Array

ES6新增了一些实用的原生API,方便开发者对Array的操控性更强。

ES5操作数组的方法 concat、join、push、pop、shift、unshift、slice、splice、substring 和 substr 、sort、 reverse、indexOf 和 lastIndexOf 、every、some、filter、map、forEach、reduce

ES6新增操作数组的方法 find、findIndex、fill、copyWithin、Array.from、Array.of、entries、values、key、includes

围绕数组产生的动作无非是遍历,转换,生成,查找。。。。。。(数据库增删改查一样一样的)

数组遍历的方法有很多例如for循环,forEach,every,for...in,for...of等等

数组的遍历

举几个例子

for循环

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

forEach

forEach ( ) 方法。等同于for,不支持break;continue,会抛出异常

forEach()对于空数组是不会执行回调函数的

array.forEach(function(i){
  console.log(i);
})
[1,2,3,4,5].forEach(function(i){
    if(i===2){
    	return;
    }else{
    	console.log(i) //1,3,4,5
    }
})

every

every()方法遍历可以达到break效果。

every的代码块种仍然不能使用break,continue,会抛出异常

[1,2,3,4,5].every(function(i){
  if(i===2){
    return false; //return false等同于break
  }else{
    console.log(i)
    return true  // return true 等同于continue
  }
})

for...in

for... in 的目的是用来遍历对象,而数组刚好是可遍历对象。。。

for (var index in array) {
	//index是索引值,是字符串
  console.log(array[index]);
}

for...of

for…of是支持 break、continue的,所以在功能上非常贴近原生的 for。

for…of 遍历的是一切可遍历的元素(数组、对象、集合)等。ES6 中允许开发者自定义遍历

for (variable of iterable) {}

variable:每个迭代的属性值被分配给该变量

iterable:一个具有可枚举属性并且可以迭代的对象

数组转换功能

伪数组 具有length属性; 按索引方式存储数据; 不能调用数组的方法

ES5伪数组转换为数组

let args = [].slice.call(arguments)

let imgs= [].slice.call(document.querySelectorAll('img'))//NodeList

ES6伪数组转换为数组

let args = Array.from(arguments)

let imgs = Array.from(document.querySelectorAll('img'))

Array.from(arrayLike,mapFn,thisArg)
//arrayLike 必选  想要转换成数组的伪数组对象或可迭代对象
//mapFn  可选  新数组中的每个元素会执行该回调函数
//thisArg 可选 执行回调函数 mapFn 时 this 对象

数组的生成

ES5初始化一个长度为5的数组,每个数组元素有默认值

Array.from({ length: 5 }, function () { return 1 })

ES6初始化一个长度为5的数组,每个数组元素有默认值

Array.prototype.from()方法

Array.from({ length: 5 }, function () { return 1 })

Array.prototype.of()方法

Array.of(element0[, element1[, ...[, elementN]]])  
elementN  任意个参数,将按顺序成为返回数组中的元素。
Array.of(7);       // [7] 
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

Array.prototype.fill()方法

fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

let array = [1, 2, 3, 4]
array.fill(0, 1, 2)
// [1,0,3,4]

arr.fill(value[, start[, end]])
value 必选 用来填充数组元素的值
start 可选 起始索引,默认值为0
end 可选 终止索引,默认值为this.length

数组的查找

ES6新增查找方法find(),findIndex()

Array.prototype.find()方法

find() 方法返回数组中满足提供的测试函数的第一个元素的值,否则返回 undefined。

let array = [5, 12, 8, 130, 44];
let found = array.find(function(element) {
  return element > 10;
});
console.log(found);// 12
array.find(function(currentValue, index, arr),thisValue)
//function(currentValue, index, arr) 在数组每一项上执行的函数
//currentValue 当前遍历到的元素
//index 当前遍历到的索引
//array 数组本身
//thisArg 执行回调时用作this的对象

Array.prototype.findIndex()方法
findIndex()方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。其实这个和 find() 是成对的,不同的是它返回的是索引而不是值

免责声明:文章转载自《ES6-10笔记(let&amp;amp;const -- Array)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MyCat 学习笔记 第十二篇.数据分片 之 分片事务处理Hadoop_24_MapReduce实现QQ共同好友下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

c/c++中变量的作用域

作用域规则告诉我们一个变量的有效范围,它在哪儿创建,在哪儿销毁(也就是说超出了作用域)。变量的有效作用域从它的定义点开始,到和定义变量之前最邻近的开括号配对的第一个闭括号。也就是说,作用域由变量所在的最近一对括号确定。 (1) 全局变量:    全局变量是在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)都可以使用。全局变量不受作用域的影响...

【js重学系列】作用域

作用域 在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。 在 Javascript 中,作用域分为 全局作用域 和 函数作用域 什么是作用域呢,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。 全局变量 变量在函数外定义,即为全局变量。 全局变量有 全局作用域: 网页中所有脚本和函数均可使...

C#程序员开发WinForm必须知道的 Window 消息大全(转)

消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。 消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。这个记录类型叫做TMsg,它在Windows...

Thinkphp的Volist标签

Volist标签主要用于在模板中循环输出数据集或者多维数组。 volist标签(循环输出数据) 闭合 非闭合标签 属性 name(必须):要输出的数据模板变量 id(必须):循环变量 offset(可选):要输出数据的offset length(可选):输出数据的长度 key(可选):循环的key变量,默认值为i mod(可选):对key值取模,...

FFmpeg解码H264及swscale缩放详解

原文  http://blog.csdn.net/gubenpeiyuan/article/details/19548019 主题 FFmpeg 本文概要:         本文介绍著名开源音视频编解码库ffmpeg如何解码h264码流,比较详细阐述了其h264码流输入过程,解码原理,解码过程。同时,大部分应用环境下,以原始码流视频大小展示并不是...

使用Pls_Integer的好处

如果你要做循环的记数器,可以使用pls_integer. pls_interger,binary_integer,number中,pls_integer速度最快。   转的别人的: Binary_Integer 与 Pls_Integer 都是整型类型. Binary_Integer类型变量值计算是由Oracle来执行,不会出现溢出,但是执行速度较慢,因为...