创建函数:
//函数声明:可前置(在声明前调用)
function add(a,b) {
}
//函数表达式:
var add=function(a,b){};
(function(){//do sth})();
return function(){
//do sth
};
var add=function foo(a,b) {
//do sth
};
//函数构造器
var func1 = new Function('a','b','console.log(a+b);');
var func2 = Function('a','b','console.log(a+b);');
//Function内部申明的变量是局部的,不可使用外层函数声明的变量,可使用全局变量。
三种方式的比较:
(图片截自慕课网)
函数表达式可赋值给变量,通过变量名调用;
函数构造器只能是匿名的形式
不同的调用方式:
fun();
new fun();
obj.fun();
fun.call(o),fun.apply(o);
//第一个参数是对象,如果是基本类型,会转成对象,如果传的是null或者undefined,会转成window(浏览器下)或global,严格模式下不变
function fun(c) {
return this.a+this.b+c;
}
var o = {a:1,b:3};
add.call(o,5);//1+3+5;
add.apply(o,[5]);//1+3+5;
this
//全局里this===window
//类函数里的this
var o = {
prop:37,
f:function() {
return this.prop;//指向类,37
}
//普通函数里的this
function() {
return this;//window
}
//原型链上的this
var o = {f:function(){return this.a+this.b;}};
var p = Object.create(o);//继承
p.a=1;
p.b=4;
//原型链上的this可以指向当前类的a,b;
p.f();//5
//defineProperty添加的函数里的this指向调用的类
返回值
1.如果没有返回值或返回基本类型,那么将返回this(当前类)
2.如果返回了一个类,如return {a:38},那么将吧这个返回值赋给变量
bind函数
//例1
function f() {
return this.a;
}
var g = f.bind({a:"test"});
g();//test
var o = {a:37,f:f,g:g};
o.f();//37
o.g();//37,绑定后的值不受影响
//例2
this.x=9;
var m = {
x:81,
getX:function(){return this.x;}//指向类,81
var getX=m.getX;//指向window,9
var bindGetX = getX.bind(m);//绑定了类,this指向类
}
//绑定参数,调用时改参数都是这个值
function getConfig(color, size, otherOptions) {
//...
}
var defaultConfig=getdConfig.binf(null,"#cc0000","100*100");//第三个参数不指定
defaultCinfig("123");//至指定第三个
function foo(){
this.b=100;
return this.a;
}
var func=foo.bind({a:1});
func();//1
new func();//{b:100},返回this,new在this层面忽略bind
函数的属性和方法
function foo(x,y,z) {
arguments.length;//2
arguments[0];//1
arguments[0]=10;//x=10;数组与x绑定,但是严格模式下x不会改变
arguments[2]=100;//z undefined,未传参数失去绑定关系
arguments.callee === foo;//true,严格模式下禁止使用
}
foo(1,2);
foo.length;//3
foo.name//"foo"