[关闭]
@15152278073 2018-03-28T06:37:45.000000Z 字数 1899 阅读 414

Function类型

JS


说起来ECMAScript中什么最有意思,莫过于函数了----而有意思的根源,在于函数实际上是对象.每个函数都是Function的实例,而且与其他引用类型一样具有属性和方法.由于函数是对象,所以函数名实际上是一个指向函数的指针,不会与某个函数绑定.

  1. //函数的声明
  2. function sum(num1 , num2){
  3. return num1 + num2;
  4. }
  5. //与上面类似的声明
  6. var sum = function(num1 , num2){
  7. return num1 + num2;
  8. };
  9. //使用Function构造函数
  10. //不推荐
  11. var sum = new Function("num1","num2","return num1 + num2;")

没有重载

将函数名想象成指针,有助于理解JS为什么没有重载的概念.同名的函数,后面声明的会覆盖前面声明的函数.

作为值的函数

因为函数名本身就是变量,所以函数可以作为值来使用.函数不仅可以作为传递参数也可以作为函数的结果返回.

函数内部属性

在函数内部,有两个特殊对象:argumentsthis.

arguments是一个类数组对象,包含着传入的所有参数.虽然arguments的主要用途是保存函数参数,但这个对象还有一个名叫callee的属性,该属性是一个指针,指向arguments对象的函数.

  1. function factorial(num){
  2. if(num <= 1) return 1;
  3. else return num * factorial(num-1);
  4. }

以上方法如果函数名factorial,则无法得到正确的结果,所以可以这样修改:

  1. //消除函数名的耦合
  2. function factorial(num){
  3. if(num <= 1) return 1;
  4. else return num * arguments.callee(num -1)
  5. }
  6. //测试
  7. var trueFunc = factorial;
  8. factorial = function(){ return 0; };
  9. console.log(trueFunc(5)) //120
  10. console.log(factorial(5)) //0

函数内部另一个特殊对象是this.this引用的是函数据以执行的环境对象----或者说是this的值.(全局作用域是window对象).

  1. //this
  2. window.color = 'red';
  3. var o = {color:'blue'};
  4. function sayColor(){
  5. return console.log(this.color);
  6. }
  7. sayColor() //red
  8. o.sayColor = sayColor;
  9. o.sayColor() //blue

注意:函数的名字只是一个包含指针的变量而已.因此,即使在不同的执行环境中,全局的sayColor()函数与o.sayColor指向的仍是同一个函数.

函数的属性和方法

JS中的函数是对象,所以函数也有属性和方法.每个函数包含两个属性:lengthprototype.

length属性表示函数希望接收的命名参数个数.
prototype是保存他们所有的实例方法的真正所在.在JS中,prototype是不可枚举的,所以for-in无法发现.

每个函数包含两个非继承而来的方法apply()call().这两个方法都是在特定的作用域中调用函数,实际上是设置this的对象的值.不同的地方在于,apply()接收两个参数,一个是作用域对象,另一个是参数数组(可以是Array也可以是arguments).call()第一个参数是作用域对象,之后的参数直接传递给函数.

  1. //call
  2. //function.call(thisArg, arg1, arg2, ...)
  3. sayColor.call(null) //red
  4. sayColor.call(window) //red
  5. sayColor.call(o) //blue
  6. //apply
  7. //function.apply(thisArg, [argsArray])
  8. sayColor.apply(null) //red
  9. sayColor.apply(window) //red
  10. sayColor.apply(o) //blue

还有一个方法:bind().这个方法会创建一个函数实例.其this值会绑定到传给函数的值.

  1. //bind
  2. var objSayColor = sayColor.bind(o);
  3. //do some thing
  4. console.log("======")
  5. objSayColor() //blue

注意:bind()返回的是函数,所以可以延迟调用,而call()apply()是立即执行的.

参考:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注