[Java教程]JavaScript函数的4种调用方法详解

0 2016-08-09 00:00:12

在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而非像C#或其他描述性语言那样仅仅作为一个模块来使用。函数有四种调用模式,分别是:函数调用形式、方法调用形式、构造器形式、以及apply形式。这里所有的调用模式中,最主要的区别在于关键字 this 的意义,下面分别介绍这个几种调用形式。

本文主要内容:

1.分析函数的四种调用形式

2.弄清楚函数中this的意义

3.明确构造函对象的过程

4.学会使用上下文调用函数

一、函数调用形式

函数调用形式是最常见的形式,也是最好理解的形式。所谓函数形式就是一般声明函数后直接调用即是。例如:复制代码代码如下:// 声明一个函数,并调用

function func() {

alert("Hello World");

}

func();

或者:复制代码代码如下:// 使用函数的Lambda表达式定义函数,然后调用

var func = function() {

alert("你好,程序员");

};

func();

这两段代码都会在浏览器中弹出一个对话框,显示字符串中的文字,这个就是函数调用。

可以发现函数调用很简单,就是平时学习的一样,这里的关键是,在函数调用模式中,函数里的 this 关键字指全局对象,如果在浏览器中就是 window 对象。例如:复制代码代码如下:var func = function() {

alert(this);

};

func();

此时,会弹出对话框,打印出 [object Window]。

二、方法调用模式

函数调用模式很简单,是最基本的调用方式。但是同样的是函数,将其赋值给一个对象的成员以后,就不一样了。将函数赋值给对象的成员后,那么这个就不在称为函数,而应该叫做方法。例如:复制代码代码如下:// 定义一个函数

var func = function() {

alert("我是一个函数么?");

};

// 将其赋值给一个对象

var o = {};

o.fn = func; // 注意这里不要加圆括号

// 调用

o.fn();

此时,o.fn 则是方法,不是函数了。实际上 fn 的方法体与 func 是一模一样的,但是这里有个微妙的不同。看下面的代码:复制代码代码如下:// 接上面的代码

alert(o.fn === func);

打印结果是true,这个表明两个函数是一样的东西,但是修改一下函数的代码:

// 修改函数体

var func = function() {

alert(this);

};

var o = {};

o.fn = func;

// 比较

alert(o.fn === func);

// 调用

func();

o.fn();

这里的运行结果是,两个函数是相同的,因此打印结果是 true。但是由于两个函数的调用是不一样的,func 的调用,打印的是 [object Window],而 o.fn 的打印结果是 [object Object]。

这里便是函数调用与方法调用的区别,函数调用中,this 专指全局对象 window,而在方法中 this 专指当前对象,即 o.fn 中的 this 指的就是对象o。

三、构造器调用模式

同样是函数,在单纯的函数模式下,this 表示 window;在对象方法模式下,this 指的是当前对象。除了这两种情况,JavaScript 中函数还可以是构造器。将函数作为构造器来使用的语法就是在函数调用前面加上一个 new 关键字。如代码:复制代码代码如下:// 定义一个构造函数

var Person = function() {

this.name = "程序员";

this.sayHello = function() {

alert("你好,这里是" + this.name);

};

};

// 调用构造器,创建对象

var p = new Person();

// 使用对象

p.sayHello();

上面的案例首先创建一个构造函数Person,然后使用构造函数创建对象p。这里使用 new 语法。然后在使用对象调用sayHello()方法,这个使用构造函数创建对象的案例比较简单。从案例可以看到,此时 this 指的是对象本身。除了上面简单的使用以外,函数作为构造器还有几个变化,分别为:

1、所有需要由对象使用的属性,必须使用 this 引导;

2、函数的 return 语句意义被改写,如果返回非对象,就返回this。

构造器中的 this

我们需要分析创建对象的过程,方能知道 this 的意义。如下面代码:复制代码代码如下:var Person = function() {

this.name = "程序员";

};

var p = new Person();

这里首先定义了函数 Person,下面分析一下整个执行:

1、程序在执行到这一句的时候,不会执行函数体,因此 JavaScript 的解释器并不知道这个函数的内容。

2、接下来执行 new 关键字,创建对象,解释器开辟内存,得到对象的引用,将新对象的引用交给函数。

3、紧接着执行函数,将传过来的对象引用交给 this。也就是说,在构造方法中,this 就是刚刚被 new 创建出来的对象。

4、然后为 this 添加成员,也就是为对象添加成员。

5、最后函数结束,返回 this,将 this 交给左边的变量。

分析过构造函数的执行以后,可以得到,构造函数中的 this 就是当前对象。

构造器中的 return

