🍉JavaScript进阶——函数进阶

简介: 🍉JavaScript进阶——函数进阶

学习目标


  • 能够说出函数的多种定义和调用方式
  • 能够说出和改变函数内部this的指向
  • 能够说出严格模式的特点
  • 能够把函数作为参数和返回值传递


1. 函数的定义和调用方式


1.1 函数的定义方式


自定义函数(命名函数)


function fn(){}
复制代码


函数表达式(匿名函数)


var fun = function(){}
复制代码


利用new Function('参数1','参数2','函数体')


该方法比较麻烦,执行效率较低,我们很少使用。


var f = new Function(){'a','b','console.log(a+b)'}
f(1,2)
复制代码


结论:


  • 所有函数都是Function的实例(对象)


  • 函数也属于对象一图明晰函数的原型三角关系



1.2 函数的调用方式

这里要分6种情况

1.普通函数

function fn(){
    console.log('走上人生巅峰')
}
fn()
复制代码

2.对象的方法

var o = {
    sayHi:function(){
        console.log('走上人生巅峰');
    }
}
o.sayHi()
复制代码

3.构造函数

new Star();
复制代码

4.绑定事件函数

btn.onclick = function(){};// 点击了按钮就可以调用这个函数
复制代码

5.定时器函数

setInterval(function(){},1000)// 这个函数是定时器自动1秒钟调用一次
复制代码

6.立即执行函数

(function(){
    console.log('走上人生巅峰')
}
)()// 立即函数是自动调用
复制代码

2. 函数内this指向问题

这些this的指向,是我们调用函数的时候确定的。调用方式的不同决定了this的指向不同,一般指向我们的调用者。

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

2.1 call方法及其应用

  • call()第一个可以调用函数 第二个可以改变函数内的this指向。
  • call()的主要作用可以实现继承
var o = {
    name:'Bob'
}
function fn(a ,b){
    console.log(this);
    console.log(a+b);
}
fn.call(o,1,2)
复制代码

2.2 apply方法及其应用

  • 也是调用函数 也可以改变函数内部的this指向
  • 但是它的参数必须是数组(伪数组)
  • apply主要应用 比如说我们可以利用 apply 借助数学内置对象求最大值,数组不能以前我们如何求数组里的最大值呢?代码如下:
var arr1 = [2, 6, 1, 77, 52, 7];
        var maximum = arr1[0];
        for ( var i = 1; i < arr1.length; i++) {
            while (arr1[i] > maximum) {
                maximum = arr1[i];
            }
        }
复制代码

这种方法看起来好像并不是很复杂,但是现在我们利用apply 借助于数学内置对象求最大值

var arr1 = [2, 6, 1, 77, 52, 7];
var max = Math.max.apply(Math,arr1);
复制代码

代码是不是变得更简洁了,6行代码现在我们只需要1行代码就能解决了(write less,do more 才是我们学习的终止嘛)

2.3 bind方法及其应用

  • 不会调用原来的函数 可以改变原来函数内部的this指向
  • 返回的是原函数改变this之后产生的原函数拷贝
var o = {
    name:'Bob'
};
function fn(a,b){
    console.log(this);
    console.log(a +b);
};
var f = fn.bind(o,1,2);
f();
复制代码

网络异常,图片无法展示
|

bind方法的应用

应用场景:我们有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向 这个时候就需要用到bind方法了,因为它不会调用原来的函数,在开发中,我们bind方法其实是用的最多的

举例:我们网站注册页面往往需要有一个按钮点击来发送手机验证码,然后这个按钮通常会被禁用60s。我们暂且改为禁用3s吧!

HTML部分

<input type="text"><button>发送</button>
复制代码

JavaScript部分

方法一

var btn = document.querySelector('button');
btn.onclick = function(){
    this.disabled = true;// 按钮被禁用,这里的this指向的是btn这个按钮
    // 接下来设置定时器 3s后按钮可用
    setTimeout(function(){
            btn.disabled = false;
    },3000)
};
 // 缺点:定时器里的btn会需要经常修改非常麻烦。
复制代码

方法二

var btn = document.querySelector('button');
btn.onclick = function(){
    this.disabled = true;// 按钮被禁用,这里的this指向的是btn这个按钮
    // 接下来设置定时器 3s后按钮可用
    var that = this;
    setTimeout(function(){
            that.disabled = false;
    },3000)
};
 // 缺点:在定时器外面将this赋值给that,这种方法可用,但是会另外开辟内存空间,不太好。
复制代码

方法三(最正确的办法)

var btn = document.querySelector('button');
btn.onclick = function(){
    this.disabled = true;// 按钮被禁用,这里的this指向的是btn这个按钮
    // 接下来设置定时器 3s后按钮可用
    setTimeout(function(){
            this.disabled = false;
    }.bind(this),3000)
};
 // 此方法很好地解决了前面两种问题,只需要在定时器函数外面改变它的this指向,使它的this指向从window变为btn这个按钮。
复制代码

2.4 call apply bind 总结

相同点:

都可以改变函数内部的this指向。

区别点:

  1. call 和apply会调用函数,并且改变函数内部this指向
  2. call和apply传递的参数不一样,call传递参数aru1,aru2形式 apply必须数组形式[arg]
  3. bind不会调用函数,可以改变函数内部的this指向

主要应用场景:

  1. call经常做继承。
  2. apply经常跟数组有关系。比如借助于数学对象实现数组最大值最小值。
  3. bind 不调用函数,但是还是想改变this指向,比如改变定时器内部的this指向。

