JS变量作用域与解构赋值
用var变量是有作用域的
变量在函数内部声明时,那么该变量只属于整个函数体,函数外不可调用
当两个不同的函数里,使用了用一个相同的变量名,二者不互相影响,相互独立
遇到嵌套函数时,外部函数不可调用内部函数的变量,而内部函数可调用外部函数变量
当遇到同一变量时,也是同理,“就近原则”
变量提升
JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部
function test(){
var x = 'test, ' + y;
console.log(x);
var y = '2';
}
foo();
返回:
//test, undefined
打印并不会出错,这是因为此时,变量 y 已经被声明,当未被赋值
在引擎里面看到的代码
function test(){
var x;
var y;
x = 'test, ' + y;
console.log(x);
y = '2';
}
基于Javascript特性,我们在函数定义变量时,应该遵守,首先声明所有变量的规则
最常见的做法是用一个var申明函数内部用到的所有变量
function test(){
var x = 1, y = 2, z;
...
}
全局作用域
不在任何函数内定义的变量就具有全局作用域,全局作用域的变量会被绑到window的一个属性上
var course = 'Learn Js';
console.log(course); // 'Learn Js'
console.log(window.course); // 'Learn Js'
我们以前用变量定义函数,同样的,其也会成为全局变量
提升ReferenceError错误,是因为没有该变量
命名空间
为了避免使用了相同全局变量,造成命名冲突
我们把所有的变量和函数全部绑定到一个全局变量(对象)里
//唯一全局变量 myApp
var myApp = {};
//其他变量
myApp.name = 'Job';
myApp.edition = 1.0;
myApp.test = function(){
...
}
局部作用域
变量作用域在函数内部,但for等语句块无法定义其局部的作用域,所有可以被当前函数所调用
function test() {
for (var i = 0; i < 2; i++){
...
}
console.log(i); // 2
}
为了解决类似这样的问题,ES6标准引入了关键字let,功能和var一样,但let可以声明一个块级作用域变量
function test() {
for (let i = 0; i < 2; i++){
...
}
console.log(i); // ReferenceError 该作用域没有此变量
}
常量
在ES6标准之前,无法没有此功能,通常用变量整体大写来表示常量
var EDITION = 1.0;
ES6标准则引入关键字,const来定义常量,const与let一样具有块级作用
const edition = 1.0;
edition; // 1.0
解构赋值
ES6标准引入了解构赋值,可以同时对一组变量进行赋值
什么是解构赋值?
var array = ['Job', 'Steven', 'Ben'];
var x = array[0];
var y = array[1];
var z = array[2];
ES6演示
var [x, y, z] = ['Job', 'Steven', 'Ben'];
console.log('x = ' + x + ', y = ' + y + ', z = ' + z)
// x = Job, y = Steven, z = Ben
也可以选择解构赋值某一个值
var [, , z] = ['Job', 'Steven', 'Ben'];
z; // Ben
同样也可以获取对象属性
var person = {
name: 'Job',
age: 18,
school: 'No.1 school',
email: 'xxx.@xx.com'
};
var {name, age, email} = person;
console.log('name = ' + name + ', age = ' + age + ', email = ' + email);
// name = Job, age = 18, email = xxx.@xx.com
对嵌套的对象属性进行赋值时, 只要保证对应的层次是一致的
var person = {
name: 'Job',
age: 18,
school: 'No.1 school',
email: 'xxx.@xx.com'
address: {
city: 'Earch',
mail: 10001
}
};
var {name, address: {city, street}} = person;
name; // Job
city; // Earch
street; // undefined
解决解析赋值对应不存在问题
var {name, city: test} = person;
name; // Job
test; // Earch
这里的city并非变量,仅仅是把值赋给test
city; // ReferenceError
解构赋值也可以使用默认值
var {name, single = true} = person;
当变量被声明后,解析赋值所被赋值的变量则无效
// 声明变量
var x, y;
// 解构赋值
{x, y} = { name: '小明', x: 100, y: 200};
// 语法错误: SyntaxError
这是因为JavaScript引擎把{开头的语句当作了块处理,于是=不再合法。解决方法是用小括号括起来
({x, y} = { name: '小明', x: 100, y: 200});
这里暂时看不懂
使用场景
交换两个临时变量
var x=1, y=2;
[x, y] = [y, x]
快速获取当前页面域名和路径
var {hostname:main, pathname:path} = location;
JS变量作用域与解构赋值的更多相关文章
- JavaScript学习笔记(八)——变量的作用域与解构赋值
在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...
- ES6 (一)变量声明方法 & 解构赋值
就是最新的JavaScript 原来的是var,要求不严格,不能限制修改,函数级 es6要求严格 1.防止重复声明 let 变量=var const 常量 2.控制修改 const常量不能修 ...
- 001-es6变量声明、解构赋值、解构赋值主要用途
一.基本语法 1.1.声明变量的六种方法 参看地址:http://es6.ruanyifeng.com/#docs/let let:局部变量,块级作用域,声明前使用报错 var:全局变量,声明前使用 ...
- ES6知识整理(2)--变量的解构赋值
最近准备在业余空闲时间里一边学习ES6,一边整理相关知识.只有整理过的学习才是有效的学习.也就是学习之后要使用和整理成文,才是真正的学到了... 上一篇是一个试水,现在接上. 变量提升 看了下朋友回复 ...
- ES6学习随笔--字符串模板、解构赋值、对象、循环、函数、Promise、Generrator
在线编译器:babel.github 在nongjs中使用 'use strict' let a = ; 运行node : node --harmony_destructuring xxx.js 代码 ...
- ES6笔记(3)-- 解构赋值
系列文章 -- ES6笔记系列 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组.对象.字符串的解构赋值等 一.数组的解构赋值 function ids() { ret ...
- ES6解构赋值
前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程.本文将详细介绍ES6解构赋值 ...
- ES6 - Note2:解构赋值
ES6的解构赋值就是利用模式匹配从按照一定模式的数组或者对象中提取值赋值给变量. 1.数组的解构赋值 在ES6以前,变量的赋值是直接指定的,以后可以这么来写,如下所示 let [a,b,c] = [1 ...
- ES6-个人学习笔记二--解构赋值
第二期,解构赋值如果能够熟练应用确实是个十分方便的功能,但是过分的依赖和嵌套只会让代码理解和维护起来十分困难,是个体现高逼格的表达式呢~ 1,解构赋值的基础 //定义:es6运行按照一定模式,从数组或 ...
随机推荐
- zookeeper 回调和Watcher
ZooKeeper客户端可以对指定节点设置指定Watcher,当服务器指定节点发生变化是,客户端会收到服务器的通知,然后客户端可以执行相应Watcher的代码. 默认ZooKeeper内置了一个wat ...
- 【转】Locust性能-零基础入门系列(1)-wait_time属性用法
本篇文章,从局部出发,利用一个简单的测试,来说明场景模拟的wait_time属性的用法.wait_time为什么要单独拎出来讲,是因为它主要有两种模式,而初学者对这两种模式,容易混淆.1) wait_ ...
- gRPC-Protocol基础知识-C#篇
本文使用协议缓冲区语言的proto3版本,为C#程序员提供了使用协议缓冲区的基本介绍. 通过创建一个简单的示例应用程序,展示了如何 在.proto文件中定义消息格式. 使用协议缓冲区编译器. 使用C# ...
- Spring Boot 自动配置的原理、核心注解以及利用自动配置实现了自定义 Starter 组件
本章内容 自定义属性快速入门 外化配置 自动配置 自定义创建 Starter 组件 摘录:读书是读完这些文字还要好好用心去想想,写书也一样,做任何事也一样 图 2 第二章目录结构图 第 2 章 Spr ...
- OpenCV图像处理学习笔记-Day03
OpenCV图像处理学习笔记-Day03 目录 OpenCV图像处理学习笔记-Day03 第31课:Canny边缘检测原理 第32课:Canny函数及使用 第33课:图像金字塔-理论基础 第34课:p ...
- C#设计模式-适配器模式(Adapter Pattern)
概念 把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作.适配器模式有类的适配器模式和对象的适配器模式两种形式.前者类之间的耦合度比后者高,且要求程 ...
- 用JTable 实现日历
效果图: 主要思想:日历最核心的功能就是能显示某年某月对应的日期和星期几.因此只要实现传入具体的年份和月份,得到一组存放了日期的数组a[ ]即可.其中数组的大小设置成42,要考虑的问题是当月的第一天对 ...
- Python练习题 010:分解质因数
[Python练习题 010]将一个正整数分解质因数.例如:输入90,打印出90=2*3*3*5. -------------------------------------------------- ...
- 一种基于均值不等式的Listwise损失函数
一种基于均值不等式的Listwise损失函数 1 前言 1.1 Learning to Rank 简介 Learning to Rank (LTR) , 也被叫做排序学习, 是搜索中的重要技术, 其目 ...
- CF538B Quasi Binary 思维题
题目描述 给出一个数 \(n\),你需要将 \(n\) 写成若干个数的和,其中每个数的十进制表示中仅包含\(0\)和\(1\). 问最少需要多少个数 输入输出格式 输入格式: 一行 一个数 \(n(1 ...