call and apply

来源:互联网 发布:防蹭网软件手机版 编辑:程序博客网 时间:2024/05/04 08:30

Call apply

1、方法定义

call方法: 
语法:call([thisObj[,arg1[, arg2[,  [,.argN]]]]]) 
定义:调用一个对象的一个方法,以另一个对象替换当前对象。 
说明: 
call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。 
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。 

apply方法: 
语法:apply([thisObj[,argArray]]) 
定义:应用某一对象的一个方法,用另一个对象替换当前对象。 
说明: 
如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。 
如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。

 

谁在call前就用谁的方法。

Call后后面的第二参数可以是随便任何东西,apply的有限制,数组,argument。。。

functionAnimal(){ 

    this.name = "Animal"; 

    this.showName = function(){ 

        alert(this.name); 

    } 

 

functionCat(){ 

    this.name = "Cat"; 

 

varanimal = new Animal(); 

varcat = new Cat(); 

 

//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。 

//输入结果为"Cat" 

animal.showName.call(cat,","); 

//animal.showName.apply(cat,[]);

把 animal 的方法放到cat上执行,原来cat是没有showName() 方法,现在是把animal 的showName()方法放到 cat上来执行,所以this.name 应该是 Cat

 

实现继承

function Animal(name){   

    this.name = name;   

    this.showName = function(){   

        alert(this.name);   

    }   

 }   

  

 function Cat(name){ 

    Animal.call(this, name); 

 }   

  

 varcat = new Cat("Black Cat");  

 cat.showName();

 

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

 

 

2 javascript的方法可以分为三类:

a 类方法(如果没有声明实例,直接调用方法,就是类方法)

b 对象方法(如果用的是实例来调用的方法,就是对象方法。)

c 原型方法

function People(name)
{
 this.name=name;
 //对象方法
 this.Introduce=function(){
    alert("My name is "+this.name);
  }
}
//类方法
People.Run=function(){
  alert("I can run");
}
//原型方法
People.prototype.IntroduceChinese=function(){
  alert("我的名字是"+this.name);
}

var p1=new People("Windking");
p1.Introduce();
People.Run();
p1.IntroduceChinese();

 

A.prototype = new B();

理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。

其实与继承很像。

function baseClass()

{

   this.showMsg = function()

    {

       alert("baseClass::showMsg");  

    }

}

 

function extendClass()

{

   this.showMsg =function ()

    {

       alert("extendClass::showMsg");

    }

}

 

extendClass.prototype = new baseClass();

var instance = new extendClass();

 

instance.showMsg();//显示extendClass::showMsg

http://www.cnblogs.com/frostbelt/archive/2012/04/01/2428014.html

实验证明:函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。

用call或prototype实现继承

function Person(name){    //父类

    this.name=name;

    this.SayHello=function(){alert("Hello, I'm "+this.name);};

}

function Employee(name,salary){   //子类

    Person.call(this,name);       //将this传给父构造函数

    this.salary=salary;

    this.ShowMeTheMoney=function(){alert(this.name+" $"+this.salary);};

}

 

var BillGates=new Person("Bill Gates");

var SteveJobs=new Employee("Steve Jobs",1234);

 

BillGates.SayHello();  //显示:I'm Bill Gates

SteveJobs.SayHello();  //显示:I'm Steve Jobs

SteveJobs.ShowMeTheMoney();  //显示:Steve Jobs $1234

 

alert(BillGates.constructor == Person);   //true

alert(SteveJobs.constructor == Employee); //true

直接定义prototype似乎更有extends的意韵

function Person(name){    //父类

    this.name=name;

    this.SayHello=function(){alert("Hello, I'm "+this.name);};

}

function Employee(salary){   //子类

    this.salary=salary;

    this.ShowMeTheMoney=function(){alert(this.name+" $"+this.salary);};

}

Employee.prototype=new Person("Steve Jobs");

var SteveJobs=new Employee(1234);

 

SteveJobs.SayHello();  //显示:I'm Steve Jobs

SteveJobs.ShowMeTheMoney();  //显示:Steve Jobs $1234

练习实例:call.html

那么又会有一个新的问题:

如果我想使用extendClass的一个实例instance调用baseClass的对象方法showMsg怎么办?

extendClass.prototype = new baseClass();

var instance = new extendClass();

var baseinstance = new baseClass();

baseinstance.showMsg.call(instance);//显示baseClass::showMsg

0 0
原创粉丝点击