js 函数

函数只定义一次但可能被执行或调用任意次,但在定义的时候并不会执行。
函数的参数有形参和实参,形参是函数中定义的变量,实参是在运行是的函数调用时传入的参数。
函数使用function关键字来定义,es6可以用=>来定义,函数的组成:

  • 函数名
  • 一对圆括号(由0个或多个标识符组成,这些标识符是函数的参数名称,他们就像函数体中的局部变量)
  • 一对花括号(其中包含0条或多条js语句。一旦调用函数,就会执行这些语句)

函数调用

  • 函数调用(由一个函数对象和左圆括号,参数列表和右圆括号组成)
  • 方法调用 (调用的上下文不同,也就是this不同)
  • 构造函数调用 (如果函数或者方法调用之前带有关键字new,他就构成构造函数调用。)
  • 间接调用(call和apply方法间接调用)
    形参和实参
    当调用函数的时候传入的实参比函数声明时指定的形参个数要少,剩下的形参都将设置为undefined值。
    可变长的实参列表
function b(x,y){console.log(arguments.length)}
b(1,2,3) //3

callee和caller
callee和caller指代调当前正在执行的函数。caller是非标准的。它们在匿名函数中用来递归会非常有用。
作为值的函数
函数还可以作为值

function fun(x){
    return x*x
}
fun(4) //16

此时,这个是作为值。
当函数作为对象的属性调用时,函数就称为方法。

var o={fun:function(x){return x*x}}
var y=o.fun(4) //16

函数属性
函数是一种特殊对象,说明函数也可以拥有属性。

int.counter=0
function int(){
    return int.count++
}

每次调用都会返回一个唯一的整数。

匿名函数
没有函数名的的函数

(function(){
    //do
}())

闭包
在js中作用域内部可以访问外部变量,反之则不可以,这时候我们就需要闭包来实现。
函数的执行依赖于变量作用域,作用域是在函数定义时决定的,而不是调用时决定的。
函数对象通过作用域相互关联起来,函数体内部的变量都可以保存在函数的作用域内,这种特性被称为闭包。

var a=1
function foo(){
    var a=2
    function f(){return a}
    return f
}
foo()() //2

这段代码中,foo只返回一个函数对象,看起来就像在作用域外部拿到作用域内部的变量一样。
函数的方法和属性
函数也有length属性,它表示传入的实参个数(在定义的时候)。
prototype表示函数定义的时候从原型对象上继承的属性。

// call和apply都是表示临时调用方法
f.call(o)
f.apply(o)
//上面代码等同于下面代码
o.m=f
o.m()
delete o.m
//apply和call不同之处在于apply可传入实参作为数组的性式传入。

//把函数绑定至某个对象
function f(y){return this.x+y}
var o={x:1}
var g=f.bind(o) 
g(2) //3
//es5中不仅可以绑定至对象也可以绑定到this,这种技术被称之为柯里化(有种搭积木的感觉)。
function f(y,z){return this.x+y+z}
var g=f.bind({x:1},2)
g(3) // 6 (this.x=1,y=2,z=3)

记忆
函数记忆是指将上次的计算结果缓存起来,当下次调用时,如果遇到相同的参数,就直接返回缓存中的数据。(适用于计算量大,复杂的情况)

function memoize(f) {
  var cache = {};
  return function(){
    var key = arguments.length + Array.prototype.join.call(arguments, ",");
    if (key in cache) {
      return cache[key]
    }
    else return cache[key] = f.apply(this, arguments)
  }
}
var propValue = function(obj){
  return obj.value
}

var memoizedAdd = memorize(propValue)

console.log(memoizedAdd({value: 1})) // 1
console.log(memoizedAdd({value: 2})) // 1

//优化一下记忆的方法 加入了hasher判断唯一性
var memorize = function(func, hasher) {
  var memoize = function(key) {
    var cache = memoize.cache;
    var address = '' + (hasher ? hasher.apply(this, arguments) : key);
    if (!cache[address]) {
      cache[address] = func.apply(this, arguments);
    }
    return cache[address];
  };
  memoize.cache = {};
  return memoize;
};
var memoizedAdd = memorize(add, function(){
  var args = Array.prototype.slice.call(arguments)
  return JSON.stringify(args)
})

console.log(memoizedAdd(1, 2, 3)) // 6
console.log(memoizedAdd(1, 2, 4)) // 7
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值