在js中,函数属于较为容易掌握,但使用情况则最为复杂的一种技术。本文仅尝试从如下方面着重阐述一些特点及用法,留待今后update:
函数基本特点:
1、
函数属于对象类型的一种(ECMAScript中有5中简单类型Undefined、Null、Boolean、Number和String,还有1种复杂类型Object),并且是标准内置类型Function的实例
ECMA-262 写道
function:
member of the Object type that is an instance of the standard built-in Function constructor and that may be invoked as a subroutine.
function demo() {
}
alert(typeof demo);//function,注意,不是object
2、函数在定义的时候,参数与返回值均为可选。
- 函数的参数在内部使用一个数组(arguments)来表示,在函数体内可通过arguments[index]来获取指定参数
- 当没有指定返回值时,将自动返回undefined
3、在js中,函数没有重载,当定义了2个名字相同的函数,则该函数名属于后定义者(或简称覆盖)
函数的定义方式
大致分为如下3种:
//1.使用函数声明语法
function demo1(){}
//2.使用函数表达式
var demo2=function(){};//注意不要省略分号,因为有些js引擎实现必须通过分号来判断表达式结尾
//3.使用Function构造函数
var demo3=new Function("m","n","return m+n;");//不推荐
区别:
第一种定义方式:常规方式,不赘述
第二种定义方式:较为特殊,但基本特点和第一种相似。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针,因此第二种定义方式实质上等价于:首先定义一个匿名函数,然后将其值赋给一个变量。
第三种定义方式:在Function构造器中,参数分别为若干个形参和函数的具体实现代码,因为使用这种方式定义的时候存在2次解析(一次解析ECMAScript代码,一次解析传入构造器的字符串)、书写代码可读性不好及脚本注入的问题,故不推荐使用。
js解析器在向环境中加载数据时,对前2种方式并非完全一样。
解析器会首先读取函数声明,并使其在执行任何代码之前可访问;而函数表达式,则必须等到解析器执行到他所在的代码行才会真正被解释执行:
alert(demo1(3,4));
function demo1(m,n){
return m+n;
}
这段代码运行没问题,最终答案为:弹出“7”
alert(demo2(3,4));
var demo2=function(m,n){
return m+n;
};
这段代码在执行期间会导致错误,因为在执行到函数所在语句之前,变量demo2不会保存对函数的引用
除开这一点区别之外,函数声明与函数表达式的语法其实是等效的。
函数的几种调用方式:
1、常规方式,不赘述
2、apply
function add(n1, n2) {
return n1 + n2;
}
//param1:在其中运行函数的作用域
//param2:Array的实例
alert(add.apply(this, [ 1, 2 ]));//注意,不能去掉中括号
alert(add.apply(window, [ 1, 2 ]));
3、call
function add(n1, n2) {
return n1 + n2;
}
//param1:在其中运行函数的作用域
//param2:可变参数,必须逐个罗列
alert(add.call(this, 1, 2 ));
alert(add.call(window, 1, 2 ));
基本上这2种调用方式的区别就在于第二个参数,apply必须传入一个数组的实例,而call则类是java中的可变参数,必须逐个罗列
apply和call在使用场景上,主要是为了扩展函数赖以运行的作用域,而这一点,常规调用方式难以做到
var gender = "female";
var obj = {
gender : "male"
};
function demo() {
alert(this.gender);
}
demo(this);//female
demo.call(window);//同上
demo.call(obj);//male
使用call与apply,实际上做到了:解除了函数调用者与函数实现的耦合关系。或者说apply和call用起来有点像java反射当中method.invoke(obj,args)
分享到:
相关推荐
### 知识点一:JavaScript 箭头函数 ES6(ECMAScript 2015)标准中引入了一种新的函数表达式——箭头函数(Arrow Function)。箭头函数提供了一种更简洁的函数写法,它主要有以下几个特点: 1. **简洁语法**:箭头...
在深入探讨JavaScript变量和函数的浅析之前,我们首先要明确JavaScript是一种动态类型语言,其在程序设计中扮演着核心角色。接下来将详细解释有关变量与函数的基础知识点: ### 变量 在JavaScript中,变量是一种...
JavaScript回调函数是编程中一种常见的技术,特别是在异步编程领域。回调函数允许我们将一个函数作为参数传递给另一个函数,以便在特定条件满足时执行。这种技术在JavaScript中尤为重要,因为JavaScript是单线程的,...
JavaScript中的闭包和函数柯里化是两种强大的编程技术,它们在函数式编程中起着核心作用。理解并熟练运用这两种技术,可以帮助开发者编写出更加高效、可维护的代码。 **闭包** 闭包是一种特殊的现象,它允许内部...
JavaScript函数重载是指在同一个作用域内创建多个同名函数,但这些函数的参数列表不同。通过不同的参数列表可以区分不同的函数,使得同一个函数名可以根据不同的参数类型或数量执行不同的操作。在传统的编程语言中,...
JavaScript 是一种广泛使用的编程语言,特别是在Web开发中。这篇文档主要探讨了ES6(ECMAScript 2015)中引入的一些新特性,包括箭头函数、生成器(generator)、Date对象以及JSON。这些特性极大地丰富了JavaScript...
JavaScript中的函数闭包是一个重要的概念,它涉及到函数的作用域、变量持久化以及内存管理等多个方面。闭包的本质是在函数内部创建另一个函数,使得内部函数能够访问并操作外部函数的局部变量,即使外部函数已经执行...
JavaScript是Web开发中不可或缺的一部分,它提供了两种声明函数的方式:函数声明式和函数表达式。这两者虽然看似相似,但存在显著的区别。 1. **函数声明式**:这是JavaScript中最直接的函数定义方式,通常以`...
JavaScript函数表达式是一种创建函数的方式,与函数声明不同。在JavaScript中,有两种主要的函数创建方式:函数声明和函数表达式。本篇文章将深入探讨函数表达式的概念和相关特性。 1. **函数声明与函数表达式** ...
尽管文章的标题提到了“闭包函数浅析”,但内容上似乎更偏向于解释 `return` 的用法,以及如何通过立即执行函数表达式(IIFE)实现闭包的效果。 首先,`return` 关键字在JavaScript中是函数中不可或缺的部分。当一...
接下来,我们简要了解一下JavaScript函数的两种基本形式: 1. **函数声明**:这是最直观的定义函数的方式,如`function fnA() {alert('msg');}`。这种形式的函数会在脚本解析时自动声明,因此可以在声明之前就被...
javascript函数劫持,也就是老外提到的javascript hijacking技术。虽然这个概念在前端领域使用较少,但是在安全领域、自定义业务等场景下还是有一定的使用价值的。所以,这一篇文章将会和大家一起去了解一下JS中的...
上述知识点涵盖了动画的基本概念、动画原理的数学模型、JavaScript中的动画实现方法、动画库设计的关键问题以及缓动函数的介绍和应用。这些知识对于制作流畅、平滑的动画效果非常关键。而通过这些基本原理和方法的...
在JavaScript中实现柯里化的例子中,我们通常会定义一个currying()函数,该函数接受一个函数fn和一个参数数组rest1作为输入,然后返回一个新的函数,这个新的函数接受剩余的参数rest2。当调用新的函数时,它会将rest...
### 浅析JavaScript原型继承机制 #### 一、引言 JavaScript作为一种动态语言,其对象模型与传统的面向对象编程语言有所不同。在JavaScript中,并没有直接提供类的概念,而是通过原型来实现继承。本文将深入探讨...
JavaScript函数防抖和节流是前端开发中常见且重要的性能优化技术,它们主要用于控制在一定时间间隔内高频触发的事件函数的执行频率,以避免不必要的计算或者请求,提高程序的性能和用户体验。 函数防抖(debounce)的...