`
mr.a
  • 浏览: 95033 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

javascript中apply方法和call方法的作用以及prototype.js中的应用

阅读更多

说明白一点其实就是更改对象的内部指针,即改变对象的this指向的内容。这在面向对象的js编程过程中有时是很有用的。

call函数和apply方法的第一个参数都是要传入给当前对象的对象,及函数内部的this。后面的参数都是传递给当前对象的参数。

对于apply和call两者在作用上是相同的,但两者在参数上有区别的。
对于第一个参数意义都一样,但对第二个参数:
apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。

如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

同时使用apply的好处是可以直接将当前函数的arguments对象作为apply的第二个参数传入。


(reference:http://www.cnblogs.com/beyondnet/archive/2007/12/06/985216.html)

 

TEST:

function cls1()
{
   this.b='111';
   this.c ='222';
   this.d ='333';
   this.f = function()
   {
       alert("nihao");
}
}

function cls2()
{
   this.a='aaa';
  
   cls1.apply(this); //这里用的是类(也可直接看成函数)直接来apply的。不是用实例。此时,cls2类拥有                                cls1类的所有属性和方法.
  
}
var st = new cls2();

alert(st.d);

/*注意,这里可以在第2个类中,用第一个类的名称来实现所有属性和方法的复制。方法可以用如下方法复制:ss.f.apply(this);可以正常运行。而属性ss.c.apply(this);则会报错,

 

function cls2()
{
   this.a='aaa';
   var ss = new cls1;
   ss.c.apply(this); //这里会报错。如果为ss.f.apply(this);则正确。如果是属性,则用类名,如果是方法, 即                                     可用类名,也可用实例加方法的形式应该(var ss = new cls1;ss.f.apply(this);)

如下形式(***正确****)。
  
}
var st = new cls2();

alert(st.c);

****正确*******
function cls2()
{
   this.a='aaa';
  
   cls1.apply(this); //如果是属性,则用类名,如果是方法,即可用类名,也可用实例加方法的形式

}

var st = new cls2();

alert(st.c);

_______________________________________________

function simpleApplyDemo(sim) {
this.sim_name = sim;
}
function handleSPA(hand) {
    this.hand_name = hand ;
simpleApplyDemo.apply(this, new Array('222222222222'));   //这里用的是类名

////此处用Array()数组,是将这个数组的初始化值赋给simpleApplyDemo函数中的参数。也就是sim = 222222222222,在JS手册中,apply( [thisObj [,argArray ]])的 argArra是可选项,解释为将被传递给该函数的参数数组。(也就是说argArray同下的arguments是一样的)

alert(this.sim_name);
}                     

handleSPA();

上面的方法和下面的方法实现的效果一样

function simpleApplyDemo(sim) {
this.sim_name = sim;
}
function handleSPA(hand) {
    this.hand_name = hand ;
simpleApplyDemo.apply(this,arguments);   //这里用的是类名

/* 此处用arguments,是将handleSPA('55555555')中5555555作为arguments(arguments代表本身的参数 的集合,此处只代表5555555)将arguments传到simpleApplyDemo()中,也就是sim = arguments =55555 */


alert(this.sim_name);
}                     

handleSPA('55555555');

 

 

call方法在msdn中的解释   调用一个对象的一个方法,以另一个对象替换当前对象。

apply方法在msdn中的解释 应用某一对象的一个方法,用另一个对象替换当前对象。

这个解释也是非常抽象的,这两个方法的作用基本是一样的,举个例子

<script>
function cls1()
{
   this.a='123';
}
cls1.prototype.fun1=function()
{
   alert(this.a);
}
function cls2()
{
   this.a='456';
}
var o1=new cls1();
var o2=new cls2();
o1.fun1.apply(o2); //这里用的是实例名,如果写成 o1.apply(o2)则报错
</script>

只有o1对象的类cls1中有fun1这个方法,但是,这时我们需要用o2对象替代o1对象,所以这个时候显示的this.a会是456,呵呵很神奇吧,换成call方法也是一样的,这两种方法使用的不同点仅仅是参数的使用方法上不同,这里就不多做解释了。

大家可以在prototype.js里看到
var Class = {
   create: function() {
     return function() {
       this.initialize.apply(this, arguments);
     }
   }
}
这种代码,相当的夸张,很多人很容易被这种bt的代码弄糊涂,其实仔细分析其中的道理却也不难

显然这种写法代表了Class是声明的一个Object对象,其中create是这个object对象的一个属性,这个属性就是一个函数。这个函数执行过后返还一个函数。可能这样解释太复杂了,那不如做一个试验好了。

<script>
var x=function(){return function(){alert(123);}}
var n=x();
n();
</script>
很好玩吧,这里n就是x函数执行过后返还给的一个函数也就是n现在等于了function(){alert(123);}再执行n()的时候就跳出了123

现在开始讲难点 this.initialize.apply(this, arguments);

这句表达了什么含义,其实现在先看看prototype.js里怎么调用的就明白了

var Template = Class.create();

Template.prototype = {
   initialize: function(template, pattern) {
     this.template = template.toString();
     this.pattern   = pattern || Template.Pattern;
   },....省略代码若干

var template = new Template(replacement);

第一句话Class.create(); 就是返还给Template 一个函数,这个函数是
function() {
       this.initialize.apply(this, arguments);
     }
当执行var template = new Template(replacement);时,就变成了要执行这个函数,而这个函数的作用是
执行当前类中initialize这个函数

所以prototype.js中的每一个类都预留了
Template.prototype = {
   initialize: function(template, pattern) {
     this.template = template.toString();
     this.pattern   = pattern || Template.Pattern;
   },....
这么个函数,如果没有这个的话,程序将会出错

知其然,知其所以然,为什么要这么写呢?

一般我们声明的时候funciton fun(){} var o=new fun();这样感觉fun又是类又是构造函数很别扭,为了分开这种不是很友好的代码方案,所以prototype.js使用了如上方法

 

 

 

from: http://hi.baidu.com/black8/blog/item/50dbb452de79f70a0cf3e3e8.html

分享到:
评论

相关推荐

    Array.prototype.slice.apply的使用方法

    `Array.prototype.slice.apply` 是 JavaScript 中一种巧妙的技巧,它允许我们借用 `Array.prototype.slice` 方法来处理非数组对象,尤其是 `arguments` 对象。`arguments` 是一个伪数组对象,它在每个函数内部可用,...

    关于Javascript中call与apply的进一步探讨

    在JavaScript中,`call`和`apply`是两个非常重要的方法,它们都用于改变函数调用时的上下文(即`this`的值),并且可以灵活地传递参数。本篇文章将深入探讨这两个方法的用法、区别以及实际应用场景。 `call`方法...

    Function.prototype.call.apply结合用法分析示例

    在JavaScript中,`Function.prototype.call` 和 `Function.prototype.apply` 是两种非常重要的方法,它们都是用来改变函数调用时的上下文(即`this`值)以及传递参数。在这个特殊的面试题中,这两种方法被结合在一起...

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

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

    深化理解关于javascript中apply()和call()方法的区分_.docx

    在JavaScript中,`apply()`和`call()`方法都是用于改变函数调用时的上下文(即`this`关键字指向的对象)以及传递参数。这两个方法都隶属于`Function.prototype`,因此所有函数实例都拥有这两个方法。它们的主要作用...

    详解js中call与apply关键字的作用.docx

    JavaScript中的`call`和`apply`是两种非常重要的方法,它们都用于改变函数内部`this`的指向,并执行该函数。这两个方法都是Function对象的原型方法,因此所有的函数都具备`call`和`apply`。 1. `call`方法: - `...

    js的继承方法小结(prototype、call、apply)(推荐).docx

    ### JavaScript 的继承方法小结(Prototype、Call、Apply) #### 一、JavaScript 原型继承 -- Prototype 在 JavaScript 中,“一切皆对象”。通过 `new` 关键字创建的对象是函数对象,而直接赋值的对象则是一般...

    call与apply区别 详细解读.pdf

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

    js中继承的几种用法总结(apply,call,prototype)

    在JavaScript中,实现对象继承主要有三种方式:原型链继承(prototype)、构造函数继承和call/apply继承。下面将分别详细介绍这三种继承方式的具体用法和实现原理。 1. 原型链继承(prototype) 原型链继承是...

    JS中的call、apply、bind方法详解.pdf

    JS中的call、apply、bind方法详解 随着JavaScript的发展,函数调用对象的改变变得越来越重要。在JavaScript中,call、apply、bind三个方法都是函数对象的方法,它们的作用都是改变函数的调用对象。下面,我们将详细...

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

    在JavaScript中,`apply`与`call`是两个非常重要的函数,它们都属于`Function.prototype`的一部分,因此每一个函数对象都拥有这两个方法。这两个方法的主要作用在于改变函数执行时的上下文环境(`this`值),这对于...

    Function.prototype.apply()与Function.prototype.call()小结

    在JavaScript中,`Function.prototype.apply()` 和 `Function.prototype.call()` 是两种非常重要的方法,它们用于在不同的上下文中调用函数,并允许我们灵活地传递参数。这两个方法的主要区别在于处理参数的方式,但...

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

    总结来说,apply、call和bind是JavaScript中非常重要的函数方法,它们提供了控制函数上下文的能力,无论是直接调用函数、扩展数组元素,还是改变对象的方法调用,这些方法都是不可或缺的工具。掌握它们的用法,能够...

    js中apply方法的使用详细解析.docx

    JavaScript中的`apply`方法是`Function.prototype`的一个内置方法,用于改变函数调用时的上下文(即`this`的指向)以及将参数以数组的形式传递给函数。这个方法对于理解和实现面向对象编程中的继承机制、处理数组...

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

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

    js中call与apply的用法小结

    在JavaScript中,`call` 和 `apply` 是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文,即`this`的指向。本文将深入探讨这两种方法的用法及其在实际编程中的应用。 ### 1. `call` 的基本用法 `...

    理解JavaScript的caller callee call apply

    ### 理解JavaScript中的`caller`...综上所述,理解`caller`、`callee`、`call`、`apply`以及`arguments`对象在JavaScript编程中至关重要,它们不仅增强了函数的灵活性和复用性,还提供了深入分析和调试代码的强大工具。

    JS中的prototype

    JavaScript中的`prototype`是语言核心概念之一,它在对象创建、继承和方法共享中起着关键作用。在JavaScript中,每个对象都有一个`prototype`属性,这个属性引用了一个对象,通常用于实现对象间的继承。理解`...

    详解js中的apply与call的用法.docx

    在JavaScript中,`call`和`apply`是两种非常重要的函数调用方式,它们都用于改变函数执行时的上下文,即改变`this`的指向。这两个方法的主要区别在于它们处理参数的方式。 `call`方法允许你指定一个对象来替代原...

Global site tag (gtag.js) - Google Analytics