JS 函数

https://developer.mozilla.org/zh-CN/docs/Web/API

 

定义函数

function sayHi(name, message) {
alert("Hello " + name + "," + message);
}

 

调用函数

sayHi("Nicholas", "how are you today?");

ECMAScript 中的函数在定义时不必指定是否返回值 

 

形参和实参

函数定义的参数为形参,调用时的参数是实参

调用时:

如果形参数量多于实参,则多出的形参会被忽略

如果实参数量多于形参,则多出的实参会复制为undefined

 

剩余参数 es6

function t(a, ...arr) {
    console.log(arr)
}
t(1, 2, 4, 5)
结果  [ 2, 4, 5 ]
 

默认参数 es6

function t(a, b=3) {
    console.log(b)
}
t(1)

 

隐式函数参数arguments  es5

 

function t(a,b) {
console.log(a)
console.log(arguments[1])
}
t(1,2)

实际上argument是参数的别名,赋值后对应的参数值也会改变

function t(a) {
console.log(arguments[0])
arguments[0]=666
console.log(a)
}
t(1)
1
666

严格模式下不能使用

"use strict"
function t(a) {
console.log(arguments[0])
arguments[0]=666
console.log(a)
}
t(1)
1
1

 

隐式函数参数this 

 在浏览器中,以函数方式调用,this是windows的对象。以方法调用,this是该调用的对象

 

理解参数

ECMAScript 函数的参数与大多数其他语言中函数的参数有所不同。 ECMAScript 函数不介意传递进
来多少个参数,也不在乎传进来参数是什么数据类型。也就是说,即便你定义的函数只接收两个参数,
在调用这个函数时也未必一定要传递两个参数。可以传递一个、三个甚至不传递参数,而解析器永远不
会有什么怨言。之所以会这样,原因是 ECMAScript 中的参数在内部是用一个数组来表示的。函数接收
到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任
何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过 arguments 对象来
访问这个参数数组,从而获取传递给函数的每一个参数。
其实, arguments 对象只是与数组类似(它并不是 Array 的实例),因为可以使用方括号语法访
问它的每一个元素(即第一个元素是 arguments[0],第二个元素是 argumetns[1],以此类推),使
用 length 属性来确定传递进来多少个参数。在前面的例子中, sayHi()函数的第一个参数的名字叫
name,而该参数的值也可以通过访问 arguments[0]来获取。因此,那个函数也可以像下面这样重写,
即不显式地使用命名参数: 

function sayHi() {
alert("Hello " + arguments[0] + "," + arguments[1]);
}
FunctionExample05.

 

这个重写后的函数中不包含命名的参数。虽然没有使用 name 和 message 标识符,但函数的功能
依旧。这个事实说明了 ECMAScript 函数的一个重要特点:命名的参数只提供便利,但不是必需的。另
外,在命名参数方面,其他语言可能需要事先创建一个函数签名,而将来的调用必须与该签名一致。但
在 ECMAScript 中,没有这些条条框框,解析器不会验证命名参数。 

 

通过访问 arguments 对象的 length 属性可以获知有多少个参数传递给了函数。下面这个函数会
在每次被调用时,输出传入其中的参数个数: 

function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45); //2
howManyArgs(); //0
howManyArgs(12); //1

 

 

function doAdd() {
if(arguments.length == 1) {
alert(arguments[0] + 10);
} else if (arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //20
doAdd(30, 20); //50

 

 

没有重载

 如果在 ECMAScript 中定义了两个名字相同的函数,则该名字只属于后定义的函数 

function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100); //300

 

 

回调函数

var values=[1,4,5,2,3]
var s=values.sort(function(a,b){
    return a-b
})

console.log(s)

 

自记忆函数

function t() {
    if (!t.cache) {
        console.log('create')
        t.cache = 'ok'
    }
    console.log('end')
}
t()
t()

 

create
end
end
 
 

立即执行函数

 函数外包裹一个括号,

let l=(function (a,b){return a+b})(3,2)
console.log(l)

 

箭头函数 es6

let l=(a,b)=>a+b
console.log(l(2,3))

 

参数只有一个时,可以缺略括号

 

构造函数

构造函数和函数定义相同,在调用的时候才进行区分。

使用new关键字调用函数,那么这个函数就是构造函数

function Fun(){console.log(this)}
var f1= Fun() //调用函数,并把返回值赋值给f1
var f2=new Fun() //创建一个对象,并把对象返回给f2

 构造函数执行流程

1.立即创建一个新对象

2.将对象设置为this

3.执行函数内代码

4.将新建对象返回

 为构造函数添加属性

function Fun(){this.name='tom'}
var f2=new Fun()
console.log(f2.name)

 共享函数

//定义一个公用函数
function k() {
    console.log('hello' + this.name)
}

function fun(n) {
    this.name = n
    this.k = k
}

var f1=new fun('li')
var f2=new fun('tom')

console.log(f1.name)
console.log(f2.name)

 如果构造函数有返回值

1.当返回值是对象类型时,该对象作为整个表达式的值返回,this被丢弃

2.当返回值是值类型时,值类型被忽略,仍然返回this

 

函数上下文

 

posted @ 2017-07-02 19:09  富坚老贼  阅读(118)  评论(0编辑  收藏  举报