JavaScript忍者秘籍 -函数及函数调用

函数
js中最关键的概念:函数是第一类对象,函数与对象共存,都可以实现
· 通过字面量创建
· 赋值给变量、数组或其他对象
· 作为函数的参数
· 动态创建及分配

回调函数:在随后某个时间点会“回过来调用”的函数。
简单的回调函数:js能够对数组使用比较器实现排序,只需要调用array.sort方法

 var arrays = [0, 3, 2, 4, 7, 9, 1];
    alert(arrays.sort(function (value1, value2) {
      return value1 - value2;
    }))

如上简单的排序算法实现升序排列,若实现降序排列,只需更改为value2-value1。基本原理为:通过使用value1-value2确定是否为正数,确定是否需要调换值,内置了比较函数作为回调。

自记忆函数
将一个函数的计算结果存储起来,另一个调用也使用相同参数时,直接返回结果。

    function isPrime(value) {
      if (!isPrime.answers) {
        //检查answer确定是否创建一个cache
        isPrime.answers = {};
      }
      if (isPrime.answers[value] !== undefined) {
        //若cache中已存在,直接返回值
        return isPrime.answers[value];
      }
      //校验素数
      var prime = value !== 1;
      for (var i = 2; i < value; i++) {
        if (value % i === 0) {
          prime = false;
          break;
        }
      }
      //添加cache
      return isPrime.answers[value] = prime;
    }
    //第一次调用
    assert(isPrime(5), "5 is prime!");
    //第二次调用
    assert(isPrime.answers[5], "The answer was cached!");

优点:函数调用时会自动寻找之前调用存储的值,提高处理效率
缺点:任何类型的缓存都必然会为性能牺牲缓存,并且很难做负载测试和估计算法复杂度

函数声明

function funcName(arg1,arg2){statement;}

函数表达式

funcName(1,2); 

立即函数
(function(){})(1,2) -必须包含外部(),外部()标识该表达式为立即调用,否则会被认为函数声明,引发异常——被当做函数声明但是没有函数名,函数声明的函数名是必须的。

箭头函数 -即lambda函数,ES6新增,用于简化函数创建方式

param => expression 单参数单表达式格式
(param1,param2...) =>{ expression1;expression2;...}  多参数代码块格式
arrays.sort((value1,value2) => value1 - value2 );

若函数体是代码块,若没有return语句,返回值为undefined!!!

关于剩余参数

function test(first,second,...remainingParams){}

剩余参数使用...作为前缀,可以为一个也可为多个,只有函数的最后一个参数才能为剩余参数

默认参数

function test(param, defaultParam ='defaultParamVal'){}

默认参数可以为参数defaultParam设置默认值,如果指定实参的值,默认值会被覆盖。

隐式参数-arguments、this
arguments一般用于函数内,表示传递给函数的所有参数的集合--实参集合。

function test(a,b,c){ assert(arguments.length === 5," 5 arguments" )};
test(1,2,3,4,5);

此时,arguments表示{1,2,3,4,5} 实参集合,而非等于形参的数量。arguments对象是函数参数的别名,所以如果改变了arguments的值,也会影响对应的函数参数。

什么是严格模式? 
ES5启用,可以改变js引擎的默认行为并执行更加严格的语法检查,arguments别名的情况在严格模式下无法使用。
"use strict"; ---开启严格模式

为什么this参数表示函数上下文?
this一般指定义当前方法的类的实例。this的指向不仅是由定义函数的方式和位置决定的,也收到函数调用方式的影响。非严格模式下,this为全局上下文对象(window对象),严格模式下为undefined

调用一个函数有哪些方式?
1. 直接调用 -skulk();
除另外三种方法调用函数之外,都称为直接调用。
例如:

    function ninja(){};
    ninja(); //函数定义 直接调用
    var test = function(){};
    test(); //作为表达式 直接调用
    (function(){})(); //作为立即调用函数 直接调用

2.作为方法调用 -ninja.skulk();

    function whatsMyContext() {
      return this;
    }
    var ninja1 = {
      getMyThis: whatsMyContext //面向对象,使用ninja1对象方法getMyThis调用whatsMyContext
    };


正常使用whatsMyContext()函数直接调用,在非严格模式下,得到的this是window对象,而当getMyThis属性调用whatsMyContext函数,函数的上下文变成了ninja1,总结:函数的上下文取决于其调用方式。

3.作为构造函数调用  -new Ninja();

 var puppet = {
      rules: false
    };

    function Emperor() {
      this.rules = true;
      return puppet;
    }
    new Emperor().rules === false,构造函数中对函数的上下文操作是无效的。

4.通过apply或call方法调用  -skulk.apply(ninja); or  skulk.call(ninja);

func.apply(obj,[param1,param2,...]); //apply传递参数数组
func.call(obj,param1,param2,...);  //call传递参数列表

箭头函数绕过上下文 
箭头函数没有单独的this值,箭头函数的this值与所声明的上下文相同。

bind方法绑定上下文
 

    var button = {
      clicked: false,
      click: function(){
        this.clicked = true;
        assert(button.clicked,"The button has been clicked");
      }
    };
    var elem = document.getElementById("test");
    elem.addEventListener("click", button.click.bind(button));

所有函数都可以访问bind方法,可以创建并返回一个新函数,并绑定在传入的对象上,不管如何调用函数,this都是对象本身。

函数和方法之间有什么区别?
声明不同、结构不同

如果一个构造函数显式地返回一个对象会发生什么?

 var puppet = {
      rules: false
    };
    function Emperor() {
      this.rules = true;
      return puppet;
    }
    var emperor = new Emperor();
       assert(emperor === puppet,
      "The emperor is merely a puppet!");
    assert(emperor.rules === false,
      "The puppet does not know how to rule!");

 新生成的对象会传递给构造函数作为函数上下文this,同时被初始化。


总结:
    如果构造函数返回一个对象,则该对象作为整个表达式的值返回,而传入构造函数的this将会被丢弃;
    但是,如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值