`
zhangjiahao8961
  • 浏览: 5189 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JavaScript call 与apply的用法(转)

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

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


实质:通过改变this指向,改变函数的调用对象。(this指向调用时才知道指向谁)

二、例子程序:
Java代码  
1. <html> 
2. <head> 
3. <script language="javascript"> 
4. /**定义一个animal类*/ 
5. function Animal(){ 
6.     this.name = "Animal"; 
7.     this.showName = function(){ 
8.         alert(this.name); 
9.     } 
10. } 
11. /**定义一个Cat类*/ 
12. function Cat(){ 
13.     this.name = "Cat"; 
14. } 
15.  
16. /**创建两个类对象*/ 
17. var animal = new Animal(); 
18. var cat = new Cat(); 
19.  
20. //通过call或apply方法,将原本属于Animal对象的showName()方法交给当前对象cat来使用了。 
21. //输入结果为"Cat" 
22. animal.showName.call(cat,","); 
23. //animal.showName.apply(cat,[]); 
24.   
25.  
26. </script> 
27. </head> 
28. <body></body> 
29. </html> 


以上代码无论是采用animal.showName.call或是animal.showName.apply方法,运行的结果都是输出一个"Cat"的字符串。说明showName方法的调用者被换成了cat对象,而不是最初定义它的animal了。这就是call和apply方法的妙用!

三、小结:
call和apply方法通常被用来实现类似继承一样的功能,以达到代码复用的功效。它们的区别主要体现在参数上。

。。。。。。。。。。。你所写的,只是call和apply最基本的作用。根本不是面向对象

你代码的修改版(一般情况已经够用)
Javascript代码  
1. <html>   
2. <head>   
3. <script language="javascript">   
4.  
5. function Animal(name){   
6.     this.name = name;   
7.     this.showName = function(){   
8.         alert(this.name);   
9.     }   
10. }   
11.  
12. function Cat(name){ 
13.     Animal.call(this, name); 
14. }   
15.  
16. var cat = new Cat("Black Cat");   
17.  
18. cat.showName(); 
19.  
20.    
21. </script>   
22. </head>   
23. <body></body>   
24. </html>   


更完全版
Javascript代码  
1. <html>   
2. <head>   
3. <script language="javascript">   
4.  
5. function Animal(name){   
6.     this.name = name;   
7.     this.showName = function(){   
8.         alert(this.name);   
9.     }   
10. }   
11.  
12. function Cat(name){ 
13.     Animal.call(this, name); 
14. }   
15.  
16. Cat.prototype = new Animal(); 
17.  
18. var cat = new Cat("Black Cat");   
19.  
20. cat.showName(); 
21.  
22. alert(cat instanceof Animal); 
23.  
24.    
25. </script>   
26. </head>   
27. <body></body>   
28. </html>   


call和apply都是基于this替换。把this的语义转了

模拟call, apply的this替换
Javascript代码  
1. function Animal(name){   
2.     this.name = name;   
3.     this.showName = function(){   
4.         alert(this.name);   
5.     }; 
6. }; 
7.  
8. function Cat(name){ 
9.     this.superClass = Animal; 
10.     this.superClass(name); 
11.     delete superClass; 
12. } 
13.  
14. var cat = new Cat("Black Cat");   
15.  
16. cat.showName(); 


1. function Animal(name) 
2. { 
3.     this.name = name; 
4. } 
5. function Dog(name) 
6. { 
7. this.name = name; 
8. this.base = Animal; 
9. this.base('animal');           
10. } 
11.  
12. var d = new Dog('dog.chen'); 
13. window.alert(d.name); 


为什么Dog传递的是'dog.chen',而结果居然是 'animal'?我想不明白
在 Dog的构造函数里面直接调用了 Animal的构造函数为什么会影响Dog的name的属性呢?

1. function Animal(name) {  
2.    this.name=name;  
3. }  
4.  
5. funciton Dog(name) {  
6.     this.base=Animal  
7.     this.base(name);   /*先执行父类的构造函数,此时父类构造函数中上下文的this,就是Dog构造函数中的上下文this*/ 
8.     this.name=name    //覆盖了父类中继承下来的this.name
9. } 


1. function Animal(name){ 
2.    this.name = name; 
3. } 
4. Animal.protptype.showName = function(){ 
5.    alert(this.name); 
6. } 
7. function Dog(name,color){ 
8.    Animal.call(this,name);   //相当于 java的super(); 
9.    this.color = color; 
10. } 
11. Dog.prototype = new Animal(); //继承父类的方法,书上说在这里调用无参数的构造函数是标准做法,但我不清楚为什么 
12. Dog.prototype.showColor = function(){ 
13.    alert(this.color); 
14. } 
15. var dog = new Dog('wangwang','white'); 
16. dog.showName();  //输出wangwang 
17. dog.showColor(); //输出white 


apply(),call()最常见的理解就是继承的概念,继承这个概念有点不好理解,我们可以从他的扩充函数作用域这个角度去理解:
《javascript高级程序设计》书上的例子:
window.color="red";
var o={color:"blue"};
function sayColor(){
    alert(this.color);
}
sayColor();//red
sayColor().call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue

sayColor()是全局函数,
sayColor().call(this);//red
sayColor.call(window);//red
这两个是显式的在全局作用域中调用函数方式

运行sayColor.call(o);时,函数的执行环境就改变了,这是函数中的this指向了o作用域改变到o中了。

在这里,使用call(),apply()扩充作用域的最大好处在于,对象不需要和方法有任何耦合关系。

另外再次从扩充作用域的角度去回顾之前的一片文章(Javascript 中的 call 继承(转载整理))的例子:

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

function webDever(name,age,sex){
   Person.call(this,name,age);//这里的Person作用域就变为了webDever里面的作用域了,Person原本的this指向的是全局,现在它的this指向webDever函数中,可以理解为webDever类就继承Person类,更加通俗的理解就是,Person函数可以在webDever的作用域中执行了
   this.sex=sex;
   this.alertSex = function(){
      alert(this.sex);
   }
}

var test= new webDever("愚人码头",28,"男");
test.alertName();//愚人码头
test.alertAge();//28
test.alertSex();//男
分享到:
评论

相关推荐

    javascript中apply和call方法的作用及区别说明

    1、call,apply都属于Function.prototype的一个方法,它是JavaScript引擎内在实现的,因为属于Function.prototype,所以每个Function对象实例(就是每个方法)都有call,apply属性。既然作为方法的属性,那它们的使用...

    Javascript中call,apply,bind方法的详解与总结

    以下内容会分为如下小节: 1.call/apply/bind方法的来源 2.Function.prototype.call() ...首先,在使用call,apply,bind方法时,我们有必要知道这三个方法究竟是来自哪里?为什么可以使用的到这三个方法?

    javascript中call,apply,bind函数用法示例

    主要介绍了javascript中call,apply,bind函数用法,结合实例形式分析了call,apply,bind函数的功能、使用方法与相关注意事项,需要的朋友可以参考下

    javascript中apply、call和bind的用法区分_.docx

    javascript中apply、call和bind的用法区分_.docx

    Javascript call和apply区别及使用方法

    JavaScript中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象

    开启Javascript中apply、call、bind的用法之旅模式

    在Javascript中,Function是一种对象。Function对象中的this指向决定于函数被调用的方式,使用apply,call 与 bind 均可以改变函数对象中this的指向。

    Javascript 中的 call 和 apply使用介绍

    简单的说就是改变函数执行的上下文,这是最基本的用法。两个方法基本区别在于传参不同。 call(obj,arg1,arg2,arg3);call第一个参数传对象,可以是null。参数以逗号分开进行传值,参数可以是任何类型。 apply(obj,...

    javascript中call apply 与 bind方法详解

    在JavaScript中,call、apply和bind是Function对象自带的三个方法,本文将通过几个场景的应用,来详细理解三个方法。 call() call() 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法。 ...

    javascript中call和apply的用法示例分析

    主要介绍了javascript中call和apply的用法示例分析,非常的详细,需要的朋友可以参考下

    跟我学习javascript的call(),apply(),bind()与回调

    JavaScript 中通过call或者apply用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。简单的说就是改变函数执行的上下文,这是最基本的用法。两个方法基本区别...

    简单对比分析JavaScript中的apply,call与this的使用

    call:调用一个对象的方法,用另一个对象替换当前对象。 语法:call([thisObj[, arg1[, arg2[, [, argN]]]]]) thisObj 可选。将作为当前对象使用的对象。 arg1, arg2, , argN 可选。将被传递到该方法的参数列表。 3....

    JavaScript中call和apply方法的区别实例分析

    主要介绍了JavaScript中call和apply方法的区别,结合实例形式分析call和apply方法的功能、原理及相关使用操作区别,需要的朋友可以参考下

    javascript中call,apply,callee,caller用法实例分析

    主要介绍了javascript中call,apply,callee,caller用法,结合实例形式分析了javascript中call,apply,callee,caller功能、使用方法及相关操作注意事项,需要的朋友可以参考下

    Javascript中call和apply函数的比较和使用实例

    一些简单的Javascript操作中较少会用到call和apply函数,在另外一些较大型的操作中,如web应用开发,js框架开发中可能会经常遇到这两个函数。关于这两个函数的解释,网上的资料也很多,但是本人认为很多资料要么...

    javascript中call和apply方法浅谈

    例如,如果要想以对象o的方法来调用函数f,可以按如下的方式使用call和apply方法: 代码如下: f.call(o); f.apply(o);可以按如下的代码来理解: 代码如下: o.m = f; //将f存储为o的临时方法 o.m(); //调用这个...

    javascript基于原型链的继承及call和apply函数用法分析

    主要介绍了javascript基于原型链的继承及call和apply函数用法,结合实例形式较为详细的分析了javascript中继承的概念、创建方法以及call和apply函数的功能与使用技巧,需要的朋友可以参考下

    call&&apply的一些小用法以及原型

    JavaScript中的call以及apply与原型的相关操作,学习JavaScript中的一些小细节,深入了解JavaScript的相关语法,了解JavaScript中的语法核心

Global site tag (gtag.js) - Google Analytics