在构造函数中 return 的意义发生了变化,首先如果在构造函数中,如果返回的是一个对象,那么就保留原意。如果返回的是非对象,比如数字、布尔和字符串,那么就返回 this,如果没有 return 语句,那么也返回 this,看下面代码:复制代码代码如下:// 返回一个对象的 return

var ctr = function() {

this.name = "赵晓虎";

return {

name:"牛亮亮"

};

};

// 创建对象

var p = new ctr();

// 访问name属性

alert(p.name);

执行代码,这里打印的结果是”牛亮亮”。因为构造方法中返回的是一个对象,那么保留 return 的意义,返回内容为 return 后面的对象,再看下面代码:复制代码代码如下:// 定义返回非对象数据的构造器

var ctr = function() {

this.name = "赵晓虎";

return "牛亮亮";

};

// 创建对象

var p = new ctr();

// 使用

alert(p);

alert(p.name);

代码运行结果是,先弹窗打印[object Object],然后打印”赵晓虎”,因为这里 return 的是一个字符串,属于基本类型,那么这里的 return 语句无效,返回的是 this 对象,因此第一个打印的是[object Object]而第二个不会打印 undefined。

四、apply调用模式

除了上述三种调用模式以外,函数作为对象还有 apply 方法与 call 方法可以使用,这便是第四种调用模式,我称其为 apply 模式。

首先介绍 apply 模式,首先这里 apply 模式既可以像函数一样使用,也可以像方法一样使用,可以说是一个灵活的使用方法。首先看看语法:函数名.apply(对象, 参数数组);

这里看语法比较晦涩,还是使用案例来说明:

1、新建两个 js 文件,分别为”js1.js”与”js2.js”;

2、添加代码复制代码代码如下:// js1.js 文件中

var func1 = function() {

this.name = "程序员";

};

func1.apply(null);

alert(name);

// js2.js 文件

var func2 = function() {

this.name = "程序员";

};

var o = {};

func2.apply(o);

alert(o.name);

3、分别运行着两段代码,可以发现第一个文件中的 name 属性已经加载到全局对象 window 中; 而第二个文件中的 name 属性是在传入的对象 o 中,即第一个相当于函数调用,第二个相当 于方法调用。

这里的参数是方法本身所带的参数,但是需要用数组的形式存储在,比如代码:复制代码代码如下:// 一个数组的例子

var arr1 = [1,2,3,[4,5],[6,7,8]];

// 将其展开

var arr2 = arr1.conact.apply([], arr1);

然后介绍一下 call 模式,call 模式与 apply 模式最大的不同在于 call 中的参数不用数组,看下面代码就清楚了:

// 定义方法

var func = function(name, age, sex) {

this.name = name;

this.age = age;

this.sex = sex;

};

// 创建对象

var o = {};

// 给对象添加成员

// apply 模式

var p1 = func.apply(o, ["赵晓虎", 19, "男"]);

// call 模式

var p2 = func.call(o, "赵晓虎", 19, "男");

上面的代码,apply 模式与 call 模式的结果是一样的。

实际上,使用 apply 模式和 call 模式,可以任意的操作控制 this 的意义,在函数 js 的设 计模式中使用广泛。简单小结一下,js 中的函数调用有四种模式,分别是:函数式、方法式、构造 器式和 apply 式. 而这些模式中,this 的含义分别为:在函数中 this 是全局对象 window,在方 法中 this 指当前对象,在构造函数中 this 是被创建的对象,在 apply 模式中 this 可以随意的指定.。在 apply 模式中如果使用 null,就是函数模式,如果使用对象,就是方法模式。

五、综合例子

下面通过一个案例结束本篇吧。案例说明:有一个div,id为dv,鼠标移到上面去高度增大2倍,鼠标离开恢复,下面直接上js代码:复制代码代码如下:var dv = document.getElementById("dv");

var height = parseInt(dv.style.height || dv.offsetHeight);

var intervalId;

dv.onmouseover = function() {

// 停止已经在执行的动画

clearInterval(intervalId);

// 得到目标高度

var toHeight = height * 2;

// 获得当前对象

var that = this;

// 开器计时器,缓慢变化

intervalId = setInterval(function() {

// 得到现在的高度

var height = parseInt(dv.style.height || dv.offsetHeight);

// 记录每次需要变化的步长

var h = Math.ceil(Math.abs(height - toHeight) / 10);

// 判断变化,如果步长为0就停止计时器

if( h > 0 ) {

// 这里为什么要用that呢?思考一下吧

that.style.height = (height + h) + "px";

} else {

clearInterval(intervalId);

}

}, 20);

};

