js之call()、apply()方法

call()解读可参见:MDN-call()
apply()解读可参见:MDN-apply()

每个函数都包含两个非继承而来的方法:apply()call()

call与apply都属于Function.prototype的一个方法,所以每个function实例都有call、apply属性。


作用

call()方法和apply()方法的作用相同:改变this指向

call()apply()方法能劫持另外一个对象的方法,继承另外一个对象的属性


call()

obj1.(method).call(obj2,argument1,argument2)

如上,call()的作用就是把obj1的方法放到obj2上使用,后面的argument1…这些做为参数传入。

function add (x, y) 
{ 
    console.log (x + y);
} 
function minus (x, y) 
{ 
    console.log (x - y); 
} 
add.call (minus , 1, 1);    //2 

这个例子中的意思就是用 add 来替换 minus ,add.call(minus ,1,1) == add(1,1) ,所以运行结果为:console.log (2); // 注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。

A.call(B,x,y)

就是把A的函数放到B中运行,x 和 y 是A方法的参数。

call()来实现继承,用this可以继承myfunc1中的所有方法和属性。

function myfunc1(){
    this.name = 'Lee';
    this.myTxt = function(txt) {
        console.log( 'i am',txt );
    }
}
 
function myfunc2(){
    myfunc1.call(this);
}
 
var myfunc3 = new myfunc2();
myfunc3.myTxt('Geing'); // i am Geing
console.log (myfunc3.name);	// Lee

apply()

func.apply(thisArg, [argsArray])

thisArg对象将代替functhis对象。如果 argArray 不是一个有效的数组或者不是 arguments 对象(类数组对象),那么将导致一个 TypeError。
argArray数组里的元素将作为单独的参数传给 func 函数。如果没有提供 argsArray 和 thisArg 任何一个参数,那么 Global 对象将被用作 thisArg , 并且无法被传递任何参数。

function Person(name,age)
{
	this.name=name;
	this.age=age;
}

function Student(name,age,grade)
{
	Person.apply(this,arguments);
	this.grade=grade;
}

var student=new Student("zhangsan",21,"一年级");
console.log(student.name+"-"+student.age+"-"+student.grade);//zhangsan-21-一年级

分析:Person.apply(this,arguments);
用构造器调用函数,this就是当前对象本身,此时代表的是Student。
arguments是类数组对象,此时是[“zhangsan”,21,“一年级”]。
最后去执行Person里面的内容。

apply的妙用: 可以将一个数组默认的转换为一个参数列表([param1,param2,param3] 转换为 param1,param2,param3)

apply() 将数组添加到另一个数组
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);//与下区别?prototype 原型
//Array.prototype.push.apply(array,elements);
console.info(array); // ["a", "b", 0, 1, 2]

//这里如果直接push()的话,是直接将elements数组添加到array中,而不是将元素添加进去
array.push(elements);
console.info(array);//["a", "b", [0, 1, 2]]
使用 apply() 和内置函数
/* 找出数组中最大/小的数字 */
var numbers = [5, 6, 2, 3, 7];

/* 应用(apply) Math.min/Math.max 内置函数完成 */
var max = Math.max.apply(null, numbers); /* 基本等同于 Math.max(numbers[0], ...) 或 Math.max(5, 6, ..) */
var min = Math.min.apply(null, numbers);

/* 代码对比: 用简单循环完成 */
max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max)
    max = numbers[i];
  if (numbers[i] < min) 
    min = numbers[i];
}

注:JavaScript引擎的参数个数有限制(JavaScript 核心中已经做了硬编码 参数个数限制在65536),不同的JavaScript引擎有差异,超出限制会导致参数丢失。


apply 和call 是可以实现继承和多重继承

继承

function Animal(name,age){
      this.name = name;
      this.age = age;
      this.showName = function(){
           alert(this.name);
      }
      this.showAge = function(){
           alert(this.age);
      }
}

function Cat1(name,age){
      Animal.call(this, name,age);
}

function Cat2(name,age){
      Animal.apply(this,arguments);
}

var cat1 = new Cat1("Black Cat1","1");
var cat2 = new Cat2("Black Cat2");
cat1.showName();
cat2.showName();

Animal.call(this) 与Animal.apply(this) 的意思就是使用 Animal对象代替this对象,那么 Cat1,Cat2中不就有Animal的所有属性和方法了吗,Cat1,Cat2 对象就能够直接调用Animal的方法以及属性了。

多重继承

function Class10(){
     this.showSub = function(a,b){
          alert(a-b);
     }
}

function Class11(){
     this.showAdd = function(a,b) {
           alert(a+b);
     }
}

function Class2() {
    Class10.call(this);
    Class11.call(this);
}

function Class3() {
     Class10.apply(this);
     Class11.apply(this);
}

call()与apply()区别

他们的区别在于接收参数的方式不同:

call():第一个参数是this值没有变化,变化的是其余参数都直接传递给函数。在使用call()方法时,传递给函数的参数必须逐个列举出来

apply():传递给函数的是参数数组

function add(c, d){ 
    return this.a + this.b + c + d; 
} 
var zzz = {a:1, b:3}; 
add.call(zzz, 5, 7); // 1 + 3 + 5 + 7 = 16 
add.apply(zzz, [10, 20]); // 1 + 3 + 10 + 20 = 34 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值