1、任意数求和
function sum(){
var total = null;
for(var i=0;i<arguments.length;i++){
var a = arguments[i];
var item = parseFloat(a);
!isNaN(item)? total += item:null ;
}
return total;//相当代替了函数的位置,还在函数这个执行上下文里,外界无法访问这个私有变量。
}
console.log(sum(1,22,'2'));//25
2、变量提升与var类型
console.log(a,b);//undefined undefined
var a=12,b=12;
function fn(){
console.log(a,b);//undefined 12,当前作用域有变量a,就不去外面找;当前没有变量b,所以去外面找。
var a=b=13;//var a=13;b=13;不带VAR不是私有变量,相当于操作作用域链上的变量。
console.log(a,b);//13 13
}
fn();
console.log(a,b);//12 13
3、变量监测机制
考察:当前作用域中只要是let声明的变量,针对该变量执行变量检测机制,其他老语法的变量常规操作。
let a=10,b=10;
let fn = function(){
console.log(a,b);//报错,浏览器检测机制;
//代码执行前检测到内部作用域有变量a,且是let定义的,没有变量提升,所以提前使用会报错;
//而不是沿作用域链找。
let a=b=20;//let a=20;b=20;去上一级找到变量b修改
console.log(a,b);
}
fn();//如果报错那行去掉,20 20
console.log(a,b);//如果报错那行去掉,10 20
4、全局变量与私有变量
考察:函数作用域中先形参赋值、再变量提升,最后代码执行。
var a=12,b=13,c=14;
function fn(a){
console.log(a,b,c);//12 undefined 14;内部变量提升,a是形参先赋值=12,b是变量提升有值=undefined,c没有去上一级找;
var b=c=a=20;//==>var b=20;c=20;a=20;
console.log(a,b,c);//20 20 20
}
fn(a);//实参就是值,相当于fn(12)
console.log(a,b,c);//12 13 14
5、上级作用域
考察:上级作用域只跟函数在哪里创建有关,与在哪里执行无关。
var a=12;
function fn(){
//arguments:实参集合
//arguments.callee:函数本身
//arguments.callee.caller:函数的宿主,在哪执行(全局作用域下是null)
console.log(a);
console.log(arguments.callee.caller);//function sum(){...}
}
function sum(){
var a=120;
fn();
}
sum();//12,上级作用域是创建时的。
6、自执行函数结合this指向、上级作用域
考察给引用数据类型变量 声明、创建引用值以及定义的时机;
考察函数私有作用域的上级作用域:只和在哪里创建有关;
考察私有作用域中的this指向:与被谁执行有关。
var n=2;
var obj={
n:3,
fn:(function(n){
n*=2;
this.n+=2;
var n=5;
return function(m){
this.n*=2;
console.log(m+(++n));
}
})(n)//自执行函数执行时,还没有赋值给obj,此时obj=undefined,所以这里的n是全局的;obj.n会报错。
};//自执行函数,this指向window,在创建时执行;
var fn=obj.fn;
fn(3);
obj.fn(3);
console.log(n,obj.n);
在浏览器中:9 10 8 6;
在node中执行:9 10 2 6。