美文网首页
JavaScript | 变量作用域与解构赋值

JavaScript | 变量作用域与解构赋值

作者: shawn233 | 来源:发表于2018-08-31 12:44 被阅读0次

Reference : JavaScript教程 - 廖雪峰的官方网站

原文变量作用域与解构赋值 - 廖雪峰的官方网站

变量作用域

  • 在函数体中用var申明的变量:整个函数体,建议将var申明放到函数体的开头
function foo() {
    var
        x = 1,
        y = x + 1,
        z, i;
    for (i = 0; i < 100; i++) {
        // ...
    }
}
  • 不在任何函数内定义的变量具有全局作用域,可以通过全局对象window获取。所有全局变量被绑定为window的属性

  • 由于全局变量都在一个window对象上,当涉及到多个js文件时,容易出现命名冲突,且很难发现。解决这个问题的办法是引入名字空间。定义一个全局对象作为名字空间,并把文件内的变量和函数绑定到这个对象上,例如:

// 唯一的全局变量MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
    return 'foo';
};

这个办法也是许多著名的JavaScript库的做法,如jQuery, YUI等。

  • let申明的变量是块级变量,作用域仅存在于申明的语句块内,如以下语句
'use strict'

for (let i = 0; i < 100; i ++) {
    sum += i;
}
i += 1; // Syntax error
  • const申明的是常量,对const申明的常量进行赋值也许不会报错,但一定不会修改常量的值。常量的作用域与let申明相同,仅在申明的块内有效

解构赋值 [ES6]

解构赋值是一种对一组变量进行赋值的方法。

  1. 数组类型,注意等号左侧的变量要用[...]括起来
'use strict'

var [x, y, z] = ['hello', 'JavaScript', 'ES6'];
// x, y, z 分别被赋值为数组对应元素

还可以忽略数组中的某些元素

let [, , z] = ['hello', 'JavaScript', 'ES6']; // 忽略前两个元素
z; // 'ES6'
  1. 对象类型
'use strict';

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school'
};
var {name, age, passport} = person;
// name, age, passport分别被赋值为对应属性:
console.log('name = ' + name + ', age = ' + age + ', passport = ' + passport);

Output:

name = 小明, age = 20, passport = G-12345678

对一个对象进行解构赋值时,同样可以直接对嵌套的对象属性进行赋值,只要保证对应的层次是一致的:

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school',
    address: {
        city: 'Beijing',
        street: 'No.1 Road',
        zipcode: '100001'
    }
};
var {name, address: {city, zip}} = person;
name; // '小明'
city; // 'Beijing'
zip; // undefined, 因为属性名是zipcode而不是zip
// 注意: address不是变量,而是为了让city和zip获得嵌套的address对象的属性:
address; // Uncaught ReferenceError: address is not defined

使用解构赋值对对象属性进行赋值时,如果对应的属性不存在,变量将被赋值为undefined,这和引用一个不存在的属性获得undefined是一致的。如果要使用的变量名和属性名不一致,可以用下面的语法获取:

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678',
    school: 'No.4 middle school'
};

// 把passport属性赋值给变量id:
let {name, passport:id} = person;
name; // '小明'
id; // 'G-12345678'
// 注意: passport不是变量,而是为了让变量id获得passport属性:
passport; // Uncaught ReferenceError: passport is not defined

解构赋值还可以使用默认值,这样就避免了不存在的属性返回undefined的问题:

var person = {
    name: '小明',
    age: 20,
    gender: 'male',
    passport: 'G-12345678'
};

// 如果person对象没有single属性,默认赋值为true:
var {name, single=true} = person;
name; // '小明'
single; // true

有些时候,如果变量已经被声明了,再次赋值的时候,正确的写法也会报语法错误:

// 声明变量x, y
var x, y;
// 对已经声明过的x, y进行解构赋值:
{x, y} = { name: '小明', x: 100, y: 200};
// 语法错误: Uncaught SyntaxError: Unexpected token =

这是因为JavaScript引擎把{开头的语句当作了块处理,于是=不再合法。解决方法是用小括号括起来:

({x, y} = { name: '小明', x: 100, y: 200});

使用场景

解构赋值在很多时候可以大大简化代码。例如,交换两个变量x和y的值,可以这么写,不再需要临时变量:

var x=1, y=2;
[x, y] = [y, x]

快速获取当前页面的域名和路径:

var {hostname:domain, pathname:path} = location;
domain;
path;

如果一个函数接收一个对象作为参数,那么,可以使用解构直接把对象的属性绑定到变量中。例如,下面的函数可以快速创建一个Date对象:

function buildDate({year, month, day, hour=0, minute=0, second=0}) {
    return new Date(year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second);
}

使用解构赋值可以减少代码量,但是,需要在支持ES6解构赋值特性的现代浏览器中才能正常运行。目前支持解构赋值的浏览器包括Chrome,Firefox,Edge等。

相关文章

网友评论

      本文标题:JavaScript | 变量作用域与解构赋值

      本文链接:https://www.haomeiwen.com/subject/iueswftx.html