Open rccoder opened 7 years ago
2016-9-17 10:46 补充说明 const 关于引用值修改问题
我们在学习 JavaScript 的过程中最基础的一项就是如何使用变量。变量是存储所有可能类型(比如:number, string, array 等)值的容器。每个变量都会有一个被称之为变量名的名字,这个名字会在后面的代码中使用(比如:读出这个变量的值)。
在这篇文章中,你将会了解到如何去使用变量以及不同变量声明方式的区别。
声明: 变量将会已一个包含相应作用域范围(比如: 在一个函数里面)的名字进行注册。
初始化: 当你声明一个变量的时候会自动的进行初始化,也就是说由 JavaScript 解释引擎为变量分配了一块内存。
赋值: 把一个指定的值指派(赋)给一个变量。
注意: 在 JavaScript 第一个版本 released 的的时候 var 这个关键词就是可以使用的。在 ES6(ES 2015)以及之后的版本中出现了 let 和 const 关键词 var
注意: 在 JavaScript 第一个版本 released 的的时候 var 这个关键词就是可以使用的。在 ES6(ES 2015)以及之后的版本中出现了 let 和 const 关键词
var
let
const
语法:
var x; // 声明变量、初始化 x = "Hello World"; // 赋值 // 用一行代码写 var y = "Hello World";
这种方式的变量声明和赋值是非常流行的,直到 ES 2015 出现之后这种方式才有了可替代的方法。在封闭的函数作用域中用 var 的方式声明变量是可以的,但是如果不是在封闭的函数作用域中,声明的变量就是全局的。(换句话中,用 var 声明没有块级作用域的概念)
例子:
function sayHello(){ var hello = "Hello World"; return hello; } console.log(hello);
这将会抛出一个错误ReferenceError: hello is not defined,变量hello只有在函数sayHello中是可用的。但是下面的这个例子将会正常工作,以变量全局声明的方式运行。
ReferenceError: hello is not defined
hello
sayHello
var hello = "Hello World"; function sayHello(){ return hello; } console.log(hello);
let x; // 声明与初始化 x = "Hello World"; // 赋值 // 用一行代码写 let y = "Hello World";
在新的 JavaScript 中出现了 var 的后裔。 let 的作用域不仅在函数中封闭,也在块语句中封闭。块语句就是包含在 { 与 } 中的所有语句(比如: 一个判断或一个循环)。let 的优点就是让变量在一个较小的范围内使用,这样就可以让错误产生的可能性减小。
{
}
var name = "Peter"; if(name === "Peter"){ let hello = "Hello Peter"; } else { let hello = "Hi"; } console.log(hello);
这将会抛出一个错误:ReferenceError: hello is not defined,变量 hello 只有在块级作用域中是可用的(这个例子中的 if 判断中),但是下面的例子将正常工作。
if
var name = "Peter"; if(name === "Peter"){ let hello = "Hello Peter"; console.log(hello); } else { let hello = "Hi"; console.log(hello); }
const x = "Hello World";
技术角度上讲 constant 不是一个变量。constant 的特殊就在于你只能在声明的时候进行初始化(赋值给他),在以后的过程中是无法给他赋新值的。constant 也是限制于块级作用域中(和 let 一样)
constant
constant 应该用于那些在程序运行的时候值一定不能改变的量,当你想重写他的值得时候,应用将抛出一个错误。
注解:
如果 const 的变量是一个引用类型的,比如 Object 或者 Array,会发现这个变量还是可以修改的。但是这并不违反上文所说的内容。
Object
Array
引用类型可以理解为申明了一块地址,然后指针指向一块内容。像 Object 或者 Array 这样的引用类型,我们在修改值得时候并不会改动他的指针地址,变得只是指向的内容里面的东西。
const a = {}; a['b'] = 1; const b = []; b.push(1)
你可能会创建一个全局的变量(比如: 在函数的外面),但是即使你在函数的里面,如果你在声明变量的时候忘记了写 var、let 或者 const,创建的变量也将会是全局的。
function sayHello(){ hello = "Hello World"; return hello; } sayHello(); console.log(hello);
上面的例子将会输出 Hello World,这是因为在函数中变量 hello 声明的时候 hello = 前面没有任何的变量声明描述。
Hello World
hello =
要避免这种意料之外的全局变量声明你可以在 JavaScript 中开启 严格模式。 变量提升和时间死区(Temporal Dead Zone)
要避免这种意料之外的全局变量声明你可以在 JavaScript 中开启 严格模式。
var 和 let/const 之间的另外一个重要区别就是 变量提升。变量的声明一直会被提升到当前作用域的顶部,这也就是说:
let/const
console.log(hello); var hello; hello = "I'm a variable";
等价于
var hello; console.log(hello); hello = "I'm a variable";
这种方式的表现方式就是在两个例子中都会输出 undefined。如果不是 var hello, 变量的声明将不会提升到作用域的顶部,并且将抛出一个 ReferenceError 的错误
undefined
var hello
ReferenceError
这种现象叫做hoist,在 var 中有,同样在 let/const 中也有。
就和上面所提及到的一样,在声明代码之前使用后面用 var 声明的变量会返回一个 undefined,这个值是默认的在初始化的时候赋进去的。
但是如果是在声明之前使用后面会用 let/const 声明的变量会抛出一个错误。这个因为变量在声明代码之前是不可用的(没有被初始化)。进入作用域和使用作用域的值得这段时期就叫做时间死区(Temporal Dead Zone)。
注解: 时间死区(Temporal Dead Zone): 在进入一个scope之后,let/const也会有一个hoist,这个过程和var 一样,区别是 var 在hoist之后,被初始化为了 undefined,但是let/const没有初始化,直到真正声明它的地方。 结论
注解: 时间死区(Temporal Dead Zone): 在进入一个scope之后,let/const也会有一个hoist,这个过程和var 一样,区别是 var 在hoist之后,被初始化为了 undefined,但是let/const没有初始化,直到真正声明它的地方。
无论在什么情况下,为了减少出现不必要的错误你应该使用 let 和 const。如果你一定要使用 var,最好在作用域的顶部使用,以防止产生不可预料的错误(大多和变量提升相关)
原文: Quick Tip: How to Declare Variables in Javascript
写文不易,赠我一杯咖啡增强一下感情可好?
👍
:clap: 可以再进一步讲一下function的声明定义吗
掘金讨论 http://gold.xitu.io/entry/57daa9d28ac24700614f8b69/detail
我们在学习 JavaScript 的过程中最基础的一项就是如何使用变量。变量是存储所有可能类型(比如:number, string, array 等)值的容器。每个变量都会有一个被称之为变量名的名字,这个名字会在后面的代码中使用(比如:读出这个变量的值)。
在这篇文章中,你将会了解到如何去使用变量以及不同变量声明方式的区别。
声明、初始化、赋值之间的区别
声明: 变量将会已一个包含相应作用域范围(比如: 在一个函数里面)的名字进行注册。
初始化: 当你声明一个变量的时候会自动的进行初始化,也就是说由 JavaScript 解释引擎为变量分配了一块内存。
赋值: 把一个指定的值指派(赋)给一个变量。
声明的类型
语法:
这种方式的变量声明和赋值是非常流行的,直到 ES 2015 出现之后这种方式才有了可替代的方法。在封闭的函数作用域中用
var
的方式声明变量是可以的,但是如果不是在封闭的函数作用域中,声明的变量就是全局的。(换句话中,用var
声明没有块级作用域的概念)例子:
这将会抛出一个错误
ReferenceError: hello is not defined
,变量hello
只有在函数sayHello
中是可用的。但是下面的这个例子将会正常工作,以变量全局声明的方式运行。let
语法:
在新的 JavaScript 中出现了
var
的后裔。let
的作用域不仅在函数中封闭,也在块语句中封闭。块语句就是包含在{
与}
中的所有语句(比如: 一个判断或一个循环)。let
的优点就是让变量在一个较小的范围内使用,这样就可以让错误产生的可能性减小。例子:
这将会抛出一个错误:
ReferenceError: hello is not defined
,变量hello
只有在块级作用域中是可用的(这个例子中的if
判断中),但是下面的例子将正常工作。const
语法:
技术角度上讲
constant
不是一个变量。constant
的特殊就在于你只能在声明的时候进行初始化(赋值给他),在以后的过程中是无法给他赋新值的。constant
也是限制于块级作用域中(和let
一样)constant
应该用于那些在程序运行的时候值一定不能改变的量,当你想重写他的值得时候,应用将抛出一个错误。如果
const
的变量是一个引用类型的,比如Object
或者Array
,会发现这个变量还是可以修改的。但是这并不违反上文所说的内容。引用类型可以理解为申明了一块地址,然后指针指向一块内容。像
Object
或者Array
这样的引用类型,我们在修改值得时候并不会改动他的指针地址,变得只是指向的内容里面的东西。例子:
意料之外的全局变量创建
你可能会创建一个全局的变量(比如: 在函数的外面),但是即使你在函数的里面,如果你在声明变量的时候忘记了写
var
、let
或者const
,创建的变量也将会是全局的。例子:
上面的例子将会输出
Hello World
,这是因为在函数中变量hello
声明的时候hello =
前面没有任何的变量声明描述。var
和let/const
之间的另外一个重要区别就是 变量提升。变量的声明一直会被提升到当前作用域的顶部,这也就是说:等价于
这种方式的表现方式就是在两个例子中都会输出
undefined
。如果不是var hello
, 变量的声明将不会提升到作用域的顶部,并且将抛出一个ReferenceError
的错误这种现象叫做hoist,在
var
中有,同样在let
/const
中也有。就和上面所提及到的一样,在声明代码之前使用后面用
var
声明的变量会返回一个undefined
,这个值是默认的在初始化的时候赋进去的。但是如果是在声明之前使用后面会用
let
/const
声明的变量会抛出一个错误。这个因为变量在声明代码之前是不可用的(没有被初始化)。进入作用域和使用作用域的值得这段时期就叫做时间死区(Temporal Dead Zone)。无论在什么情况下,为了减少出现不必要的错误你应该使用
let
和const
。如果你一定要使用var
,最好在作用域的顶部使用,以防止产生不可预料的错误(大多和变量提升相关)原文: Quick Tip: How to Declare Variables in Javascript
参考资料:
版权声明
捐赠
写文不易,赠我一杯咖啡增强一下感情可好?