语句和代码块,变量作用域
语句和代码块概念
我们的JS程序是由一条一条语句构成的语句是按照自上向下的顺序一条一条执行的
在Js中可以使用{}来为语句进行分组,同一个{}中的语句我们称为一组语句他们要么都执行,要么都不执行一个{}中的语句我们也称为一个代码块在代码块{}后面不用写;js中的代码块,只具有分组的作用,没有其他的用途,代码块里面的内容,在外部是完全可见的.
//作用域:
// * 全局变量:在代码块之外声明的变量都是全局变量,它所处的环境就称为全局作用域,全局变量无论在在什么地方都可以调用到,当浏览器关闭时销毁
// *
// * 局部变量:在函数内什么的变量,就叫局部变量,它所处的环境就称为局部作用域,只能在函数内调用,当函数执行完马上销毁
// *
// * 块级变量:在代码块中定义的变量,(比如在if语句中),它所处的环境就称为块级作用域
// *
例如:
alert(a) //语句
console.log(a) //语句
{
var a = 10;
alert(a); //10
console.log(a); //10
}
document.write(a) //10
一般而言。js的代码块确实是这样的。
但JS还有一个概念叫做作用域。
作用域指一个变量的作用范围
在js中有三种作用域变量: 全局变量 、局部变量、 块级变量es6
全局变量:在代码块之外声明的变量都是全局变量,他所处的环境就叫做全局作用域;全局变量无论在什么地方都可以调用到。当浏览器关闭时全局变量销毁。
全局作用域
1、直接编写在script标签中的js代码,都在全局作用域中
2、全局作用域中有一个全局对象window,我们可以直接使用,它代表的是一个浏览器的窗口,它由浏览器创建,我们可以直接使用
在全局作用域中:
创建的变量都会作为window对象的属性保存
创建的函数都会作为window对象的方法保存
例如:
var a = 10;
console.log(window.a); //10
function fun(){
console.log("我是fun函数,也是window对象的方法")
}
window.fun();
例如:console.log(alert() == window.alert());//true
局部变量:在函数内声明的变量,就叫做局部变量,所处的环境就叫局部作用域,只能在函数中调用,局部变量当函数执行完马上销毁
块级变量es6:在代码块中定义的变量(比如在if语句中,所处的环境叫块级作用域(代码块)。不过变量要用let,否则用var还是会让变量成为全局变量。
声明变量的关键词:
var let(es6语法) const
var 和 let 的区别:
1、通过var来声明的变量,可以重复声明,let不可以
2、我们通过var来声明的全局变量会自动挂在到window对象下,称为window对象下的一个属性,let不会
3、在块级作用域中,通过var来声明的变量,可以在全局作用域中调用,let不可以
4、通过var来声明的变量,会发生声明提前的清空,let不会
如: if(true){
var a = 10;//全局作用域
}
console.log(a);//10
但是
if(true){
leta = 10; //块级作用域
}
console.log(a);//underfined
const:用来声明一个常量的(es6语法)
1、即变量一旦声明并赋值了某个值,就不能更改其值了,也就是常量名是唯一的,值也是唯一的
const ISBLACK = true;
const ISBLACK = false; //直接报错。
ISBLACK = false; //依然报错。
变量的声明提前
使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)
但是如果声明变量时不使用var关键字,则变量不会被声明提前 (会报错)
例:
console.log(a); //报错
a = 123;
例: console.log(a); //undefined
var a = 123;
//相当于:
var a;
console.log(a);
a = 123;
var str1 = "hello";
let str2 ="我是通过let声明的全局变量";
str = "可以更改let声明的值";
console.log(str1);//hello
console.log(window.str1); //hello
console.log(window.str2); //undefined通过var来声明的全局变量会自动挂在到window对象下,称为window对象下的一个属性,let不会挂载到window
函数的声明提前
使用函数声明形式创建的函数function函数(){}
它会在所有的代码执行之前就被创建
所以我们可以在函数声明前调用函数
fun(); //hello
function fun(){
console.log("hello");
}//使用函数声明形式创建的函数,函数声明会被提前创建
使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用
fun2();//报错
var fun2 = function(){
console.log("hello")
}
//函数表达式,不会被提前创建,因为var虽然定义了fun2,但变量的提前特性是不会赋值的,所以调用一个undefined的函数会报错
注意:每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的,如下:
function fun(){
}
fun(); //互相独立的作用域
fun(); //互相独立的作用域
一些面试坑点
var a=1;
(function(){
console.log(a);
var a=2;
console.log(a);
})();
正确答案:undefined 2
2、
var result = null;
//判断中会出现的坑点
// console.log(Boolean(result)); //false
// console.log(null == false); //false,坑点
if(!result){ // !表示非, 对布尔值false取非,结果为true,对布尔值true取非,结果为false. 优先级较低会先转换布尔值再取非
var num1 = 10;
var num2 = 123;
result = num1 + num2;
}
console.log(result); //133
console.log(num1); //10