首先,作为一个初入js的初学者,刚碰到这几个函数使用的时候都不大会用,不过后来慢慢学习例子,一点点理解,还是有点理解的,这个博客作为本人的首个专业博客,专门来记录一些平时需要注意的点,有错还希望能够请大家指出。
apply vs call
共同点:使用方法相同,call(“引用对象”,”值1”,”值2”);
不同点:传入的参数方式不同,apply传入的是一个数组,
例如,有一个函数定义如下:
var func = function(arg1, arg2) {
};
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
ps:这里分享一下一些常用用法:
数组中打散数组可以用concat或者可以用apply
1、数组之间追加
var array1=[1,3,5];
var array2=[54,"join"];
[].push.apply(array1,array2);
console.log(array1);
输出的结果为:[1,3,5,54,join]
这里可以理解成push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以我们也可以通过apply来装拯救这个数组,因为apply会打散一个数组,一个个传进来。
也可以写成array1.push.apply(array1,array2);
2、获取数组中的最大值和最小值
var numbers = [1,13,-3];
var maxInNumbers = Math.max.apply(Math, numbers), //13
maxInNumbers = Math.max.call(Math,1,13,-3); //13
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。但是用apply记得是传入一个数组,apply()里面第一个参数可以是Math,也可以是null,这个是因为没有对象去调用这个方法,我只需要用这个方法帮我运算,得到返回的结果就行。
但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决 var maxInNumbers=Math.max.apply(null,numbers),这样轻易的可以得到一个数组中最大的一项(apply会将一个数组装换为一个参数接一个参数的传递给方法,记住)
3、验证是否是数组(前提是toString()方法没有被重写过)
function isArray(obj){
return Object.prototype.toString.call(obj) === '[object Array]' ;
}
isArray的底层原理就是这个。
4、类(伪)数组使用数组方法
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这种方法可以将类数组转化为数组结构。
类数组有很多,比较特别的是arguments对象,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。
特性:和数组一样,都能用length,还有下标等,但不能用数组的方法,而且具有实效性(Live);
实效性就是每次动态更新,都会影响到伪数组的length,所以如果你没有给sum赋值为lis.length.而是直接写i小于lis.length,又因为length会因为创建一个节点而++,会导致死循环!!!
<ul id="nodelist">
<li class="lis">index0</li>
<li class="lis">index1</li>
<li class="lis">index2</li>
<li class="lis">index3</li>
<li class="lis">index4</li>
</ul>
<script>
var myUl = document.getElementById('nodelist');
var lis = myUl.getElementsByTagName('li');
for(var i=0,sum=lis.length;i<sum;i++){
li = document.createElement("li");
li.className="lis";
li.innerHTML="index"+(i+5);
myUl.appendChild(li);
}
</script>
bind
bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。
var text = function(){
console.log(this.x);
}
var wcc= {
x:3
}
text(); // undefined
var cqj= text.bind(wcc);
cqj(); // 3
这里面text() 执行的结果是undefined,因为是全局函数,当然this就是指window全局变量,所以没有值。
而cqj是一个经过bind绑定wcc对象的绑定函数,这里注意不能用call,因为call传参后是立即调用,而bind返回的是一个函数,可以想调就调,加()就行。
总结bind,apply,call
- 三者都是用来改变函数的this对象的指向的;
- 三者第一个参数都是this要指向的对象,也就是想指定的上下文,上下文就是指调用函数的那个对象。(点前的那个对象,没有就是全局window)
- 三者都可以传参,但是apply是数组,而call是有顺序的传入。
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即执行 。