JS学习第11天——函数进阶(this指向、严格模式、高阶函数、闭包、递归)

一、函数的定义和调用

1、函数的定义方式

①自定义函数(命名函数) ②函数表达式(匿名函数)③new Function()(效率低,很少使用)
所有函数都是Function的实例对象,函数也属于对象
在这里插入图片描述

2、函数的调用方式

6种函数:① 普通函数 ②对象的方法 ③构造函数 ④绑定事件函数 ⑤定时器函数 ⑥立即执行函数

//  调用方式
// 1.普通函数
function fn(){};
fn();
fn.call()

// 2.对象的方法
var obj = {
  sayHi: function () {},
};
obj.sayHi();

// 3.构造函数
function Star() {}
new Star();

// 4.绑定事件函数
btn.onclick = function () {};

// 5.定时器函数
setTimeout(function () {}, 1000);

// 6.立即执行函数
(function () {})();

二、this

1、this指向

调用方式this指向
普通函数调用window
构造函数调用实例对象,原型对象里面的方法也指向实例对象
对象方法调用该方法所属对象
事件绑定方法绑定事件对象
定时器window
立即执行函数window

2、改变this指向

JS中改变this指向的方法有:① bind()call()apply()方法
《1》call()(调用函数)

fun.call(thisArg, arg1, arg2, ...);
// thisArg:当前调用函数this的指向对象
// arg1,arg2:传递的其他参数

返回值:函数的返回值
使用场景:改变this指向并且调用该函数,比如继承(返回值是函数的返回值)

《2》apply()(跟数组相关)

fun.apply(thisArg, [argsArray]);
// argsArray:传递的值,必须包含在数组里面

返回值:函数的返回值
使用场景:主要跟数组有关系,比如借助于数学对象实现数组最大值最小值

《3》bind()(不调用函数)

fun.bind(thisArg, arg1, arg2, ...);

返回值:指定的 this值和初始化参数改造的原函数拷贝
使用场景:只想改变this指向,不调用该函数,比如改变定时器内部this指向

三、严格模式

JS除了提供正常模式外,还提供了严格模式(strict mode),严格模式IE10以上支持

开启严格模式的分类:① 为脚本开启严格模式 ② 为函数开启严格模式

1、为脚本开启严格模式

在所有语句之前放一个特定语句“use strict”;(或‘use strict’;)

<script>
 "use strict";
</script>

有的 script 基本是严格模式,有的 script 脚本是正常模式,这样不利于文件合并,所以可以将整个脚本文件放在一个立即执行的匿名函数之中。这样独立创建一个作用域而不影响其他 script 脚本文件。

<script>
 (function (){
 "use strict";
 var num = 10;
 function fn() {}
 })();
</script

2、为函数开启严格模式

要把“use strict”; (或 ‘use strict’; ) 声明放在函数体所有语句之前

function fn(){
 "use strict";
 return "这是严格模式。";
}

3、严格模式中的变化

《1》变量规定
① 变量都必须先用var 命令声明,然后再使用
②严禁删除已经声明变量

《2》this指向
严格模式下全局作用域中函数中的 this 是 undefined
② 如果构造函数不加new调用, this 指向的是undefined 如果给他赋值则会报错

《3》函数变化
函数不能有重名的参数
② 函数必须声明在顶层

更多严格模式要求:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

四、高阶函数

高阶函数是对其他函数进行操作的函数,它接收函数作为参数 将函数作为返回值输出

//  接收函数作为参数
function fn(callback) {
  callback && callback();
}
fn(function () {});
// 函数作为返回值输出
function fn() {
  return function () {};
}
fn();

典型的高阶函数应用:回调函数

五、闭包

变量根据作用域不同分为两类:① 全局变量 ② 局部变量
函数外部不能使用局部变量,当函数执行完毕,本作用域的局部变量会销毁

1、闭包(closure)

闭包:有权访问另一个函数作用域中变量函数

function fn() {  // fn就是闭包函数
  var num = 10;
  function fn2() {
    console.log(num);
  }
  fn2();
}
fn();

2、在chrome中调试闭包

在这里插入图片描述

3、闭包的作用

延时变量的作用范围

function fn() { 
	var num = 10; 
	return function { 
	console.log(num); // 10 
	}
}
var f = fn();
f()

4、思考题

// 思考题 1:
var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            return this.name;
        };
    }
};
console.log(object.getNameFunc()());
// 类似于
var f = object.getNameFunc();
var f = function() {
    return this.name;
}
f();

// 思考题 2:
var name = "The Window";
var object = {
  name: "My Object",
  getNameFunc: function () {
    var that = this;
    return function () {
      return that.name;
    };
  },
};
console.log(object.getNameFunc()());

六、递归

递归函数:在函数内部可以调用其本身
由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return

1、求123*…*n的阶乘

function fn(n) {
 if (n == 1) {
   return 1;
 }
 return n * fn(n - 1);
}

2、求斐波那契数列

function fn(n) {
  if (n < 3) {
    return 1;
  }
  return fn(n - 2) + fn(n - 1);
}

3、根据ID返回对象的数据

