当前位置: 首页 > article >正文

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

目录

  • 一、函数的定义和调用
    • 1、函数的定义方式
    • 2、函数的调用方式
  • 二、this
    • 1、this指向
    • 2、改变this指向
  • 三、严格模式
    • 1、为脚本开启严格模式
    • 2、为函数开启严格模式
    • 3、严格模式中的变化
  • 四、高阶函数
  • 五、闭包
    • 1、闭包(closure)
    • 2、在chrome中调试闭包
    • 3、闭包的作用
    • 4、思考题
  • 六、递归
    • 1、求1*2*3*...*n的阶乘
    • 2、求斐波那契数列
    • 3、根据ID返回对象的数据

一、函数的定义和调用

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));

http://www.kler.cn/a/488.html

相关文章:

  • 将多个 k8s yaml 配置文件合并为一个文件
  • 【HarmonyOS】鸿蒙将资源文件夹Resource-RawFile下的文件存放到沙箱目录下
  • MacOS下TestHubo安装配置指南
  • 详细讲解axios封装与api接口封装管理
  • 使用 ffmpeg 拼接合并视频文件
  • SwiftUI 入门趣谈:在文本框(TextField)内限制数字的输入
  • 一个nginx的小项目,不写代码,实现在局域网内访问其他电脑的网页
  • 裸辞3个月,面试了25家公司,终于找到心仪的工作了
  • C#基础之面向对象编程(二)
  • MySQL:JDBC
  • 快速测试两台服务器间的网速(ChatGPT回复)
  • 2022年全国职业院校技能大赛(中职组)网络安全竞赛试题——MYSQL安全测试解析(详细)
  • 【linux】:进程概念
  • 08从零开始学Java之记事本怎么编写Java代码?
  • Java基于UDP实现 客户端/服务器
  • ARM学习(19)交叉编译工具链的理解
  • 解析带小数的字节流
  • Graphics2D绘制图形详解
  • IIS发布.net6 api+微信小程序/H5真机调试接口的流程
  • 【SpringMVC】获取 -请求参数- 的多种方式
  • 《深入浅出WPF》——XAML语法及基础知识
  • 过来人告诉你:Java学到什么程度可以找工作?
  • C++【list容器模拟实现函数解析】
  • 【数据结构】万字超详解顺序表(比细狗还细)
  • 【MapGIS精品教程】013:如何制作三维电子沙盘?
  • 微信小程序开发学习笔记