3. 严格模式

3.1 什么是严格模式

JavaScript除了提供正常模式外,还提供了严格模式。ES5的严格模式是采用具有限制性JavaScript变体的一种方式,即在严格的条件下运行JS代码。

严格模式在IE10以上版本的浏览器中才会被支持,旧版本浏览器中会被忽略。

严格模式对正常的JavaScript语义做了一些更改:

  1. 消除了JavaScript语法的一些不合理、不严谨之处,减少了一些怪异行为。
  2. 消除代码运行的一些不安全之处,保证代码运行的安全。
  3. 提高编译器效率,增加运行速度。
  4. 为未来新版本的JavaScript做好铺垫。比如一些保留字:class,super不能做变量名。

3.2 开启严格模式

严格模式可以应用到整个脚本个别函数中,因此在使用时,我们可以将严格模式分为为脚本开启严格模式和为函数开启严格模式两种情况

1. 为脚本开启严格模式

<script>
'use strict';
  // 下面的代码按照严格模式来写
</script>
<script>
(function(){
    'use strict';
})();
</script>
复制代码

2.为函数开启严格模式

<script>
    function fn(){
        'use strict';
        // 下面的代码按照严格模式来写
    }
    function fun(){
    }
</script>
复制代码

3.3 严格模式中的变化

严格模式对JavaScript的语法和行为,都做了一些改变。

1. 变量规定

  1. 在正常模式下,如果一个变量没有声明就赋值,默认是全局变量。严格模式禁止这种用法,变量必须先用var命令声明,然后再使用。
  2. 严禁删除已经声明的变量,例如delete x;语法是错误的。

2. 严格模式下this指向问题

  1. 严格模式下全局作用域中函数中的this是undefined。
  2. 严格模式下,如果构造函数不加new调用,this是undefined,给它赋值会报错
  3. new实例化的构造函数指向创建的对象实例
  4. 定时器this还是指向window
  5. 事件,对象还是指向调用者

3. 函数变化

  1. 函数不能有重名的参数
  2. 函数必须声明在顶层,新版本的JavaScript会引入“块级作用域”(ES6中已引入)。为了与新版本接轨,不允许在非函数的代码块内声明函数。

等等,什么是非函数代码块?答:像if语句中还有for语句里这种区域就属于非函数代码块

"use strict";
if (true) {
  function f() { } // !!! 语法错误
  f();
}
for (var i = 0; i < 5; i++) {
  function f2() { } // !!! 语法错误
  f2();
}
function baz() { // 合法
  function eit() { } // 同样合法
}
复制代码

4.高阶函数

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

<script>
// 函数作为参数
function fn(callback){
    callback&&callback();
}
fn(function(){alert('hi')}
// 函数作为返回值输出
function fn(){
    return function(){}
}
fn();
</script>
复制代码

此时fn就是一个高阶函数

函数也是一种数据类型,同样可以作为参数,传递给另外一个参数使用。最典型的就是作为回调函数。


作者:Cvgod

链接:https://juejin.cn/post/6955436283548303397

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

相关文章
|
25天前
|
JavaScript 前端开发 Java
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
本文介绍了JavaScript中常用的函数和方法,包括通用函数、Global对象函数以及数组相关函数。详细列出了每个函数的参数、返回值及使用说明,并提供了示例代码。文章强调了函数的学习应结合源码和实践,适合JavaScript初学者和进阶开发者参考。
40 2
[JS]同事:这次就算了,下班回去赶紧补补内置函数,再犯肯定被主管骂
|
24天前
|
前端开发 JavaScript 开发者
除了 Generator 函数,还有哪些 JavaScript 异步编程解决方案?
【10月更文挑战第30天】开发者可以根据具体的项目情况选择合适的方式来处理异步操作,以实现高效、可读和易于维护的代码。
|
2月前
|
JavaScript 前端开发
JavaScript 函数语法
JavaScript 函数是使用 `function` 关键词定义的代码块,可在调用时执行特定任务。函数可以无参或带参,参数用于传递值并在函数内部使用。函数调用可在事件触发时进行,如用户点击按钮。JavaScript 对大小写敏感,函数名和关键词必须严格匹配。示例中展示了如何通过不同参数调用函数以生成不同的输出。
|
2月前
|
存储 JavaScript 前端开发
JS函数提升 变量提升
【10月更文挑战第6天】函数提升和变量提升是 JavaScript 语言的重要特性,但它们也可能带来一些困惑和潜在的问题。通过深入理解和掌握它们的原理和表现,开发者可以更好地编写和维护 JavaScript 代码,避免因不了解这些机制而导致的错误和不一致。同时,不断提高对执行上下文等相关概念的认识,将有助于提升对 JavaScript 语言的整体理解和运用能力。
|
2月前
|
JavaScript 前端开发
js教程——函数
js教程——函数
42 4
|
2月前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
20 2
|
2月前
|
JavaScript 前端开发 Java
【javaScript数组,函数】的基础知识点
【javaScript数组,函数】的基础知识点
25 5
|
2月前
|
JavaScript 前端开发
Node.js 函数
10月更文挑战第5天
24 3
|
2月前
|
前端开发 JavaScript
探索JavaScript函数基础
探索JavaScript函数基础
19 3
|
2月前
|
存储 JavaScript 前端开发
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
JavaScript数据类型全解:编写通用函数,精准判断各种数据类型
24 0