差异:第二个参数的传递方式不同。call必须明确传递参数(逐个列举出来),而apply可以传递参数数组。
call,apply:是非继承方法;最重要是能够扩充函数赖以生存的作用域
bind:这个方法会创建一个函数的实例,bind会接收一个参数,参数值决定this的指向
callee:是arguments(保存函数参数)对象的一个属性,该属性是一个指针。指向拥有这个arguments对象的函数
caller:是函数对象的属性,保存着调用当前函数的,函数的引用。如果是在全局作用域下调用当前函数,它的值为null
下面拿出书中例子加以详细说明:
/* ****demo0 (call,apply)关于继承的应用**** */ function Super(name) { this.name = name; } function Sub() { //继承了Super 同时传递了参数、 Super.call(this,'dongzhen'); //实力属性 this.age = 29; } var intance = new Sub(); console.log(intance.name); /* ****demo1 (call,apply)利用其传递参数**** */ function sum(num1, num2){ return num1 + num2; } function callSum1(count1, count2){ //这里要是用call就这样传递参数,逐个传参。 return sum.call(this,count1,count2); return sum.apply(this,arguments); //可能对传入的参数arguments不解,他就是函数callSum1的参数 //这里的this值是指的是window因为callSum1函数是在window下调用的。 return sum.apply(this,[count1,count2]); } console.log(callSum1(10,10)); //20 /* ****demo2 (call,apply)在不同的作用域下,实现同一种方法**** */ window.name = 'tom'; var objName = { name: 'jack'}; function getName(){ console.log('name-- '+this.name); } //在参数window对象下,调用getName方法时this值为window。相当于window.name的运行结果为tom getName.call( window ); //tom //传入的参数为objName对象下,调用getName方法时this值为objName对象,其对应的那么值为jack getName.call( objName ); //jack /* ****demo3 bind的使用**** */ window.color = 'red'; var o = { color: 'blue'}; function getColor(){ console.log( this.color ); } //传给bind的参数为o字面量对象,所以调用getColor的时候此方法的this值指向了字面量对象o; var getObjColor = getColor.bind(o); getObjColor(); //blue /* ****demo4 callee的使用**** */ //阶乘函数 function factirial(num){ if(num <= 1){ return 1; }else{ // 等同于 num * factirial(num-1) return num * arguments.callee(num-1); } } /* ****demo5 caller的使用**** */ function outer(){ inner(); } function inner(){ console.log(arguments.callee.caller); } outer(); //显示outer函数的源码