dv.onmouseout = function() {

// 原理和之前一样

clearInterval(intervalId);

var toHeight = height;

var that = this;

intervalId = setInterval(function() {

var height = parseInt(dv.style.height || dv.offsetHeight);

var h = Math.ceil(Math.abs(height - toHeight) / 10);

if( h > 0 ) {

that.style.height = (height - h) + "px";

} else {

clearInterval(intervalId);

}

}, 20);

}; 本文网址:http://www.shaoqun.com/a/245340.html

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:admin@shaoqun.com。

JavaScript

0

java调用javascript函数_[Java教程]JavaScript函数的4种调用方法详解相关推荐

  1. Java SHA-256加密的两种实现方法详解

    利用Apache的工具类实现加密,使用commons-codec包中的DigestUtils算法工具类(入参支持字符串.字节数组.文件流等): maven: 1 2 3 4 5 <depende ...

  2. python中的class怎么用_对python 中class与变量的使用方法详解

    python中的变量定义是很灵活的,很容易搞混淆,特别是对于class的变量的定义,如何定义使用类里的变量是我们维护代码和保证代码稳定性的关键. #!/usr/bin/python #encoding ...

  3. python中class变量_对python 中class与变量的使用方法详解

    python中的变量定义是很灵活的,很容易搞混淆,特别是对于class的变量的定义,如何定义使用类里的变量是我们维护代码和保证代码稳定性的关键. #!/usr/bin/python #encoding ...

  4. 下拉多选框 微信小程序_微信小程序下拉框组件使用方法详解

    本文实例为大家分享了微信小程序下拉框组件的使用方法,供大家参考,具体内容如下 适用场景 1.省市三级联动 2.出生日期选择 3.性别选择 4.一般性的下拉选择等 一.省市三级联动使用 注意mode = ...

  5. python3占位符详解_占位符最新:Python 占位符的使用方法详解_爱安网 LoveAn.com

    关于"占位符"的最新内容 聚合阅读 这篇文章主要介绍了Python 占位符的使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以 ...

  6. java equals重写原则_java中为何重写equals时必须重写hashCode方法详解

    前言 大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 在上一篇博文Ja ...

  7. Java基础(二):迭代器(Iterator)(含使用方法详解)

    Java Iterator(迭代器) Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合. Iterator 是 ...

  8. python list find函数_对python中list的五种查找方法说明

    Python中是有查找功能的,五种方式:in.not in.count.index,find 前两种方法是保留字,后两种方式是列表的方法. 下面以a_list = ['a','b','c','hell ...

  9. python cut函数_基于python cut和qcut的用法及区别详解

    我就废话不多说了,直接上代码吧: from pandas import Series,DataFrame import pandas as pd import numpy as np from num ...

  10. php短链接api,PHP通过调用新浪API生成t.cn格式短网址链接的方法详解

    本文实例讲述了PHP通过调用新浪API生成t.cn格式短网址链接的方法.分享给大家供大家参考,具体如下: 新浪提供了长链接转为短链接的API,可以把长链接转为 t.cn/xxx 这种格式的短链接. A ...

最新文章

  1. 关于如何解决解决The SDK platform-tools version ((25.0.3)) is too old to check APIs compiled with API 26...
  2. 成功解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshap
  3. 【Linux】一步一步学Linux——groupmod命令(89)
  4. c语言中常用的预处理命令6,C语言的预处理命令
  5. C#语法糖 Null 条件运算符 【?.】
  6. junit:junit_处理JUnit中异常的另一种方法:catch-exception
  7. 传智播客全栈_播客:从家庭学生到自学成才的全栈开发人员
  8. 【剑指offer - C++/Java】8、跳台阶
  9. stl vector 函数_vector :: crbegin()函数,以及C ++ STL中的示例
  10. SaaS 公司如何应对 On-Call 挑战?
  11. IOS:static和extern的使用
  12. MPU6050数据处理分析
  13. python 求复数的模
  14. 基于python的网络聊天室论文_Python基于Socket实现简单聊天室
  15. linux实验报告ALU,《linux内核分析》第一次课 实验作业
  16. 互联网商业模式O2O、C2C、B2B、B2C等介绍
  17. 服务端程序由什么定义_到底什么是街球?这款游戏由你定义!
  18. 三种显色方法ECL、NBT/BCIP和DAB的对比
  19. 国内外技术论坛的区别
  20. 微信小程序——设置背景图片

热门文章

  1. ElasticSearch之搜索结果返回字段长度问题
  2. Office 2007界面与新增功能介绍
  3. C语言学习笔记 —— 内存管理
  4. 请不要QQ挂机浪费国家电力资源!!!(ZT)
  5. com.mysql.jdbc.Driver报类找不到
  6. linux检测端口命令
  7. Python小姿势 - #
  8. 迭代器traits 编程技巧——value type
  9. 文件加密和解密软件:AutoCrypt for mac
  10. 520运维侠客行·北京站传统IT运维转型之道圆满落幕