又一天过去了。今天过得怎么样,梦想是不是更远了?
###JavaScript函数
函数是一块JavaScript代码,被定义一次,但可以执行和调用多次.JavaScript中的函数也是对象,所以函数可以像其他对象那样操作和传递,所以也常叫JavaScript中的函数为函数对象。
这是一个标准的函数由函数名,参数列表,函数体组成:1
function foo(x,y){
if(typeof x == 'number' && typeof y ==='number'){
return x + y;
}else{
return 0;
}
}
foo(1,2); // 3
函数不同的调用方法:1
foo();//直接调用
o.method();//对象方法
new Foo();//构造器
func.call(o);// call/apply/bind
创建函数 常用的两种方式就是函数声明和函数表达式
一个完整以function 开头定义一个函数叫函数声明
将一个函数赋值给一个变量叫做函数表达式
匿名函数自执行也是函数表达式
将函数对象作为一个返回值也是函数表达式
有名字的函数赋值给一个变量叫做命名式函数表达式
函数声明1
function add(a,b){
a = +a; //+ a 如果a是字符串会把a转化为number
b = +b;
if(isNaN(a) || isNaN(b)){
return ;
}
return a + b;
}
函数表达式1
// function variable
function add(a,b){
// do something
}
//IFE(立即执行函数)
(function(){
//do sth
})()
return function(){
//do sth
}
//NFE(命名函数表达式)
var add=function foo(a,b){
//do sth
}
函数声明和表达式的区别
函数声明和变量声明 会被前置但是 赋值给变量声明的函数不会被前置
函数声明不能被立即调用
命名式函数表达式有很多Bug,不推荐使用1
var num=add(1,2);
console.log(num); //result: 3
function add(a,b){
a = +a; //+ a 如果a是字符串会把a转化为number
b = +b;
if(isNaN(a) || isNaN(b)){
return ;
}
return a + b;
}
/*
*/
var num=add(1,2);
console.log(num); //报错,找不到函数
var add=function(a,b){
a = +a; //+ a 如果a是字符串会把a转化为number
b = +b;
if(isNaN(a) || isNaN(b)){
return ;
}
return a + b;
}
用函数构造器创建函数并不常见,函数构造器创建的函数可以拿到全局变量 但是拿不到外层函数的局部变量1
var func=new Function('a','b','console.log(a+b);');
func(1,2);//3
var func=Function('a','b','console.log(a+b);');
func(1,2);//3
this 全局的this 一般指向全局对象,在浏览器里面一般指window1
console.log(this.document === document); //true
console.log(this === window);// true
this.a=37;
console.log(window.a);//37
一般函数的this 也是指向window nodejs 指向 global1
function f1(){
return this;
}
f1() === window //true
function f2(){
"use strict";// see strict mode
return this;
}
f2() === undefined // true
函数如果作为一个对象的属性,常叫做对象的方法。
调用对象方法的时候一般this会指向对象
只要函数作为对象的方法调用,this就会指向对象1
var o={
pop:37,
f:function(){
return this.pop;
}
};
console.log(o.f());// 37
var o={pop:37};
function independent(){
return this.pop;
}
o.f=independent;
console.log(o.f);//37
对象原形链上的this,调用对象原形上的方法的时候,原形上的this还是指向当前调用对象1
var o={f:function(){return this.a + this.b}};
var p=Object.create(o);
p.a=1;
p.b=4;
console.log(p.f()); //5
当使用New来创建一个构造器调用的时候 ,this 会指向函数的prototype .
最后函数的返回值如果没写return语句或者return 的是一个基本类型的话会将this返回 ,
如果最后return语句返回的是一个对象的话会将对象作为返回值1
function MyClass(){
this.a=37;
}
var o=new MyClass();
console.log(o.a);//37
function c2(){
this.a=37;
return {a:38}
}
o=new c2();
console.log(o.a);//38
call 和apply可以修改函数执行时里面的this
通过call方法第一个参数作为你想当作this的对象 ,后面的是想要去添加的参数
apply 传参时把参数作为数组传进去1
function add(c,d){
return this.a + this.b + c + b;
}
var o={a:1,b:3};
add.call(a,5,7);//1+3+5+7=16
add.apply(o,[10,20]);//1+3+10+20=34
function bar{
console.log(Object.prototype.toString.call(this))
};
bar(7);// object number
bind 会按照之前绑定的 this1
function f(){
return this.a;
}
var g=f.bind({a:'test'});
console.log(g());//test
var o={a:37,f:f,b:b};
console.log(o.f(),o.g());//37,test
函数属性 arguments
可以通过 函数对象的length属性 拿到 函数参数的长度 ,通过name属性拿到函数名字
实际传参的个数 可以通过 arguments.length拿到
arguments 是一个类数组的对象,他的原形并不是Array.prototype
可以通过索引 访问arguments对象
如果参数没有传进来的话 实际上arguments和对应的参数是没有绑定关系的
在严格模式下 arguments 无法改写 参数1
function foo(x,y,z){
arguments.length;//2
arguments[0];//1;
arguments[0]=10;
x;//10
arguments[2]=100;
z; //undefined
arguments.callee === foo;//true callee 属性是 arguments 对象的一个成员,他表示对函数对象本身的引用,这有利于匿名函数的递归或确保函数的封装性
}
foo(1,2);
foo.length;//3
foo.name;//foo