`
zhangjiahao8961
  • 浏览: 5362 次
  • 性别: 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中call与apply的进一步探讨

    `apply`方法与`call`类似,主要区别在于传递参数的方式。`apply`接受两个参数:第一个参数同样是`this`值,第二个参数是一个数组或类数组对象,其中的元素作为函数的参数: ```javascript func.apply(thisArg, ...

    js中call与apply的用法小结

    JavaScript中的继承通常通过原型链实现,`call`和`apply`能帮助我们创建子类并继承父类的方法。例如: ```javascript function baseA() { // base Class A code } function childA() { baseA.call(this); // ...

    理解JavaScript的caller callee call apply

    ### 理解JavaScript中的`caller`, `callee`, `call`, `apply` #### Arguments对象:JavaScript函数调用的参数管理器 在JavaScript中,每个函数都有一个隐含参数`arguments`,它允许开发者访问传递给函数的所有参数...

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

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

    浅谈javascript中的call、apply、bind_.docx

    JavaScript 中的 call、apply、bind 方法详解 JavaScript 中的 call、apply、bind 方法是 Function 对象自带的三个方法,这三个方法的主要作用是转变函数中的 this 指向,从而可以达到“接花移木”的效果。下面将对...

    call与apply区别 详细解读.pdf

    call和apply是JavaScript中的两个重要方法,它们都是Function.prototype中的方法,这意味着每个函数都可以使用这两个方法。它们的作用是改变函数体内的this对象的值,以扩充函数赖以运行的作用域。 相同点:call和...

    javascript中call和apply方法浅谈

    `apply`方法与`call`类似,但它处理参数的方式略有不同。`apply`也接受两个参数:第一个参数同样是`this`的指向,第二个参数是一个数组或类数组对象,其元素会被作为单独的参数传递给被调用的函数。继续使用上面的...

    js中call与apply的用法小结.docx

    接下来,`apply`的用法与`call`类似,但参数传递方式不同。`apply`的语法是`func.apply(context, [argsArray])`。这里,`context`同样用于指定`this`的值,而`argsArray`是一个数组或类数组对象,其元素会被作为单独...

    Js的call与apply1

    JavaScript中的`call`和`apply`是两种非常关键的方法,它们允许我们改变函数内部`this`的指向,同时也为实现模拟继承提供了可能。虽然JavaScript不直接支持类继承,但通过`call`和`apply`,我们可以实现类似的效果。...

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

    bind()方法与apply和call不同,它不会立即执行函数,而是创建一个新的函数,当这个新函数被调用时,它的this被绑定到bind()方法的第一个参数,即传入的上下文对象。bind()可以传递部分参数给原函数。 ```javascript...

    【JavaScript源代码】JavaScript函数之call、apply以及bind方法案例详解.docx

    JavaScript中的call、apply和bind方法都是用来改变函数调用时的上下文(即this值)以及传递参数。它们之间的相同点在于,都能够指定函数执行时的this对象,并且都能接收参数。不同点在于它们的调用方式和执行时机。 ...

    Javascript call和apply区别及使用方法

    ### Javascript call和apply区别及使用方法 在JavaScript中,`call`和`apply`方法被用于显式地设定函数体内`this`的值,这是所谓的函数借用(method borrowing)或函数上下文改变(context changing)。它们使得一...

    Javascript - 全面理解 caller,callee,call,apply (转载)

    这篇文章将深入探讨四个关键概念:caller、callee、call和apply,它们都是JavaScript函数操作的核心部分,对于理解和使用高级JavaScript编程至关重要。 首先,我们来了解`caller`和`callee`。在JavaScript的函数...

    javascript call和apply方法

    另一方面,`apply`方法与`call`非常相似,也是用于改变`this`的值,但它接受一个参数数组。这使得`apply`更适合于处理动态数量的参数。`apply`的基本语法如下: ```javascript functionName.apply(object, [arg1, ...

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

    Function.prototype.apply()方法与call方法类似,同样可以指定函数内部this的指向并执行函数,但是apply方法仅接受两个参数,第一个参数同样是函数内部this的指向,第二个参数必须是一个数组,数组中的元素依次对应...

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

    ### JavaScript中apply、call和bind的用法区分 在JavaScript编程中,`apply`、`call`和`bind`这三个方法被广泛用于改变函数内部`this`的指向,这对于理解和编写复杂的JavaScript代码至关重要。虽然它们的功能相似,...

    js中apply与call简单用法详解.docx

    ### JavaScript中的apply与call用法详解 #### 一、引言 在JavaScript中,`apply`与`call`是两个非常重要的函数,它们都属于`Function.prototype`的一部分,因此每一个函数对象都拥有这两个方法。这两个方法的主要...

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

    本文将详细解释JavaScript中call(), apply(), 和 bind() 方法的作用、语法以及使用场景,并且会探讨回调函数的使用,帮助理解这些概念在实际编程中的应用。 首先,我们来探讨call() 和 apply() 方法。这两个方法都...

Global site tag (gtag.js) - Google Analytics