一、JS中函数的不同调用方式:
1. 直接调用 foo();
2.方法存在于对象中,调用对象方法 o.method();
3.构造器 new Foo();
4. call/apply/bind func.call(o);
二、函数声明和函数表达式的区别:
函数声明:
区别:函数的声明和变量会前置,但是表达式不会。举例:
//函数声明变量前置了,会把function add(a,b)前置,所以添加参数1,2即可成功打印;
var num = add(1,2);
console.log("num",num);
function add(a,b){ //声明一个函数add
a=+a; //一元运算符,对数字没有影响,对字符串会将字符串转化为数字
b=+b;
if(isNaN(a)||isNaN(b)){
return;
}
return a+b;
}
//函数表达式就不会前置.但是会把变量提升var add1前置, 这个变量前置只能是undefined
var num1=add1(1,2);
console.log("num1",num1);
var add1=function(a,b){ //定义一个叫add1的匿名函数表达式
a=+a; //一元运算符,对数字没有影响,对字符串会将字符串转化为数字
b=+b;
if(isNaN(a)||isNaN(b)){
return;
}
return a+b;
}
三、this
1. 当this为全局变量的时候,this就相当于window。
console.log(this===window)
this.a=37; console.log(window.a) //37
一般情况下,this关键字指向全局对象window,但是在严格模式下"use restrict";下禁止this指向全局对象的。
2. 作为对象方法的函数调用时的this,指向这个对象:
var o={
props:37,
f:function(){
return this.props;
}
}
console.log(o.f()); //用字面量形式创建的对象函数,调用this指向o对象
var o1={props:36};
function test(){
return this.props; //这时候this指向的是window,那么window.props返回的是undefined
}
o1.f=test;
console.log(o1.f()); //将函数test指向o1对象的f属性下,这时候this.props中的this指向对象o1
3. 对象原型链上的this
var o3={
f:function(){
return this.a+this.b;
}
}
var p=Object.create(o3); //p的原型继承了这个o3的方法
console.log("p",p) //这时候打印出来的p是一个空的对象,p的原型上有o3的方法f
p.a=1;
p.b=2;
console.log(p.f()); //3
4.构造函数中的this
构造函数中的this,是指向于用构造函数创建对象后的那个对象。
注意:当你的构造函数中有return语句时,需要看构造函数中的return语句是值类型还是引用类型;如果是值类型,那么没有影响,将this作为返回值;如果是引用类型,就会直接返回该引用类型。没有return语句,或者return;也是将this作为返回值;
详情,你可以看我的另外一篇博客:JavaScript之构造函数内有return详解
5. call/apply方法改变this指向;ES5中的bind方法(IE9+等主流浏览器)改变this指向
call和apply都可以将this指向传入的某个函数或者对象中,这两者的区别就是call可以添加其他参数,直接以逗号的形式传参,但是apply传入的其他参数必须是数组的格式;
function add(c,d){
return this.a+this.b+c+d;
}
var o={
a:2,
b:1
}
add.call(o,10,20); //返回2+1+10+20=33;
add.apply(o,[12,13]); //返回2+1+12+13=28;
bind中的参数是一个你想将this指向的对象;不同点:bind: 不立即执行函数,一般用在异步调用和事件; call/apply: 立即执行函数。