零基础入门-javaScript学习笔记之变量和作用域

 

变量的声明方式 var

对于 Var x=1; var y = x;此时,x为基本类型,修改y的值不会影响到x

而对于对象,函数,数组等类型,均是属于引用类型,vara = [1,2,3];var y = a;

ya的一个引用。

 

需要注意的是:

变量的声明和函数的声明会被提升。

a=1;
console.log(a);
var a;

 

>>1

此时,并不会出错,原因是var a = 1;这句代码被提升了,其效果相当于

var a;
a =1;
console.log(a);

 

值得注意的是,

console.log(a);
var a=1;

>>undefined

 

声明(包括变量声明和函数声明)会被提升,但是赋值并不会被提升。上面的代码会被引擎理解为

var a;
console.log(a);
a =1;

 

 

不得不说的作用域

 

Js的作用域与c/c++的作用域有着非常大的差别,一不小心就会出现各种意想不到的结果。

先从一小段代码讲起:

var a =1;
function b(){
   
console.log(a);
}
(
function top(){
   
var a= 2;
   
( function t(){
       
console.log(a);
   
})();
    b();
})();

 

>>2

>>1

 

从输出结果看,并不是都是1或者2,这点就是因为作用域不一样导致。在js中,函数有着自身的作用域,在查找变量的时候,会先在函数自身的作用域中查找。上述例子中,t函数是函数top中的一个函数语句(函数t被一对()包装,此时函数被当成一条语句,在top函数中也访问不到函数t,还有一点值得注意的是,函数t只有在(function  t (){ //“此处才能访问” }),(function(){})(),后面的一个括号为立即执行改语句)。所以在t自身的作用域中并没有a这个对象,编译器会沿着作用域往外找,是top函数作用域,找到a2并输出改值。在执行到b()函数的时候,因为b函数是在全局声明的,所以b函数自身没有a对象的时候,编译器便往上一层作用域查找a对象,即在全局作用域中找到a对象。这便是js中的词法作用域,简单理解和函数声明的位置有关,和调用的位置无关。

 

if(true){
   
var a="test!"
}
console.log(a);

 

>>test!

 

没有接触过js的人对上述代码也会非常的吃惊,竟然不是抛出ReferenceError。在c/c++中,有块作用域,用{}来包裹。而在js中,当你用var来声明的时候,并不是声明在块作用域中,它会被声明在上一级作用域中,(书中说用let可以声明为块作用域变量。但本人学习js环境不支持let,可能是版本的问题)所以上述代码片段实际是在全局作用域中声明了一个a变量。之后再输出a自然不会有错。不注意这一点很容易导致变量覆盖,从而引起意想不到的错误。对于for()等语句也是一样。

 

注意:

var a =1;

(
function (){
   
console.log(a);
   
var a=2;
   
console.log(a);

})();

>>undefined

>>2

 

上述代码并不是预12,当词法作用域和变量提升结合时就可能会引发这种错误。

你可能感兴趣的:(js)