以前总是搞不清楚js里面的作用域、块级作用域、预解析,做题总做错,今天彻底搞明白了,来记录梳理一下~
块级作用域
在其他语言中,任何一对花括号中的语句都属于一个块儿,在这之中定义的所有变量在代码块外都是不可见的。Js中没有块级作用域
一个感觉在面试中会经常遇到的问题
for(var i =0;i<10;i++){ var num = 100; } console.log(i); //i是多少
第一反应是i是9,但是错了,i是10。因为按照循环条件,i肯定是在0-10之间,当i=9的时候,都还在执行循环体,然后9++到10,不符合循环条件,跳出循环,所以此时i是10
变量的使用范围
1.局部变量
因为js里面没有块级作用域,当一个变量声明在函数的内部,此时这个变量叫做局部变量,它不能在函数外部被访问到
function f1(){ var num = 1000; } f1(); console.log(num);
2.全局变量
直接在script标签中定义的变量,或者说是不在函数中定义的变量都叫做全局变量
var num = 1000; </script> <script> function f1(){ console.log(num); } f1(); </script>
3.隐式全局变量
隐式全局变量:当一个变量声明的时候,没有使用var,那么这个变量就是隐式全局变量
注意!
通过var创建的全局变量是不可被删除的,而隐式全局变量是可以被删除的。这表明在技术上,隐式全局变量并不是真的全局变量,它们是全局对象的属性,属性是可以通过delete删除的,而变量不能。
var num = 1000; num2 = 200; delete num; delete num2; console.log(typeof num); //number 这里即使用delete删除了num,它的类型还是number 无法真正被删除 console.log(typeof num2); //undefined 而隐式全局变量很容易被删除了
变量退出作用域后会被销毁,全局变量关闭网页或浏览器之后才会被销毁/释放
function f1(){ var num = 10; } f1();
这个函数被调用以后,变量所占的空间就被释放了——因为这个函数被用完了
**回调函数粗略的讲解
回调函数:函数作为另一个函数的参数使用
function getSum(x,y){ return x + y; } function ff(x,y,fn){ //fn作为一个参数 return fn(x,y); //fn是一个函数,并且被调用了 } var result = ff(1,5,getSum); //给fn传参 console.log(result)
函数还可以作为另一个函数的返回值调用
function f1(){ return function (){ console.log(123); } } var result = f1(); //函数赋值给result //console.log(result) 错误写法 这样只会打印出来f1的函数体 result();
little Trick
function aa(){ alert('aaaa'); return function (){ alert('bbbb'); } } alert(aa); alert(aa()); alert(aa()());这三个结果分别是什么?
结果1 函数名打印出来是整个函数体
结果2 弹出aaaa和返回值内的匿名函数,原因是,函数被调用后内部执行了这段代码,然后匿名函数并未被调用,所以返回的是整段匿名函数体
结果3 弹出aaaa,bbbb,和undefined 匿名函数也被调用了,所以弹出了bbbb 为什么会再弹一次undefined呢~?
arguments对象
arguments是一个对象,一个伪数组,可以获取函数参数的个数
**伪数组的概念:可以使用.length,但是不可以调用数组的方法。
function f1(){ var sum = 0; for(var i =0;i<arguments.length;i++){ sum += arguments[i]; //arguments是一个伪数组。它可以指代函数的参数 } return sum; } var result = f1(10,22,11,33,155); console.log(f1);