作用域和闭包
全部 局部
变量提升理解
执行上下文:执行前,先把声明拿出来。(拿函数的时候是整个函数方法都拿出来,跟变量不一样,变量就拿出变量,不拿变量后
面的赋值)
范围:一段<script>或者一个函数
全局:变量定义 函数声明 一段<script>
函数(局部):变量定义 函数声明 this arguments 函数
ps:注意函数声明和函数表达式得区别
形参:定义得时候
实参 :调用得时候
arguments:类数组对象 ,当调用一个函数得时候,把传入这个函数得参数存放在arguments里,以数组得形式存放得,
并且把长度也传进去。不是数组,是类数组,又很多数组得方式也可以调用。arguments对象的_proto_指
object,所以不是数组对象。有了这个对象很方便,不用给所有的形参指定参数名,通过参数名的方式获取参数名
可以直接使用arguments就行了
function add (){ if(arguments.length==2){ return arguments[0]+arguments[1];} else { return "input va
lid";}} console.log(_add(1,2));//3 console.log(add(1,2,3))//input valid
callee属性:表示当前函数的一个引用,这个属性里面存放的是我们调用的这个函数的代码。(就是调用的函数
代码)
1 函数重载,参数类型不同或参数个数不同可以让方法实现的功能不同。js(弱数据类型)不支持函数重载,
就是重写函数时,会把原来的函数覆盖了。
重写:覆盖的意思,弱数据类型没有重载的概念,所以函数名相同时,会覆盖之前的函数。
强类型只有函数名和参数名相同时才会重写。
强/弱类型是指类型检查的严格程度的。语言有无类型,弱类型和强类型三种。无类型的不检查,
甚至不区分指令和数据。弱类型的检查很弱,仅能严格的区分指令和数据。强类型的则严格的在编译
期进行检查。c++,c,c#,java这些都是强类型,因此每个变量和对象都必须具有声明类型。
function add() { var len = arguments.length, sum = 0; for(;len--;){ sum += arguments[len]; }
return sum; } console.log( add(1,2,3) ); //6 console.log( add(1,3) ); //4 console.log( add(1,2,3,5,6,2,7) )//26
this场景:this在执行的时候才能确认值,定义时无法确认。表示当前对象
1.作为构造函数执行
function Foo(name){
this.name=name;
}//new 的过程 whh 给Foo,this指向{}空对象,赋值,返回this
var f=new Foo("whh");
console.log(f.name);//whh
2.作为对象属性执行
var obj ={
name:'A',
print:function(){ console.log(this.name)}
}
obj.print();//A
3.作为普通函数执行 window
function fn(){console.log(this)}
fn();//返回window
4.call apply bind
//call apply bind 三个用法差不多的 第一个参数指向this,执行的是第二个开始
function fn1(name,age){alert(name+age);console.log(this)}
fn1.call({x:100},"whh",20);//第一个参数指向this,执行的时第二个
fn1.apply({x:100},["whh",20])//后面的当数组传递 whh20
var fn1=function(name,age){alert(name+age);console.log(this)}.bind({x:100});//whh20
fn1("whh",20);
如何理解作用域
没有块级作用域 (一个{}代表一个块,js中没有块级作用域(不像c++那些),就是变量定义在函数内部,但是在函数外部
可以使用),所以定义变量时在外部定义。
有函数(局部,函数外访问不了的,不能改变的)和全局作用域(所有人都可以改变覆盖,使用)
作用域链
当前作用域内没有定义的变量是自由变量(去父级作用域寻找)
闭包: 就是根据自由变量去寻找作用域链。 闭包使用场景:函数作为返回值;函数作为参数传递
函数作为返回值
function fn(){
var a=100;
return function(){ console.log(a);}
}
var f1=fn();
var a=200;
f1();//100 f1方法是fn,fn返回return后面,向父级是fn里寻找a,所以跟全局变量没关
函数作为参数传递
function fn(){
var a=100;
return function(){ console.log(a);}
}
var f1=fn();
function f2(fn){ var a=200;fn();} f2(f1)//100