博客
关于我
【JS】函数定义与调用方式-函数this指向问题-call-apply-bind方法使用与自定义
阅读量:565 次
发布时间:2019-03-09

本文共 3474 字,大约阅读时间需要 11 分钟。

函数概念与定义方式:函数声明式、表达式、构造函数式、箭头函数与注意事项

在软件开发中,函数是代码的核心单元之一。函数可以作为独立的操作模块实现特定功能,但其定义方式有多种,灵活性更强。以下是常见的函数定义方式及其特点分析。

1. 函数声明式

此种方式通过function关键字定义函数,简洁且直接。适用于在全局或函数级别定义基本操作。

function fn(a, b) {    return a + b;}

优点

  • 代码简洁明了,没有理解障碍。
  • 社区广泛接受,兼容性强。
  • 适合频繁使用的公共功能模块。

缺点

  • 代码块较大,不利于代码量的管理。
  • 无法通过letconst 定义,不能直接用于变量声明。

2. 函数表达式

采用function关键字作为表达式的一部分,适合在模块化或函数表达式式中使用。

let fun = function(a, b) {    return a + b;};

特点

  • 与声明式相比,表达式式代码体短。
  • 可以通过赋值操作符进行更灵活的定义。
  • 适合在模块中作为变量赋值。

3. 构造函数式

通过new 操作符调用Function构造函数生成函数实例,适用于传统的对象化方法。

let fun = new Function('a', 'b', 'return a + b');

特点

  • 最高程度的灵活性,可通过代码生成任意函数。
  • 不便于贮存与维护,导致代码无从排查。
  • 适用于开发者通过字符串构造特定功能时使用。

4. 箭头函数

比声明式更简短,适用于函数表达式,并支持剩余参数。

let fn = (a, b) => {    return a + b;};

特点

  • 代码最简,语法支持更加强大。
  • 提供了显式的返回值语法。
  • 适合回调函数、事件处理等场景使用。

5. 注意事项

  • 所有函数都属于Function实例,继承自Object
  • 如果函数不使用this可能导致错误,需要谨慎操作。
  • 箭头函数的this指向取决于如何调用,需谨慎设计。

2. 函数调用的方式:如何正确调用函数

不同场景下的函数调用方式有多种,可灵活选择以满足需求。

1. 普通函数调用

直接使用函数名称或引用执行。

fun();fun.call();

2. 对象方法调用

函数作为对象的属性被调用时,this指向对象本身。

obj.fun();

3. 构造函数调用

用于创建对象时,函数作为构造函数执行。

new Fun();

4. 绑定事件函数

将函数赋值给对象的事件属性,系统会自动触发调用。

btn.onclick = function() {    // 定义具体操作};

5. 定时器函数

通过setIntervalsetTimeout定时调用函数。

setInterval(function() {    // 定时器执行操作}, 1000);

6. 立即执行函数

函数通过()直接调用,适用于不需要this指向的情况。

(function() {    // 定义操作})();

3. 函数中的this指向

this指向取决于函数调用的方式,正确理解是开发成功能的重要基础。

调用方式 this指向
普通函数调用 全局对象(浏览器环境下是 window
构造函数调用 实例对象或原型对象
对象方法调用 所有属性所属的对象
事件绑定函数调用 绑定对象
定时器函数调用 全局对象(窗口对象)
立即执行函数调用 全局对象(窗口对象)
箭头函数调用 箭头函数定义时所在的 this

注意事项

  • 在箭头函数中,this是静态的,始终指向函数定义时的 this 值。
  • 如果需要灵活控制,建议采用callapply方法。

4. 改变函数的this指向

1. 使用call方法

fun.call(thisArg, arg1, arg2, ...);
  • 同时调用this和传递参数,适用于需要多次继承的场景。-```javascriptfunction add(a, b) {console.log(a + b);}let obj = { c: 520 };add(1, 2); // this指向 windowadd.call(obj, 1, 2); // this指向 obj
### 2. 使用` apply `方法```javascriptfun.apply(thisArg, [argsArray]);
  • 行为类似 call,但传递参数为数组形式。-```javascriptfunction add(a, b) {console.log(a + b);}add(1, 2); // this指向 windowadd.apply(obj, [1, 2]); // this指向 obj
### 3. 使用` bind `方法```javascriptfun.bind(thisArg, arg1, arg2, ...);
  • 不会立即调用fun,而是返回一个新的函数。-```javascriptfunction add(a, b) {console.log(a + b);}let obj = { c: 520 };let f = add.bind(obj, 1, 2); // this指向 objf(); // 调用时 this仍然指向 obj
## 5. 自定义` call `、` apply `、` bind `方法### 1. 自定义` call `方法```javascriptexport default function call(Fn, obj, ...args) {    obj = obj === undefined || obj === null ? globalThis : obj;    obj.temp = Fn;    let result = obj.temp(...args);    delete obj.temp;    return result;}

2. 自定义apply方法

export default function apply(Fn, obj, arr) {    obj = obj === undefined || obj === null ? globalThis : obj;    obj.temp = Fn;    let result = obj.temp(...arr);    delete obj.temp;    return result;}

3. 自定义bind方法

import call from './call';export default function bind(Fn, obj, ...args) {    return function(...args2) {        return call(Fn, obj, ...args, ...args2);    };}

测试代码

import call from "./call";import apply from "./apply";import bind from "./bind";console.log("****test call ****");function add(a, b) {    console.log(this);    return a + b + this.c;}let obj = { c: 521, };window.c = 1314;console.log(call(add, obj, 10, 20));console.log(call(add, null, 30, 40));console.log(obj);console.log("****test apply****");console.log(apply(add, obj, [10, 20]));console.log(apply(add, null, [30, 40]));console.log(obj);console.log("****test bind****");let fn = bind(add, obj, 10, 20);console.log(fn());let fn2 = bind(add, obj);console.log(fn2(10, 20));

这篇文章系统地介绍了函数的定义方式及其调用方法,结合实际案例进行讲解,力求帮助开发者更高效地使用不同函数类型。

转载地址:http://lqtpz.baihongyu.com/

你可能感兴趣的文章
Objective-C实现使用二元运算符将两个数字相加fullAdder算法(附完整源码)
查看>>
Objective-C实现使用分而治之找到单峰列表的峰值算法(附完整源码)
查看>>
Objective-C实现使用数组实现约瑟夫环(附完整源码)
查看>>
Objective-C实现使用矩阵求幂的第 n 个斐波那契算法(附完整源码)
查看>>
Objective-C实现使用管道重定向进程输入输出(附完整源码)
查看>>
Objective-C实现倒计时(附完整源码)
查看>>
Objective-C实现借记款项功能(附完整源码)
查看>>
Objective-C实现全年3天打渔,2天晒网(附完整源码)
查看>>
Objective-C实现八进制转十进制算法(附完整源码)
查看>>
Objective-C实现共享内存(附完整源码)
查看>>
Objective-C实现关机、重启、注销功能的实现(附完整源代码)
查看>>
Objective-C实现关机程序(附完整源码)
查看>>
Objective-C实现关系矩阵A和B的乘积(附完整源码)
查看>>
Objective-C实现关系矩阵乘法(附完整源码)
查看>>
Objective-C实现关系矩阵乘法(附完整源码)
查看>>
Objective-C实现关键字移位字母表密码算法(附完整源码)
查看>>
Objective-C实现内存映射文件(附完整源码)
查看>>
Objective-C实现内存泄露检查(附完整源码)
查看>>
Objective-C实现内核中的自旋锁结构(附完整源码)
查看>>
Objective-C实现内格尔·施雷肯伯格算法(附完整源码)
查看>>