JS中最大最小值的计算技巧
在JS中如果要计算最大值最小值,我们第一个会想到的就是Math.max方法和Math.min方法,但是这两个方法你真的了解吗?我们今天一起来讲讲这两个方法的一些知识。
现在我们有几个数字,比如11,7,23,9,18,6这几个数字,如果我们想得出其中的最大值,那么很简单,只需要使用Math.max方法即可,如下:
var result = Math.max(11,7,23,9,18,6);
result就是这几个数字的最大值,很简单。
不过有时候我们所遇到的场景会稍微复杂一些,如果现在这一些数字的存在形式是数组,如[11,7,23,9,18,6],那我们还能如此简单的得到最大值吗?
var data = [11,7,23,9,18,6];
var result = Math.max(data);
此时result的值是这些数字中的最大值吗?不是这样的,此时result是NaN,获取不到最大值。
因此,Math.max的方法是需要多个参数的,不能只能是一个数组。
也许有些同学会做如下的尝试:
var data = [11,7,23,9,18,6];
var str = "";
for(var i=0;i<data.length;i++){
str += data[i] + ",";
}
str = str.substr(0,str.length-1);
console.log(str);//此时str为 11,7,23,9,18,6
var result = Math.max(str);
这种做法可行吗?很可惜,也不行,虽然通过循环遍历的方式将数组中的元素全部取出来并且以逗号进行连接,看似满足了Math.max方法对参数的要求,其实并没有,因为生成出来的str是一个字符串,传递到Math.max方法中依然是只有一个参数。所以,得出一个简单的结论,Math.max方法是需要多个参数的,不能是一个数组,不能是一个字符串。是需要多个数字参数。
那么,如果我们就是拥有一个数组,如何得到数组中的最大值呢?有以下三种方法:
第一种方法比较傻,不推荐使用,如下:
var data = [11,7,23,9,18,6];
var result = Math.max(data[0],data[1],data[2],data[3],data[4],data[5]);
第二种方法比较简单,通过循环遍历就可以得出:
var data = [11,7,23,9,18,6];
var max = data[0];
for(var i=0;i<data.length;i++){
if(max < data[i]){
max = data[i];
}
}
console.log(max);
第三种方法有一些技巧:
var data = [11,7,23,9,18,6];
var result = Math.max.apply(null,data);
console.log(result);
下面对第三种方法做一个讲解。
通过之前的结论我们已经得出Math.max方法需要的是多个数字参数,如果我们能将数组中的每一个元素依次当作Math.max方法中的每一个参数,就像方法一那样,那么就可以得出最大值,第一种方法的弊端是在于数组的长度有可能是不确定的。apply这个方法就可以帮助我们把这个问题解决。
我们来了解一下apply这个方法。
var tom = {
name:"I am tom",
sayHello:function(arg1,arg2,arg3){
console.log(this.name + ",say hello to:" + arg1 + "," + arg2 + "," + arg3);
}
};
tom.sayHello("zhangsan","lisi","wangwu");
tom这个对象中拥有一个方法sayHello,所以tom可以直接调用sayHello这个方法,没有任何问题。下面又有一个对象jerry,如下:
var jerry = {
name:"I am jerry",
};
jerry.sayHello("zhangsan","lisi","wangwu");
jerry中没有sayHello这个方法,如果调用这个方法的话,必然会报错。
如果我们就是想让jerry调用sayHello这个方法,此时就可以使用apply,让tom中的sayHello方法作用在jerry之上。
var jerry = {
name:"I am jerry",
};
tom.sayHello.apply(jerry,["zhangsan","lisi","wangwu"]);
让tom中的sayHello这个方法作用在jerry之上,就是相当于让jerry调用了tom中的sayHello这个方法。那tom中的sayHello这个方法是需要参数的,参数就在apply的第二个参数指定,注意,apply的方法第二个参数要求的是一个数组。
在tom中的sayHello这个方法是需要三个参数的,而在使用apply方法让jerry调用此方法的时候,apply会将其第二个参数的那个数组里面的每一个元素取出来,一一的对应在tom的sayHello方法,这个是apply的特性,所以我们使用Math.max.apply(null,数组)方法的时候第二个参数就应该是一个数组,刚好和我们的场景一致。
那下面来讲讲Math.max.apply(null,数组)中的第一个参数null.
var tom = {
name:"I am tom",
sayHello:function(arg1,arg2,arg3){
console.log(this.name + ",say hello to:" + arg1 + "," + arg2 + "," + arg3);
}
};
tom.sayHello("zhangsan","lisi","wangwu");
var jerry = {
name:"I am jerry",
};
tom.sayHello.apply(jerry,["zhangsan","lisi","wangwu"]);
上面两次调用sayHello方法打印的日志如下:
I am tom,say hello to:zhangsan,lisi,wangwu
I am jerry,say hello to:zhangsan,lisi,wangwu
第一个的name是tom,因为是tom调用的,所以在sayHello中的this指的就是tom,第二个是jerry,因为是通过apply的方式让jerry调用了此方法,所以此时sayHello中的this指的是jerry,而jerry中又有一个属性name.
如果我这样写代码:
tom.sayHello.apply(null,["zhangsan","lisi","wangwu"]);
这时候的日志是:
,say hello to:zhangsan,lisi,wangwu
注意,前面this.name没有任何输出,为什么呢?是因为如果apply中的第一个参数传null,就相当于是让window调用了tom中的sayHello中方法,所以此时的sayHello中的this指的是window,而window中没有name这个属性,所以就没有任何的打印,如果我给window增加一个属性:
window.name = "I am window";
tom.sayHello.apply(null,["zhangsan","lisi","wangwu"]);
此时的打印为:
I am window,say hello to:zhangsan,lisi,wangwu
由此可以证明,如果apply的第一个参数传null,指的是让window调用某一个方法。
所以Math.max.apply(null,数组)指的就是让window调用Math.max方法,得到数组中的最大值。
|
|