一.函数
函数是一个对象,所以JS函数可以像其他对象那样操作和传递,所以我们也常叫JS中的函数为函数对象。
函数返回值是依赖于return语句.
对于一般的函数,若没有return语句,默认返回undefined。
若作为构造器,外部使用new去调用,则返回this,反之,若return一个对象,便将这个对象作为new操作的返回值。
二.函数不同的调用方式
1.直接调用 foo();
2.对象方法 o.method();
3.构造器 new Foo();
4.call/apply/bind func.call(o);
三.创建函数的方式
1.函数声明
function add(a,b){
...
}
2.函数表达式
//方式一
var add=function(a,b){
};
//方式二:立即执行函数表达式
(function(){
})();
//方式三
return function(){
}
//方式四:命名式函数表达式
var add=function foo(a,b){
}
两者比较
函数声明会被前置,在声明的位置前面调用依然可以成功。可是在函数表达式位置前调用则不会成功。
函数表达式中只有变量的声明会提前,后面的函数的创建只有在执行时才会被赋值。
3.Function构造器
//前两个参数表示函数对象的形参,第三个参数表示函数体里的代码,是字符串。
var func=new Function('a','b','console.log(a+b);');
func(1,2);
var func= Function('a','b','console.log(a+b);');
func(1,2);
三者比较:
类别 | 函数声明 | 函数表达式 | 函数构造器 |
---|---|---|---|
前置 | Y | ||
允许匿名 | Y | Y | |
立即调用 | Y | Y | |
定义该函数的作用域通过函数名访问 | Y | ||
没有函数名 | Y |
四.this介绍
1.全局作用下的this
console.log(this.document===document)//true
console.log(this===window);//true
this.a=37;//相当于创建了一个全局变量a并赋值3为37
console.log(window.a);//37
2.一般函数的this
function f1(){
return this;//仍然指向window
}
f1()===window;//true
3.作为对象方法的函数的this(常用)
var o={
prop:37,
f:function(){
return this.prop;
}
};
console.log(o.f())//37 this指向了对象o
与函数的创建无关,只要将函数作为对象的方法去调用,那么this就会指向该方法。
4.对象原型链上的this
var o={f:function(){return this.a+this.b}}//this可以拿到原型链上和对象本身的变量
var p=Object.create(o);//对象P是一个空对象原型指向o
p.a=1;
p.b=4;
console.log(p.f());//5
5.构造器中的this
function Myclass(){
this.a=37;
}
var o=new Myclass();//this指向空的对象,且this的原型指向MyClass.prototype
console.log(o.a);//37
6.call/apply方法中的this
function add(c,d){
return this.a+this.b+c+d;
}
var o={a:1,b:3};
add.call(o,5,7);//1+3+5+7=16,第一个参数是想要作为this的对象
add.apply(o,[5,7]);//16
function bar(){
console.log(Object.prototype.toString.call(this));
}
bar.call(7);//"[object Number]"
五.函数属性&arguments
function foo(x,y,z){
arguments.length;//2 实际传参的对象
arguments[0];//1
arguments[0]=10;
x;//10 严格模式下,仍然是1
arguments[2]=100;
z;//undefined!!! 未传入参数,则将失去绑定关系。
arguments.callee===foo;//true
}
foo.name;//foo
foo.length;//3 形参个数
foo(1,2);
argument是类数组的对象,原型并不指向Array.prototype,因此没有数组对象的方法。