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
  1. 所有函数都是 Function 的实例(对象)。函数也属于对象。
    在这里插入图片描述
	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. 绑定事件函数(点击按钮调用)
	btn.onclick = function() {
    
    }
  1. 定时器函数(n秒后调用)
	setInterval(function() {
    
    
	
	}, 1000)
  1. 立即执行函数(自动调用)
	(function() {
    
    
        console.log('上山往高处走')
    })() //上山往高处走

三、函数内 this 的指向

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

在这里插入图片描述

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

在这里插入图片描述

  1. 绑定事件函数:this 指向的是函数的调用者 btn 这个按钮对象。
	let btn = document.querySelector('button')
    btn.onclick = function(){
    
    
        console.log('绑定事件函数的this: ' + this) //绑定事件函数的this: [object HTMLButtonElement]
    }
  1. 定时器函数:this 指向的也是 window
	setTimeout(function(){
    
    
        console.log('定时器的this: ' + this)
    }, 1000) //定时器的this: [object Window]
  1. 立即执行函数:this 指向的是 window
	(function(){
    
    
        console.log('立即执行函数的this: ' + this)
    })() //立即执行函数的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对象

在这里插入图片描述

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) 

在这里插入图片描述

  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'])

在这里插入图片描述

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

在这里插入图片描述

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 对象
        }
    }

在这里插入图片描述

  1. call、apply、bind 总结

相同点

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

区别点

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

主要应用场景

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

猜你喜欢

转载自blog.csdn.net/qq_45902692/article/details/124459606