var data = [
  {
    id: 1,
    name: "家电",
    goods: [
      {
        id: 11,
        gname: "冰箱",
        goods: [
          {
            id: 111,
            gname: "海尔",
          },
          {
            id: 112,
            gname: "美的",
          },
        ],
      },
      {
        id: 12,
        gname: "洗衣机",
      },
    ],
  },
  {
    id: 2,
    name: "服饰",
  },
];
function fn(data, id) {
  var a = {};
  data.forEach((item) => {
    if (item.id == id) {
      a = item;
    } else if (item.goods && item.goods.length > 0) {
      a = fn(item.goods, id);
    }
  });
  return a;
}
console.log(fn(data, 11));
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
内容简介 · · · · · · JavaScript 是近年来非常受瞩目的一门编程语言,它既支持面向对象编程,也支持函数式编程。本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、变量的作用域和闭包高阶函数、由函数构建函数递归、纯度和不变性以及更改政策、基于流的编程、类编程。除此之外,附录中还介绍了更多函数JavaScript。 本书内容全面,示例丰富,适合想要了解函数式编程的JavaScript程序员和学习JavaScript函数式程序员阅读。 作者简介 · · · · · · Michael Fogus是Dynamic Animation Systems的软件架构师,在分布式仿真、机器视觉和专家系统建设方面经验丰富。他是Clojure、ClojureScript以及Underscore-contrib的贡献者,还是《Clojure编程乐趣》的作者。 目录 · · · · · · 第1章 JavaScript函数式编程简介1 1.1 JavaScript案例1 1.2 开始函数式编程4 1.2.1 为什么函数式编程很重要4 1.2.2 以函数为抽象单元7 1.2.3 封装和隐藏9 1.2.4 以函数为行为单位10 1.2.5 数据抽象14 1.2.6 函数JavaScript初试17 1.2.7 加速19 1.3 Underscore示例22 1.4 总结23 第2章 一等函数与Applicative编程24 2.1 函数是一等公民24 2.2 Applicative编程30 2.2.1 集合中心编程31 2.2.2 Applicative编程的其他实例32 2.2.3 定义几个Applicative函数35 2.3 数据思考36 2.4 总结43 第3章 变量的作用域和闭包44 3.1 全局作用域44 3.2 词法作用域46 3.3 动态作用域47 3.4 函数作用域51 3.5 闭包52 3.5.1 模拟闭包53 3.5.2 使用闭包57 3.5.3 闭包的抽象59 3.6 总结60 第4章 高阶函数62 4.1 以其他函数为参数的函数62 4.1.1 关于传递函数的思考:max、finder和best63 4.1.2 关于传递函数的更多思考:重复、反复和条件迭代 (iterateUntil)65 4.2 返回其他函数函数67 4.2.1 高阶函数捕获参数69 4.2.2 捕获变量的好处69 4.2.3 防止不存在的函数:fnull72 4.3 整合:对象校验器74 4.4 总结77 第5章 由函数构建函数78 5.1 函数式组合的精华78 5.2 柯里化(Currying)83 5.2.1 向右柯里化,还是向左84 5.2.2 自动柯里化参数85 5.2.3 柯里化流利的API88 5.2.4 JavaScript柯里化的缺点89 5.3 部分应用89 5.3.1 部分应用一个和两个已知的参数91 5.3.2 部分应用任意数量的参数92 5.3.3 局部应用实战:前置条件93 5.4 通过组合端至端的拼接函数96 5.5 总结98 第6章 递归100 6.1 自吸收(self—absorbed)函数(调用自己的函数)100 6.1.1 用递归遍历图105 6.1.2 深度优先自递归搜索106 6.1.3 递归和组合函数:Conjoin和Disjoin108 6.2 相互关联函数函数调用其他会再调用回它的函数110 6.2.1 使用递归深克隆111 6.2.2 遍历嵌套数组112 6.3 太多递归114 6.3.1 生成器117 6.3.2 蹦床原理以及回调120 6.4 递归是一个底层操作121 6.5 总结122 第7章 纯度、不变性和更改政策123 7.1 纯度123 7.1.1 纯度和测试之间的关系124 7.1.2 提取纯函数125 7.1.3 测试不纯函数的属性126 7.1.4 纯度与引用透明度的关系127 7.1.5 纯度和幂等性129 7.2 不变性130 7.2.1 如果一棵树倒在树林里,有没有声音?132 7.2.2 不变性与递归133 7.2.3 冻结和克隆134 7.2.4 在函数级别上观察不变性136 7.2.5 观察对象的不变性137 7.2.6 对象往往是一个低级别的操作140 7.3 控制变化的政策141 7.4 总结144 第8章 基于流的编程145 8.1 链接145 8.1.1 惰性链148 8.1.2 Promises152 8.2 管道154 8.3 数据流与控制流158 8.3.1 找个一般的形状161 8.3.2 函数可以简化创建action164 8.4 总结166 第9章 无类编程167 9.1 数据导向167 9.2 Mixins173 9.2.1 修改核心原型175 9.2.2 类层次结构176 9.2.3 改变层级结构179 9.2.4 用Mixin扁平化层级结构180 9.2.5 通过Mixin扩展新的语义185 9.2.6 通过Mixin混合出新的类型187 9.2.7 方法是低级别操作188 9.3.call(“Finis”);190 附录A 更多函数JavaScript191 A.1 JavaScript函数式库191 A.1.1 函数JavaScript191 A.1.2 Underscore—contrib192 A.1.3 RxJS192 A.1.4 Bilby194 A.1.5 allong.es195 A.1.6 其他函数式库196 A.2 能编译成JavaScript函数式语言196 A.2.1 ClojureScript196 A.2.2 CoffeeScript197 A.2.3 Roy198 A.2.4 Elm198 附录B推荐书目

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值