ES6 —— 函数进阶

简介: ES6 —— 函数进阶

一、函数的定义方式

  1. 函数声明方式 function 关键字(命名函数)
  function fn() {}
  1. 函数表达式(匿名函数)
  let fn = function() {}
  1. new Function('参数1', '参数2', '参数3')
  let f = new Function('a', 'b', 'console.log(a + b)')
    f(1, 2) //3

所有函数都是 Function 的实例(对象)。函数也属于对象。

49d0186496514145afd946129d87a38e.png

  let f = new Function('a', 'b', 'console.log(a + b)')
    f(1, 2)
    console.log(f instanceof Object) //true

二、函数的调用方式

  1. 普通函数
  function fn(){
        console.log('无名的人')
   }
    fn() //无名的人
    fn.call() //无名的人 
  1. 对象的方法
  let o = {
        sing(){
            console.log('我敬你一杯酒')
        }
    }
    o.sing() //我敬你一杯酒
  1. 构造函数
  function Star(uname){
        this.uname = uname
    }
    let a = new Star('无名的人')
    console.log(a)
  1. 370aea37f2b248219326e3bae41da9bb.png
  2. 绑定事件函数(点击按钮调用)
  btn.onclick = function() {}
  1. 定时器函数(n秒后调用)
  setInterval(function() {
  }, 1000)
  1. 立即执行函数(自动调用)
  (function() {
        console.log('上山往高处走')
    })() //上山往高处走

三、函数内 this 的指向

函数内 this 一般指向我们的调用者。

c4c10f1f5e9a4737a0d19d42e0623136.png

  1. 普通函数:this 指向 window
  function fn(){
        console.log('普通函数的this: ' + this)
    }
    fn() //普通函数的this: [object Window]
  1. 对象的方法:this 指向 对象 o
  let o = {
        sing(){
            console.log('对象方法的this: ' + this)
        }
    }
    o.sing() //对象方法的this: [object Object]
  1. 构造函数:this 指向 实例对象。原型对象里面的this 指向的也是实例对象。
  function Star(uname){
        this.uname = uname
        console.log(this)
    }
    Star.prototype.sing = function(){   
        console.log(this)
    }
    let a = new Star('毛不易')
    Star.prototype.sing()

6c4ad7c60d0043e6b3ff89d696e75dd7.png

  1. 绑定事件函数:this 指向的是函数的调用者 btn 这个按钮对象。
  let btn = document.querySelector('button')
    btn.onclick = function(){
        console.log('绑定事件函数的this: ' + this) //绑定事件函数的this: [object HTMLButtonElement]
    }

定时器函数:this 指向的也是 window

  setTimeout(function(){
        console.log('定时器的this: ' + this)
    }, 1000) //定时器的this: [object Window]

四、改变函数内部 this 指向

  1. call() 方法调用一个对象。但它也可以改变函数的 this 指向。
  fun.call(thisArg, agr1, arg2, ...)
  let o = {
        name: '张三'
    }
    function fn(a, b){
        console.log(this)
        console.log(a + b);
    }
    fn.call(o, 3, 8) //fn的this指向o对象

94d80bfa6a97414f8bed68199bc2bdca.png

call 主要用来实现继承

  function Father(uname, age){
        this.uname = uname
        this.age = age
    }
    function Son(uname, age){
        Father.call(this, uname, age)
    }
    let son = new Son('张三', 18)
    console.log(son) 

81e5766023a040c18eb2703329232c78.png

  1. apply() 方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的 this 指向。
  fun.apply(thisArg, [argsArray])
  1. thisArg:在 fun 函数运行时指定的 this 值。
  2. argsArray:传递的值,必须包含在 数组(伪数组) 里面。
  3. 返回值就是函数的返回值,因为它就是调用函数。
  let o = {
        name: '张三'
    }
    function fn(age){
        console.log(this)
        console.log(age)
    }
    fn.apply(o, ['18'])

3498d36f980547d38347c62f4aa355a3.png

apply 主要应用:比如利用 apply 借助数学内置对象求最大值

  let arr = [1, 2, 3, 4]
    let max = Math.max.apply(Math, arr)
    let min = Math.min.apply(Math, arr)
    console.log(max) //4
    console.log(min) //1
  1. bind() 方法不会调用函数。但是能改变函数内部的 this 指向。
  fun.bind(thisArg, arg1, arg2, ...)
  1. thisArg:在 fun 函数运行时指定的 this 值。
  2. arg1,arg2:传递的其他参数。
  3. 返回由指定的 this 值和初始化参数改造的原函数拷贝。
  let o = {
        name: '张三'
    }
    function fn(a, b){
        console.log(this)
        console.log(a + b)
    }
    let f = fn.bind(o, 1, 2)
    f()

852d77ade31947a7b5f3744e1455c543.png

bind 主要应用:如果有的函数我们不需要立即调用,但是又想改变这个函数内部的 this 指向,此时用 bind

例子:我们有一个按钮,当我们点击了之后,就禁用这个按钮,1 秒钟后开启这个按钮。

  //不使用bind()
  let btn = document.querySelectorAll('button')
    for(let i=0;i<btn.length;i++){
        btn[i].onclick = function(){
            this.disabled = true //这个this 指向btn按钮(调用者)
            let that = this //把btn 的this 给that
            setTimeout(function() {
                that.disabled = false //此时定时器函数里面的 that 指向的是 btn
            }, 1000) 
        }
    }
  //使用bind()
  let btn = document.querySelectorAll('button')
    for(let i=0; i<btn.length; i++){
        btn[i].onclick = function(){
            this.disabled = true //这个this 指向btn按钮(调用者)
            setTimeout(function() {
                this.disabled = false //此时定时器函数里面的 this 指向的是 btn
            }.bind(this), 1000) //bind(this) 里面的this 指向的是btn 对象
        }
    }

766cbacf146b43c7b4ab475c462f02bc.png


call、apply、bind 总结

相同点


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

区别点


call 和 apply 会调用函数,并且改变函数内部 this 指向。

call 和 apply 传递的参数不一样,

call 传递参数 aru1,aru2… 形式。

apply 必须是数组形式 [arg]

bind 不会调用函数,可以改变函数内部 this 指向。

主要应用场景


call 经常做继承

apply 经常跟数组有关系。比如借助于数学对象实现数组最大最小值。

bind 不调用函数,但是还想改变 this 指向。比如改变定时器内部的 this 指向。


相关文章
|
1月前
|
前端开发
【面试题】如何使用ES6 ... 让代码优雅一点?
【面试题】如何使用ES6 ... 让代码优雅一点?
|
1月前
|
JavaScript 前端开发 小程序
大前端进阶(ES6)
大前端进阶(ES6)
58 0
|
7月前
ES6系列笔记-参数
ES6系列笔记-参数
28 1
|
1月前
|
前端开发 JavaScript 开发者
ES6知识点
ES6知识点
33 0
|
7月前
|
JavaScript
ES6的基础用法
对js es6的用法进行简单介绍
|
7月前
|
JavaScript 前端开发 Java
|
7月前
|
Web App开发 JavaScript 前端开发
|
7月前
|
存储 JavaScript 前端开发
|
7月前
|
前端开发 JavaScript 编译器