差异:第二个参数的传递方式不同。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函数的源码