1 函数定义
- 使用function关键字来定义,即function fName(para,...){ statment;...;},可使用在函数声明语句与函数定义表达式这两种形式中
-
函数名称标识符fName。
-
是函数声明语句必需的部分。它的用途就像变量的名字,新定义的函数对象会赋值给这个变量
-
但对函数定义表达式来说,这个名字是可选的:如果存在,该名字只存在于函数体中,并指代该函数对象本身
-
-
一对圆括号(),其中包含由0个或者多个用逗号隔开的标识符组成的列表。这些标识符是函数的参数名称,它们就像函数体中的局部变量一样
-
一对花括号{ },其中包含0条或多条JavaScript语句。这些语句构成了函数体:一旦调用函数,就会执行这些语句
-
- 使用函数声明语句定义函数
- 实际上声明了一个变量, 并把一个函数对象赋值给它
- 函数可以命名, 这个名称用来来指代自己,成为函数内部的一个局部变量
- 这种方式定义的函数,拥有函数提升特性,即函数声明语句 被“提升” 到外部脚本或外部函数作用域的顶部, 使之可以被它定义之前的代码所调用
- 使用 表达式方式定义函数
- 函数名称通常被省略,以使定义代码更紧凑,如果不省略函数名称, 函数的局部作用域将会包含一个绑定到函数对象的名称。 实际上, 函数的名称将成为函数内部的一个局部变量
- 这种方式定义的函数,即要对一个变量进行赋值,而赋值不会提升,所以这种方式定义函数,必须先定义后调用
- return与函数返回值
- 函数中return 语句没有一个与之相关的表达式或省略了return, 则它返回undefined值给调用者
- 没有return 语句的函数,有时也叫过程
- 函数嵌套
- 作用域规则:被嵌套函数可以访问嵌套函数的参数和变量
- 使用函数声明的函数,不可出现在条件语句、循环语句、try/cache/finally及with语句中
- 使用表达式定义的函数,可以出现在任何JavaScript语句中
//函数声明 function myFunc(name,age){ return 'My name is ' + name + ', My old is' +age+'.' ; } //函数定义表达式 var f = function(name){ return 'My name is ' + name; } //或者 var f = function fName(name){ return 'My name is ' + name; }
//无return
function myalter(msg){
alter(msg);
}
//函数嵌套
function fName(x,y){
function func(a,b){
return a + b;
}
return func(x,y);
}
2 函数调用
- 作为函数
-
非严格模式的ECMAScript 5对函数调用的规定, 调用上下文(this的值)是全局对象
-
在严格模式下,调用上下文则是undefined
-
-
- 以函数形式调用的函数通常不使用this关键字。但 “this” 可以用来判断当前是否是严格模式
//定义并调用一个函数来确定当前脚本运行时是否为严格模式 var strict = (function() { return !this; }());
- 作为方法
- 任何函数作为方法调用,实际上都会传入一个隐式的实参(即方法调用的母体对象)。通常,基于哪个对象的方法可以进行多种操作
- 方法和this关键字是面向对象编程的核心,当方法不需要返回值时,如果返回this,即方法调用的母体对象,就可形成链式调用
- this是关键字, 不是变量, 也不是属性名。 JavaScript的语住不允许给this赋值
- 和变量不同, 关键字this没有作用域的限制, 嵌套的函数不会从调用它的函数中继承 this
- 如果嵌套函数作为方法调用, this指向调用它的对象
- 如果嵌套函数作为函数调用, 非严格模式下this指向全局对象,严格模式下this的值是undefined
- 调用嵌套函数时
- this指向不是调用它的外层函数的上下文
- 要访问调用它的外层函数的this值, 可将this的值保存在和内部函数都同在一个作用域内的变量里,通常使用变量self来保存this
var obj = { method:function(){ self = this;//将this保存到同一作用域的self变量中 console.log(this === obj);//true innerF(); } function innerF(){//嵌套函数 console.log(self == obj);//true console.log(this == obj);//是全局变量或unfined } }
- 作为构造函数
- 构造函数调用和普通的函数调用以及方法调用在实参处理、 调用上下文和返回值方面都有不同
-
如果构造函数调用时,包含一组实参列表, 则会先计算这些实参表达式,然后传入函数内,这和函数调用和方怯调用是 致的
-
但如果构造函数没有形参,JavaScript构造函数调用的语法允许省略实参列表和圆括号的(凡是没有形参的构造函数调用都可以省略圆括号)
- 构造函数调用创建一个新对象,这个对象继承自构造函数的prototype属 性。构造函数试图初始化这个新创建的对象, 并将这个对象作为其调用上下文,因此构造函数可以使用this关键字来引用这个新创建的对象。尽管构造函数看起来像一个方法调用,但它依然会将这个新对象作为调用上下文
- 构造函数通常不使用return关键字,而是通过初始化新对象, 在构造函数的函数体执行完毕时,将其显式返回,在这种情况下, 构造函数调用表达式的计算结果就是这个新对象的值
- 如果构造函数显式地使用return语句返回了一个对象,那么调用表达式的值就这个新对象
- 如果构造函数使用return语句没有指定返回值,或者返回的是一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果。
- 通过函数的方法call()或者apply()间接调用
3 函数的形参与实参
- JavaScript中的函数定义未指定函数形参的类型
- JavaScript函数调用也不对传人的实参值做任何类型检查, 甚至不检查传入形参的个数
- 可选形参
- 当调用函数的时候传人的实参比函数声明时指定的形参个数要少,剩下的形参都将设置 为undefined值
- 调用函数时形参是否可选以及是否可以省略,应当保持较好的适应性
- 使用 if 语句,判断形参是否为undefined
- 使用 ||(如var para = para || 0)
- 当用这种可选实参来实现函数时,需要将可选实参放在实参列表的最后。
- 可变长的实参列表:实参对象
-
引入实参对象可解决当调用函数的时候传入的实参个数超过函数定义时的形参个数时,不能直接获得未命名值的引用问题
-
标识符 arguments是指向实参对象的引用,实参对象是 个类数组对象,通过数字下标就能访问传入函数的实参值,而不用通过名字来得到实参
- 实参对象的重要的用处,就是让函数可以操作任意数量的实参
- arguments的callee属性与caller属性,callee指代当前正在执行的函数(如指代匿名函数),caller指代当前调用正在执行的函数的函数(非标准)
- 将对象属性用作实参(编程风格)
- 通过名/值对的形式来传入参数, 参数的顺序无关紧要
- 允许在函数中设置省略参数的默认值
-
function opt(options){ options = options || {}; var para1 = options.x || 0; var para2 = options.y || 12; var para3 = options.name || 'John'; var para4 = options.old || 5; }
- 实参类型:必要时,还是需要对传入参数执行类型检查以避免出错
4 作为值的函数
- 函数可以定义,也可以调用,这是函数最重要的特性。函数定义和调用是JavaScript的词法特性,对于其他大多数编程语言来说亦是如此
- 在JavaScript中,函数不仅是一种语法,也是值
- 可以将函数赋值给变量
- 可存储在对象的属性或数组的元素中
- 可作为参数传入另外一个函数等
- 自定义函数属性
- JavaScript中的函数并不是原始值, 而是一种特殊的对象, 也就是说, 函数可以拥有属性
- 当函数需要一个 “静态” 变量来在调用时保持某个值不变, 最方便的方式就是给函 数定义属性, 而不是定义全局变量
//返回一个唯一整数的函数, 不管在哪里调用函数都会返回这个整数, //而函数不能两次返回同一个值, 函数就必须能够跟踪它每次返回的值, //而且这些值的信息需要在不同的函数调过程中持久化。 //可以将这些信息存放到全局变量中, 但这并不是必需的, //因为这个信息仅仅是函数本身用到的。 //最好做法是将这个信息保存到函数对象的一个属性中 fAttr.counter = 0; function fAttr(){ return fAttr.counter++;//先返回属性值,然后自增1 }
标签:调用,return,函数,对象,JavaScript,实参,定义 From: https://www.cnblogs.com/cqycb720930/p/17417980.html