- 浏览: 7960866 次
- 性别:
- 来自: 广州
-
文章分类
- 全部博客 (2425)
- 软件工程 (75)
- JAVA相关 (662)
- ajax/web相关 (351)
- 数据库相关/oracle (218)
- PHP (147)
- UNIX/LINUX/FREEBSD/solaris (118)
- 音乐探讨 (1)
- 闲话 (11)
- 网络安全等 (21)
- .NET (153)
- ROR和GOG (10)
- [网站分类]4.其他技术区 (181)
- 算法等 (7)
- [随笔分类]SOA (8)
- 收藏区 (71)
- 金融证券 (4)
- [网站分类]5.企业信息化 (3)
- c&c++学习 (1)
- 读书区 (11)
- 其它 (10)
- 收藏夹 (1)
- 设计模式 (1)
- FLEX (14)
- Android (98)
- 软件工程心理学系列 (4)
- HTML5 (6)
- C/C++ (0)
- 数据结构 (0)
- 书评 (3)
- python (17)
- NOSQL (10)
- MYSQL (85)
- java之各类测试 (18)
- nodejs (1)
- JAVA (1)
- neo4j (3)
- VUE (4)
- docker相关 (1)
最新评论
-
xiaobadi:
jacky~~~~~~~~~
推荐两个不错的mybatis GUI生成工具 -
masuweng:
(转)JAVA获得机器码的实现 -
albert0707:
有些扩展名为null
java 7中可以判断文件的contenttype了 -
albert0707:
非常感谢!!!!!!!!!
java 7中可以判断文件的contenttype了 -
zhangle:
https://zhuban.me竹板共享 - 高效便捷的文档 ...
一个不错的网络白板工具
http://www.zcfy.cc/article/465
首页 登录/注册
首页
在译
问答
排行
归档
loveky
详解JavaScript变量提升
loveky · 2016-06-12翻译 · 374阅读 原文链接
变量在程序中随处可见。它们是一些始终在相互影响,相互作用的的数据和逻辑。正是这些互动使应用程序活了起来。
在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被你的代码使用。如果你在寻找关于这方面的详细介绍,那你算是来对地方了。让我们一起看看吧。
1. 简介
提升是一种将变量和函数的声明移到函数作用域(如果不在任何函数内的话就是全局作用域)最顶部的机制。
提升影响了变量的生命周期,一个变量的生命周期包含3个阶段:
声明 - 创建一个新变量,例如var myValue
初始化 - 用一个值初始化变量 例如myValue = 150
使用 - 使用变量的值 例如alert(myValue)
这个过程通常是像这样执行的:首先声明一个变量,然后用一个值给它初始化,最后就是使用它。让我们看一个例子:
在JS Bin上查看
// 声明
var strNumber;
// 初始化
strNumber = '16';
// 使用
parseInt(strNumber); // => 16
在程序中一个函数可以先声明,后使用。初始化被忽略掉了。例如:
在JS Bin上查看
// 声明
function sum(a, b) {
return a + b;
}
// 使用
sum(5, 6); // => 11
当这三个步骤按顺序执行的时候,一切看起来都很简单,自然。如果可以话,在使用JavaScript编程的时候你应该遵循这种模式。
JavaScript并没有严格遵循这个顺序,因此提供了更多的灵活性。比如,函数的使用可以在声明之前。下边的例子先调用了函数double(5),然后才声明该函数function double(num) {...}:
在JS Bin上查看
// 使用
double(5); // => 10
// 声明
function double(num) {
return num * 2;
}
这是因为JavaScript中的函数声明会被提升到作用域顶部。
变量提升在不同方面的影响也不同:
变量声明: 使用var, let或const关键字
函数声明: 使用function () {...}语法
类声明: 使用class关键字
接下来让我们详细看看这些区别。
2. 函数作用域变量: var
变量声明在函数作用域内创建并初始化一个变量,例如var myVar, myVar2 = 'Init'。默认情况下,声明但是未初始化的变量的值是undefined。
自从JavaScript的第一版本开始,开发者就在使用这种方式声明变量。
在JS Bin上查看
// 声明变量num
var num;
console.log(num); // => undefined
// 声明并初始化变量str
var str = 'Hello World!';
console.log(str); // => 'Hello World!'
提升与var
使用var声明的变量会被提升到所在函数作用域的顶部。如果在声明之前访问该变量,它的值会是undefined。
假定myVariable在被var声明前被访问到。在这种情况下,声明操作会被移至double()函数的顶部同时该变量会被赋值undefined:
在JS Bin上查看
function double(num) {
console.log(myVariable); // => undefined
var myVariable;
return num * 2;
}
double(3); // => 6
JavaScript在执行代码时相当于把var myVariable移动到了double()的顶部,就像下面这样:
在JS Bin上查看
function double(num) {
var myVariable; // 被移动到顶部
console.log(myVariable); // => undefined
return num * 2;
}
double(3); // => 6
var语法不仅可以声明变量,还可以在声明的同时赋给变量一个初始值:var str = 'initial value'。当变量被提升时,声明会被移动到作用域顶部,但是初始值的赋值却会留在原地:
在JS Bin上查看
function sum(a, b) {
console.log(myString); // => undefined
var myString = 'Hello World';
console.log(myString); // => 'Hello World'
return a + b;
}
sum(16, 10); // => 26
var myString被提升到作用域的顶部,然而初始值的赋值操作myString = 'Hello World'不会受到影响。上边的代码等价于下边的形式:
在JS Bin上查看
function sum(a, b) {
var myString; // 提升到顶部
console.log(myString); // => undefined
myString = 'Hello World'; // 赋值不受影响
console.log(myString); // => 'Hello World'
return a + b;
}
sum(16, 10); // => 26
3. 块级作用域变量: let
let声明在块级作用域内创建并初始化一个变量:let myVar, myVar2 = 'Init'。默认情况下,声明但是未初始化的变量的值是undefined。
let是ECMAScript 6引入的一个巨大改进,它允许代码在代码块的级别上保持模块性和封装性:
在JS Bin上查看
if (true) {
// 声明块级变量
let month;
console.log(month); // => undefined
// 声明并初始化块级变量
let year = 1994;
console.log(year); // => 1994
}
// 在代码块外部不能访问month和year变量
console.log(year); // ReferenceError: year is not defined
提升与let
使用let定义的变量会被提升到代码块的顶部。但是如果在声明前访问该变量,JavaScript会抛出异常ReferenceError: is not defined。
在声明语句一直到代码库的顶部,变量都好像在一个临时死亡区间中一样,不能被访问。
让我们看看以下的例子:
在JS Bin上查看
function isTruthy(value) {
var myVariable = 'Value 1';
if (value) {
/**
* myVariable的临时死亡区间
*/
// Throws ReferenceError: myVariable is not defined
console.log(myVariable);
let myVariable = 'Value 2';
// myVariable的临时死亡区间至此结束
console.log(myVariable); // => 'Value 2'
return true;
}
return false;
}
isTruthy(1); // => true
从let myVariable一行一直到代码块开始的if (valaue) {...}都是myVariable变量的临时死亡区间。如果在此区间内访问该变量,JavaScript会抛出ReferenceError异常。
一个有趣的问题出现了:myVariable真的被提升到代码块顶部了吗?还是在临时死亡区间内未定义呢?当一个变量未被定义时,JavaScript也会抛出ReferenceError。
如果你观察一下该函数的开始部分就会发现,var myVariable = 'Value 1'在整个函数作用域内定义了一个名为myVariable的变量。在if (value) {...}块内,如果let定义的变量没有被提升,那么在临时死亡区间内myVariable的值就会是'Value1'了。由此我们可以确认块级变量确实被提升了。
let在块级作用域内的提升保护了变量不受外层作用域影响。在临时死亡区间内访问let定义的变量时抛出异常会促使开发者遵循更好的编码实践:先声明,后使用。
这两个限制是促使在封装性和代码流程方面编写更好的JavaScript的有效途径。这是基于var用法教训的结果 —— 允许在声明之前访问变量很容易造成误解。
4. 常量: const
常量声明在块级作用域内创建并初始化一个常量:const MY_CONST = 'Value', MY_CONST2 = 'Value 2'。看看下边的示例:
在JS Bin上查看
const COLOR = 'red';
console.log(COLOR); // => 'red'
const ONE = 1, HALF = 0.5;
console.log(ONE); // => 1
console.log(HALF); // => 0.5
当声明一个变量时,必须在同一条语句中对该变量进行初始化。在声明与初始化之后,变量的值不能被修改。
在JS Bin上查看
const PI = 3.14;
console.log(PI); // => 3.14
PI = 2.14; // TypeError: Assignment to constant variable
提升与const
使用const定义的常量会被提升到代码块的顶部。
由于存在临时死亡区间,常量在声明之前不能被访问。如果在声明之前访问常量,JavaScript会抛出异常:ReferenceError: is not defined。
const声明常量的提升的效果与使用let声明变量的提升效果相同。
让我们在double()函数内声明一个常量:
在JS Bin上查看
function double(number) {
// 常量TWO的临时死亡区间
console.log(TWO); // ReferenceError: TWO is not defined
const TWO = 2;
// 常量TWO的临时死亡区间至此结束
return number * TWO;
}
double(5); // => 10
由于在声明之前使用常量会导致JavaScript抛出异常。因此使用常量时应该始终先声明,初始化,然后再使用。
5. 函数声明
函数声明使用提供的名称和参数创建一个函数。
一个函数声明的例子:
在JS Bin上查看
function isOdd(number) {
return number % 2 === 1;
}
isOdd(5); // => true
function isOdd(number) {...}就是一段定义函数的声明。isOdd()用来验证一个数字是否是奇数。
提升与函数声明
函数声明的提升允许你在所属作用域内任何地方使用该函数,即使是在声明之前也可以。换句话说,函数可以在当前作用域或子作用域内的任何地方访问(不会是undefined值,没有临时死亡区间,不会抛出异常)。
这种提升的行为非常灵活。不管是先使用,后声明,还是先声明,后使用都可以如你所愿。
下边的例子在开始的地方调用了一个函数,然后才定义它:
在JS Bin上查看
// 调用被提升的函数
equal(1, '1'); // => false
// 函数声明
function equal(value1, value2) {
return value1 === value2;
}
这段代码可以正常执行是因为equal()被提升到了作用域顶部。
需要注意的函数声明function () {...}和函数表达式 var = function() {...}之间的区别。两者都用于创建函数,但是却有着不同的提升机制。
下边的例子演示了该区别:
在JS Bin上查看
// 调用被提升的函数
addition(4, 7); // => 11
// 变量被提升了,但值是undefined
substraction(10, 7); // TypeError: substraction is not a function
// 函数声明
function addition(num1, num2) {
return num1 + num2;
}
// 函数表达式
var substraction = function (num1, num2) {
return num1 - num2;
};
addition被彻底的提升并且可以在声明之前被调用。
然而substraction是使用变量声明语句声明的,虽然也被提升了,但被调用时值是undefined。因此会抛出异常TypeError: substraction is not a function。
6. 类声明
类声明使用提供的名称和参数创建一个构造函数。类是ECMAScript 6中引入的一项巨大改进。
类建立在JavaScript的原型继承之上并提供了诸如super(访问父类),static(定义静态方法),extends(定义子类)之类的额外功能。
一起看看如何声明一个类并创建一个实例:
在JS Bin上查看
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
move(dX, dY) {
this.x += dX;
this.y += dY;
}
}
// 创建实例
var origin = new Point(0, 0);
// 调用实例的方法
origin.move(50, 100);
提升与class
类声明会被提升到块级作用域的顶部。但是如果你在声明前使用类,JavaScript会抛出异常ReferenceError: is not defined。所以正确的方法是先声明类,然后再使用它创建实例。
类声明的提升与let定义变量的提升效果类似。
让我们看看在声明之前创建类实例会怎样:
在JS Bin上查看
// 使用Company类
// 抛出ReferenceError: Company is not defined
var apple = new Company('Apple');
// 类声明
class Company {
constructor(name) {
this.name = name;
}
}
// 在声明之后使用Company类
var microsoft = new Company('Microsoft');
和预期的一样,在类定义之前执行new Company('Apple')会抛出ReferenceError异常。这很不错,因为JavaScript鼓励先声明后使用的方式。
还可以用使用了变量声明语句(var,let和const)的类表达式创建类。让我们看看下面的场景:
在JS Bin上查看
// 使用Sqaure类
console.log(typeof Square); // => 'undefined'
//Throws TypeError: Square is not a constructor
var mySquare = new Square(10);
// 使用变量声明语句声明类
var Square = class {
constructor(sideLength) {
this.sideLength = sideLength;
}
getArea() {
return Math.pow(this.sideLength, 2);
}
};
// 在声明之后使用Square类
var otherSquare = new Square(5);
这个类使用变量声明语句var Square = class {...}定义。Square变量被提升到了作用域的顶部,但是直到声明该变量的这行代码之前其值都是undefined。因此var mySquare = new Square(10)语句相当于把undefined当作构造函数使用,这导致JavaScript抛出TypeError: Square is not a constructor异常。
7. 最后的想法
像在本文阐述的那样,JavaScript中的提升有多种形式。即使你知道它的工作方式,一般还是建议按照声明 > 初始化 > 使用的顺序使用变量。通过let,const和class提升的方式可以看出ECMAScript 6强烈支持这种使用方式。这将使你免于遇见不期望的变量,undefined以及ReferenceError的困扰。
有一种函数可以在定义之前执行的例外情况。这就是当开发者需要快速了解函数如何被调用的时候,因为这样就不必再滚动到底部阅读函数的具体实现方式了。
例如,这篇文章解释了这种方式是如何增加Angular controllers代码的可读性的。
首页 登录/注册
首页
在译
问答
排行
归档
loveky
详解JavaScript变量提升
loveky · 2016-06-12翻译 · 374阅读 原文链接
变量在程序中随处可见。它们是一些始终在相互影响,相互作用的的数据和逻辑。正是这些互动使应用程序活了起来。
在JavaScript中使用变量很重要的一方面就是变量的提升 —— 它决定了一个变量何时可以被你的代码使用。如果你在寻找关于这方面的详细介绍,那你算是来对地方了。让我们一起看看吧。
1. 简介
提升是一种将变量和函数的声明移到函数作用域(如果不在任何函数内的话就是全局作用域)最顶部的机制。
提升影响了变量的生命周期,一个变量的生命周期包含3个阶段:
声明 - 创建一个新变量,例如var myValue
初始化 - 用一个值初始化变量 例如myValue = 150
使用 - 使用变量的值 例如alert(myValue)
这个过程通常是像这样执行的:首先声明一个变量,然后用一个值给它初始化,最后就是使用它。让我们看一个例子:
在JS Bin上查看
// 声明
var strNumber;
// 初始化
strNumber = '16';
// 使用
parseInt(strNumber); // => 16
在程序中一个函数可以先声明,后使用。初始化被忽略掉了。例如:
在JS Bin上查看
// 声明
function sum(a, b) {
return a + b;
}
// 使用
sum(5, 6); // => 11
当这三个步骤按顺序执行的时候,一切看起来都很简单,自然。如果可以话,在使用JavaScript编程的时候你应该遵循这种模式。
JavaScript并没有严格遵循这个顺序,因此提供了更多的灵活性。比如,函数的使用可以在声明之前。下边的例子先调用了函数double(5),然后才声明该函数function double(num) {...}:
在JS Bin上查看
// 使用
double(5); // => 10
// 声明
function double(num) {
return num * 2;
}
这是因为JavaScript中的函数声明会被提升到作用域顶部。
变量提升在不同方面的影响也不同:
变量声明: 使用var, let或const关键字
函数声明: 使用function () {...}语法
类声明: 使用class关键字
接下来让我们详细看看这些区别。
2. 函数作用域变量: var
变量声明在函数作用域内创建并初始化一个变量,例如var myVar, myVar2 = 'Init'。默认情况下,声明但是未初始化的变量的值是undefined。
自从JavaScript的第一版本开始,开发者就在使用这种方式声明变量。
在JS Bin上查看
// 声明变量num
var num;
console.log(num); // => undefined
// 声明并初始化变量str
var str = 'Hello World!';
console.log(str); // => 'Hello World!'
提升与var
使用var声明的变量会被提升到所在函数作用域的顶部。如果在声明之前访问该变量,它的值会是undefined。
假定myVariable在被var声明前被访问到。在这种情况下,声明操作会被移至double()函数的顶部同时该变量会被赋值undefined:
在JS Bin上查看
function double(num) {
console.log(myVariable); // => undefined
var myVariable;
return num * 2;
}
double(3); // => 6
JavaScript在执行代码时相当于把var myVariable移动到了double()的顶部,就像下面这样:
在JS Bin上查看
function double(num) {
var myVariable; // 被移动到顶部
console.log(myVariable); // => undefined
return num * 2;
}
double(3); // => 6
var语法不仅可以声明变量,还可以在声明的同时赋给变量一个初始值:var str = 'initial value'。当变量被提升时,声明会被移动到作用域顶部,但是初始值的赋值却会留在原地:
在JS Bin上查看
function sum(a, b) {
console.log(myString); // => undefined
var myString = 'Hello World';
console.log(myString); // => 'Hello World'
return a + b;
}
sum(16, 10); // => 26
var myString被提升到作用域的顶部,然而初始值的赋值操作myString = 'Hello World'不会受到影响。上边的代码等价于下边的形式:
在JS Bin上查看
function sum(a, b) {
var myString; // 提升到顶部
console.log(myString); // => undefined
myString = 'Hello World'; // 赋值不受影响
console.log(myString); // => 'Hello World'
return a + b;
}
sum(16, 10); // => 26
3. 块级作用域变量: let
let声明在块级作用域内创建并初始化一个变量:let myVar, myVar2 = 'Init'。默认情况下,声明但是未初始化的变量的值是undefined。
let是ECMAScript 6引入的一个巨大改进,它允许代码在代码块的级别上保持模块性和封装性:
在JS Bin上查看
if (true) {
// 声明块级变量
let month;
console.log(month); // => undefined
// 声明并初始化块级变量
let year = 1994;
console.log(year); // => 1994
}
// 在代码块外部不能访问month和year变量
console.log(year); // ReferenceError: year is not defined
提升与let
使用let定义的变量会被提升到代码块的顶部。但是如果在声明前访问该变量,JavaScript会抛出异常ReferenceError: is not defined。
在声明语句一直到代码库的顶部,变量都好像在一个临时死亡区间中一样,不能被访问。
让我们看看以下的例子:
在JS Bin上查看
function isTruthy(value) {
var myVariable = 'Value 1';
if (value) {
/**
* myVariable的临时死亡区间
*/
// Throws ReferenceError: myVariable is not defined
console.log(myVariable);
let myVariable = 'Value 2';
// myVariable的临时死亡区间至此结束
console.log(myVariable); // => 'Value 2'
return true;
}
return false;
}
isTruthy(1); // => true
从let myVariable一行一直到代码块开始的if (valaue) {...}都是myVariable变量的临时死亡区间。如果在此区间内访问该变量,JavaScript会抛出ReferenceError异常。
一个有趣的问题出现了:myVariable真的被提升到代码块顶部了吗?还是在临时死亡区间内未定义呢?当一个变量未被定义时,JavaScript也会抛出ReferenceError。
如果你观察一下该函数的开始部分就会发现,var myVariable = 'Value 1'在整个函数作用域内定义了一个名为myVariable的变量。在if (value) {...}块内,如果let定义的变量没有被提升,那么在临时死亡区间内myVariable的值就会是'Value1'了。由此我们可以确认块级变量确实被提升了。
let在块级作用域内的提升保护了变量不受外层作用域影响。在临时死亡区间内访问let定义的变量时抛出异常会促使开发者遵循更好的编码实践:先声明,后使用。
这两个限制是促使在封装性和代码流程方面编写更好的JavaScript的有效途径。这是基于var用法教训的结果 —— 允许在声明之前访问变量很容易造成误解。
4. 常量: const
常量声明在块级作用域内创建并初始化一个常量:const MY_CONST = 'Value', MY_CONST2 = 'Value 2'。看看下边的示例:
在JS Bin上查看
const COLOR = 'red';
console.log(COLOR); // => 'red'
const ONE = 1, HALF = 0.5;
console.log(ONE); // => 1
console.log(HALF); // => 0.5
当声明一个变量时,必须在同一条语句中对该变量进行初始化。在声明与初始化之后,变量的值不能被修改。
在JS Bin上查看
const PI = 3.14;
console.log(PI); // => 3.14
PI = 2.14; // TypeError: Assignment to constant variable
提升与const
使用const定义的常量会被提升到代码块的顶部。
由于存在临时死亡区间,常量在声明之前不能被访问。如果在声明之前访问常量,JavaScript会抛出异常:ReferenceError: is not defined。
const声明常量的提升的效果与使用let声明变量的提升效果相同。
让我们在double()函数内声明一个常量:
在JS Bin上查看
function double(number) {
// 常量TWO的临时死亡区间
console.log(TWO); // ReferenceError: TWO is not defined
const TWO = 2;
// 常量TWO的临时死亡区间至此结束
return number * TWO;
}
double(5); // => 10
由于在声明之前使用常量会导致JavaScript抛出异常。因此使用常量时应该始终先声明,初始化,然后再使用。
5. 函数声明
函数声明使用提供的名称和参数创建一个函数。
一个函数声明的例子:
在JS Bin上查看
function isOdd(number) {
return number % 2 === 1;
}
isOdd(5); // => true
function isOdd(number) {...}就是一段定义函数的声明。isOdd()用来验证一个数字是否是奇数。
提升与函数声明
函数声明的提升允许你在所属作用域内任何地方使用该函数,即使是在声明之前也可以。换句话说,函数可以在当前作用域或子作用域内的任何地方访问(不会是undefined值,没有临时死亡区间,不会抛出异常)。
这种提升的行为非常灵活。不管是先使用,后声明,还是先声明,后使用都可以如你所愿。
下边的例子在开始的地方调用了一个函数,然后才定义它:
在JS Bin上查看
// 调用被提升的函数
equal(1, '1'); // => false
// 函数声明
function equal(value1, value2) {
return value1 === value2;
}
这段代码可以正常执行是因为equal()被提升到了作用域顶部。
需要注意的函数声明function () {...}和函数表达式 var = function() {...}之间的区别。两者都用于创建函数,但是却有着不同的提升机制。
下边的例子演示了该区别:
在JS Bin上查看
// 调用被提升的函数
addition(4, 7); // => 11
// 变量被提升了,但值是undefined
substraction(10, 7); // TypeError: substraction is not a function
// 函数声明
function addition(num1, num2) {
return num1 + num2;
}
// 函数表达式
var substraction = function (num1, num2) {
return num1 - num2;
};
addition被彻底的提升并且可以在声明之前被调用。
然而substraction是使用变量声明语句声明的,虽然也被提升了,但被调用时值是undefined。因此会抛出异常TypeError: substraction is not a function。
6. 类声明
类声明使用提供的名称和参数创建一个构造函数。类是ECMAScript 6中引入的一项巨大改进。
类建立在JavaScript的原型继承之上并提供了诸如super(访问父类),static(定义静态方法),extends(定义子类)之类的额外功能。
一起看看如何声明一个类并创建一个实例:
在JS Bin上查看
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
move(dX, dY) {
this.x += dX;
this.y += dY;
}
}
// 创建实例
var origin = new Point(0, 0);
// 调用实例的方法
origin.move(50, 100);
提升与class
类声明会被提升到块级作用域的顶部。但是如果你在声明前使用类,JavaScript会抛出异常ReferenceError: is not defined。所以正确的方法是先声明类,然后再使用它创建实例。
类声明的提升与let定义变量的提升效果类似。
让我们看看在声明之前创建类实例会怎样:
在JS Bin上查看
// 使用Company类
// 抛出ReferenceError: Company is not defined
var apple = new Company('Apple');
// 类声明
class Company {
constructor(name) {
this.name = name;
}
}
// 在声明之后使用Company类
var microsoft = new Company('Microsoft');
和预期的一样,在类定义之前执行new Company('Apple')会抛出ReferenceError异常。这很不错,因为JavaScript鼓励先声明后使用的方式。
还可以用使用了变量声明语句(var,let和const)的类表达式创建类。让我们看看下面的场景:
在JS Bin上查看
// 使用Sqaure类
console.log(typeof Square); // => 'undefined'
//Throws TypeError: Square is not a constructor
var mySquare = new Square(10);
// 使用变量声明语句声明类
var Square = class {
constructor(sideLength) {
this.sideLength = sideLength;
}
getArea() {
return Math.pow(this.sideLength, 2);
}
};
// 在声明之后使用Square类
var otherSquare = new Square(5);
这个类使用变量声明语句var Square = class {...}定义。Square变量被提升到了作用域的顶部,但是直到声明该变量的这行代码之前其值都是undefined。因此var mySquare = new Square(10)语句相当于把undefined当作构造函数使用,这导致JavaScript抛出TypeError: Square is not a constructor异常。
7. 最后的想法
像在本文阐述的那样,JavaScript中的提升有多种形式。即使你知道它的工作方式,一般还是建议按照声明 > 初始化 > 使用的顺序使用变量。通过let,const和class提升的方式可以看出ECMAScript 6强烈支持这种使用方式。这将使你免于遇见不期望的变量,undefined以及ReferenceError的困扰。
有一种函数可以在定义之前执行的例外情况。这就是当开发者需要快速了解函数如何被调用的时候,因为这样就不必再滚动到底部阅读函数的具体实现方式了。
例如,这篇文章解释了这种方式是如何增加Angular controllers代码的可读性的。
发表评论
-
微信开发工具中时间问题的小坑
2018-02-07 19:07 840刚开始用微信小程序开发工具,每次运行任何应用,都报这个错误: ... -
三篇不错的介绍CSS GRID的文章
2017-12-06 09:08 565三篇不错的介绍CSS GRID的文章: http://www. ... -
双因素认证(2FA)教程
2017-11-03 09:16 1578http://www.ruanyifeng.com/blog/ ... -
es6 中的export
2017-08-20 08:00 834https://juejin.im/post/5998625f ... -
markdown中的空格
2017-08-20 07:53 1709即使手动输入空格, 也是很不推荐的方法。我推荐全角空格,切换 ... -
(转)讲真,别再使用JWT了
2017-08-17 23:21 1021不错的好文: http://insights.thoughtw ... -
(转)手把手教你WebStorm+chrome实现时时调试刷新
2017-08-15 10:50 3043参考: http://jingyan.baidu.com/ar ... -
IntelliJ Idea 2017 免费激活方法
2017-08-15 09:38 93581. 到网站 http://idea.lanyus.com/ ... -
前端框架这么多,该何去何从?
2017-08-04 07:17 653http://insights.thoughtworkers. ... -
记录一个HTML 5画拓扑图的商业公司
2017-07-18 19:56 854http://qunee.com/ DEMO:http:// ... -
vue 2例子学习收集
2017-07-16 11:46 10161 vue2.0手撸闲鱼App https://githu ... -
(收藏)虚拟DOM内部是如何工作的
2017-07-13 22:08 604虚拟DOM内部是如何工作的 https://segmentfa ... -
最近看到的几篇精彩JAVASCRIPT博客文章推荐
2017-07-11 07:10 580【深度长文】JavaScript数组所有API全解密 http ... -
jsonp 跨域原理:深入浅出 jsonp
2017-07-10 19:55 1439https://lzw.me/a/jsonp.html jso ... -
(转)深度长文-JavaScript数组所有API全解密
2017-07-08 19:59 830深度长文-JavaScript数组所有API全解密 http: ... -
(收藏)网页导出PDF的方案
2017-07-06 07:13 1007(收藏)网页导出PDF的方案 https://yiqiwuli ... -
Chromium 新的弹窗机制以及 HTML 的 <dialog> 元素
2017-06-28 12:37 1157https://juejin.im/post/59525195 ... -
国内一个不错的大屏UI设计厂家
2017-06-03 19:43 3164http://www.lanlanwork.com/dp.ph ... -
canvas仿芝麻信用分仪表盘
2017-05-28 20:21 1608canvas仿芝麻信用分仪表盘 https://segment ... -
(转)CSS 变量教程
2017-05-10 21:12 587http://www.ruanyifeng.com/blog/ ...
相关推荐
以下是关于JavaScript变量提升的一些关键知识点: 1. **声明提升**: - 变量声明(`var`、`let`、`const`)在执行环境的当前作用域顶部被“提升”。但请注意,`let`和`const`在ES6引入后,它们不再遵循完全的提升...
JavaScript 变量作用域详解 JavaScript 变量作用域是基于其特有的作用域链的。在 JavaScript 中,变量作用域是指变量可以被访问和修改的范围。 JavaScript 没有块级作用域,而是基于函数作用域和全局作用域的。 ...
变量提升和函数提升在JavaScript中的应用 JavaScript是一种基于对象的脚本语言,广泛应用于Web开发中。其中,变量提升和函数提升是JavaScript语言中两个非常重要的概念。变量提升和函数提升是JavaScript语言的核心...
JavaScript中的变量提升(Variable Hoisting)是编程时需要理解的关键概念,它涉及到JavaScript引擎如何处理变量和函数的声明。变量提升是指在JavaScript代码执行前,引擎会将所有的`var`和函数声明移动到它们所在...
JavaScript中的变量提升(Variable Hoisting)和函数提升(Function Hoisting)是理解JavaScript执行机制的关键概念,它们在JavaScript代码解析和执行过程中起着至关重要的作用。本文将详细讲解这两个概念,帮助...
JavaScript中的变量声明是编程的基础,理解这一概念对于编写健壮的代码至关重要。本文将深入探讨JavaScript中的变量声明,包括全局变量、...对于更多JavaScript变量声明的深入学习,可以参考IT技术专栏获取相关信息。
### JavaScript变量详解 #### 一、变量命名 在JavaScript中,变量命名有着一定的规范和推荐的最佳实践,这对于代码的可读性和维护性至关重要。 ##### 1. 命名规则 - **首字符限制**:变量名的第一个字符必须是...
关于变量的问题,除了作用域和声明关键字外,还可能涉及变量提升、作用域链、闭包、全局变量、垃圾回收等概念。由于这些概念相对复杂,对于初学者来说,可能会出现理解上的困难。因此,建议通过阅读官方文档、查阅...
本文主要给大家介绍了关于JavaScript中Hoisting(变量提升与函数声明提升)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 如何将 函数声明 / 变量 “移动” 到作用域的顶部。 术语 ...
第一篇文章中提到了变量的提升,所以今天就来介绍一下变量提升和函数提升。这个知识点可谓是老生常谈了,不过其中有些细节方面博主很想借此机会,好好总结一下。 今天主要介绍以下几点: 1. 变量提升 2. 函数提升 3....
JavaScript变量声明是编程基础中的重要一环,理解变量声明对于编写有效的JS代码至关重要。本文将深入探讨JavaScript中的变量声明方式,以及与之相关的全局变量、局部变量、隐式全局变量和“hoisting”(悬置/置顶...
详解JavaScript闭包问题 闭包是纯函数式编程语言的传统特性之一。通过将闭包视为核心语言构件的组成部分,JavaScript语言展示了其与函数式编程语言的紧密联系。由于能够简化复杂的操作,闭包在主流JavaScript库...
JavaScript是一种广泛应用于网页开发的脚本语言,其变量和数据类型的概念是学习基础中的基础。在JavaScript中,变量是可变的数据存储单元,可以用来保存不同类型的数据,例如数字、字符串等。这种松散的类型系统使得...
### Javascript变量作用域详解 Javascript变量作用域是编程中一个非常基础且重要的概念,理解它对于编写有效且可维护的代码至关重要。在Javascript中,变量的作用域主要分为两种:全局作用域和局部作用域。全局变量...