知识点:
#函数声明和函数表达式
fn();//成功
function fn(){
//声明
}
fn1();//失败
var fn1 = function(){
//表达式
}
如果是函数声明,那么在他之前调用这个函数,这个声明会自动提到调用之前;
如果是用fn1接受的表达式,那么在这个fn1=function之前,fn1等于undefined的,这个时候调用它会报错;
age=20;
console.log(age);
var age;
//输出20
在修改age之前,age的声明会提到修改之前,相当于
var age = undefined;
age=20;
console.log(age);
var age;
#执行上下文(变量提升)
全局:变量定义、函数声明 //在一段<script>内
函数:变量定义、函数声明、this、argument//在函数内
全局和函数在自己执行调用之前,会把以上内容提前;
对上面这段代码,首先全局中,把变量a的定义提前,a为undefined,然后把function fn的声明也提前;
所以可以输出a为undefined,也可以在声明前调用fn函数;
对于函数fn内部,会把变量age提前相当于undefined,然后this会提前,然后再把参数name提前;
#this要在执行时才能确认值,定义时无法确认
#this四种执行情况
作为构造函数执行
作为对象属性执行
作为普通函数执行
call apply bind
1、作为构造函数执行
function Foo(name){
//this = {};
this.name = name;
//return this;
}
var f = new Foo("A");
2、作为对象属性执行
var obj = {
name:'A',
printName:function(){
console.log(this.name);
}
}
obj.printName();//A this === obj
3、作为普通函数执行
function fn(){
console.log(this);//this===window
}
fn();
4、call apply bind
function fn1(name){
alert(name);
console.log(this);
}
fn1.call({x:100},'jojo'); //第一个参数为this,第二个参数为name
bind的用法:
var fn1 = function(name){
alert(name);
console.log(this);
}.bind({x:100})
fn1('jojo'); //this一直为{x:100}
注意用bind时不能用函数声明的方法,比如function fn1(){}.bind()是不行的,一定要是函数表达式才能bind
#作用域、闭包
#js没有块级作用域
if(true){
var name = 'jojo';
}
console.log(name); //可以输出jojo,不报错
这里关系到js的闭包
创建函数(或对象方法)时自动保存作用域内的上下文环境(参数和局部变量)供以后调用时使用。这里保存上下文环境的对象就是闭包(closure) 。
var s = 10;
function addNum(x) {
var t = s;
var f = function(y) {
return s + t + x + y;
}
return f;
}
var add1 = addNum(1); //10 + 10 + 1 + y
s=20;
var add2 = addNum(3); //20 + 20 + 3 + y //且add1中的s变成20
alert(add1(2));
alert(add2(4));
s t x y
20 10 1 2
20 20 3 4
产生对象时其方法也会形成闭包
function B(y){ //作用域链,没有定义就像父级作用域找
function A(x){
this.x=x+"*";
this.sayA=function(){alert(x+" "+y);}
}
var b=new A("10");
return b;
}
var s=B("20");
var t=B("30");
s.sayA(); // 10 20
t.sayA(); // 10 30
利用包装函数形成闭包
var f=(function(x){
return function(y){console.log(x,y)};
})(10);
f(20);// 10 20
* 闭包常用于把参数带入到事件处理函数中
#只有函数和全局作用域
var a = 100;
function fu(){
var a = 200;
console.log(a);
}
fu();//200,对于函数来说函数作用域优先