JavaScript函数

JavaScript函数

一、函数和方法

JavaScript中定义函数有两种方法:

function hanshu(){
	alert("hello");
}
var hs = function (x){    //通过变量定义一个函数
  alert(x);	
};
hs("hello");

在JavaScript中允许传入任意个参数而不影响调用。

Arguments关键字,只在函数内部有效,指向传入函数的参数,类似一个数组,但不是数组;可以用它判断传入的参数个数。

function test(x) {
    alert(x); // 10
    for (var i=0; i<arguments.length; i++) {
        alert(arguments[i]); // 会依次输出10, 20, 30
    }
}
test( 10,20, 30);

rest参数获取多出的参数;

function fun1(...rest) {
alert('多出参数:'+rest+'参数个数:'+rest.length);
}
 
fun1();  // 输出多出的参数(一个数组)和参数个数
fun1(5);   //多出参数:5 参数个数:1
fun1(5, 6, 7); 

在JavaScript中,会把函数中的申明提前,但是赋值不会提前。函数内外有重名变量,函数会屏蔽外部变量,就是说重名时在函数内部的申明有效(只是在这个函数体中)。

全局变量,实际上函数体也是一个全局变量。

局部变量,函数体内部的申明。

名字空间:

var MYAPP = {};//申明一个名字空间
//添加变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;
// 添加函数:
MYAPP.foo = function () {
    return 'foo';
};

const代替var定义一个常量,还有let,定义一个局部变量


方法,在一个对象中绑定函数,称为这个对象的方法(两种写法):

var xiaoming = {
    name: '小明',
    birth: 1995,
    age: function () {
        var y = new Date().getFullYear();
        return y - this.birth;
    }
};
alert(xiaoming.age()); //现在年龄

function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}
var xiaoming = {
    name: '小明',
    birth: 1995,
    age: getAge
};
alert(xiaoming.age());
//getAge();            //函数this指向window的,会返回NaN
//getAge.apply(xiaoming, []); //this指向xiaoming, 参数为空

var that = this;,你就可以放心地在方法内部定义其他函数,而不是把所有语句都堆到一个方法中。

另一个与apply()类似的方法是call(),唯一区别是:

                                        apply()把参数打包成Array再传入;

                                        call()把参数按顺序传入。

比如调用Math.max(3,4,5),分别用apply()和call()实现如下:

Math.max.apply(null, [3, 5, 4]); // 5
Math.max.call(null, 3, 5, 4); // 5

二、Array的几个方法

map()

array.map(hanshu);//则函数hanshu()对数组的每个value操作过一遍hanshu()

reduce()

arr.reduce(function (x, y) {
    return x + y;
}); // reduce中必须传入两个参数,把结果继续和序列的下一个元素做累积计算

filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

var arr = [1, 2, 4, 5, 6, 9, 10, 15];
var r = arr.filter(function (x) {
    return x % 2 !== 0;
});

使用回调函数,element是指向当前元素,index指向当前元素索引,self'指向它本身的,可以用filter()除去重复的数

arr.filter(function (element, index, self) {
     return self.indexOf(element) === index;
});

sort()方法的默认排序规则(字符串根据ASCII码进行排序),也可以自定义排序。

通常规定,对于两个元素xy,如果认为x < y,则返回-1,如果认为x == y,则返回0,如果认为x > y,则返回1

['Google', 'Apple', 'Microsoft'].sort(); // ['Apple', 'Google', 'Microsoft'];按照ascll码排序
//自己定义排序规则,
var arr = [10, 20, 1, 2];
arr.sort(function (x, y) {
    if (x < y) {
        return -1;    //返回-1,则位置不变
    }
    if (x > y) {
        return 1;   //返回1,xy交换位置
    }
    return 0;
});                 //arr=[1, 2, 10, 20]  sort()是直接对数组进行修改的

sort()是直接对array进行修改的,而不是返回一个新的数组。

三、闭包

一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。如上面的几个高阶函数。

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。不是返回结果,而是返回一个函数。

function _sum() {
    var sum = function (){
       var x;
       return x;
    };    
    return sum;
}
var f = _sum();
f();
alert(f);//返回function (){ var x; return x;}; 

_sum返回函数sum时,相关参数和变量都保存在sum中,形成一个闭包,每次调用都是返回一个新的闭包。

//返回的闭包是一个函数,所以要再次调用这个闭包才能实现它
var f = _sum();
f();

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量;因为闭包中函数不是立即执行的。

function count() {
    var arr = [];
    for (var i=1; i<=3; i++) {
        arr.push(function () {
            return i * i;
        });
    }
    return arr;          //返回function(){return i*i;}
}

方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变。

arr.push((function (n) {
            return function () {
                return n * n;
            }
        })(i));   //最后返回的是(function (n){return function(){ return n*n;}})(i)把i绑定了

JavaScript完成一个计数器:(以下两种实现是一样的)可以再返回的function中用变化的数,但不能用在外边

function create_counter(initial) {
    var x = initial || 0;
    var cc=function () {
         alert(x);
         x += 1;
         return x;
      };
  return cc;   
}
var c1 = create_counter();
c1();
c1();
c1();

function create_counter(initial) {
    var x = initial || 0;
    return {
        inc: function () {
            x += 1;
            return x;//对应对象中key(inc)的value(x)
        }
    }
}
var c1 = create_counter();
c1.inc();//1  第一次调用返回一个
c1.inc();//2
c1.inc();//3

四、箭头函数

第一种,只含有一个一个表达式:

/*x => x * x
(x,y)=>x*x//两个参数
x =>({x:y})//返回一个对象
*/
//等价于上面个第一条语句
function (x) {
    return x * x;
}

第二种,包含多条语句

x => {
    if (x > 0) {
        return x * x;
    }
    else {
        return - x * x;
    }
}

this在箭头函数中已经按照词法作用域绑定了,用call()或者apply()调用箭头函数时,无法对this进行绑定,即传入的第一个参数被忽略:

var obj = {
    birth: 1990,
    getAge: function (year) {
        var b = this.birth; // 1990
        var fn = (y) => y - this.birth; // this.birth仍是1990
        return fn.call({birth:2000}, year);
    }
};
obj.getAge(2015); 

五、generator

generator由function*定义(注意多出的*号),并且,除了return语句,还可以用yield返回多次。就是一个可以多次返回的函数,例如在一个数组中,不用返回整个数组就能获取到多个需要的数。

function* foo(x) {
    yield x + 1;
    yield x + 2;
    return x + 3;
}
//调用
var f=foo();//创建一个generator对象
f.next();//获取返回的数
f.next();
//第二种调用迭代循环fib

for (var x of fib()) {
    console.log(x);
}

完成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值