函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向

创建函数的 三种方式

<script>
        // 函数的定义方式
        // 1.自定义函数 命名函数
        function fn() { }
        // 2.函数表达式 匿名函数
        var fun = function () { }
        // 3.利用 new Function('参数1','参数2','函数体')
        var f = new Function('a', 'b', 'console.log(a+b)')
        f(1, 2)
        // 4所有函数 都是Function 的实例(对象)
        console.dir(f)
        // 5.函数也属于对象
        console.log(f instanceof Object);
    </script>

函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
函数的调用方式

  • 普通函数
  • 对象的 方法
  • 构造函数
  • 绑定事件函数
  • 定时器函数
  • 立即执行函数
 <script>
        // 1.普通函数
        function fn() {
            console.log('普通函数');
        }
        fn();  //普通函数
        fn.call()//普通函数
        // 2.对象的方法
        var a = {
            sing: function () {
                console.log('对象的方法');
            }
        }
        a.sing()  //对象的方法
        // 3 构造函数
        function Star() {
            console.log('构造函数');
        }
        new Star
            //4  绑定事件函数
            // btn.onclick = function () { } // 点击按钮就可以调用

            //   5 时器函数
            / setInterval(function () {
                console.log('定时器');
            }, 1000); //定时器函数1秒钟自动调用一次
        // 6 立即执行函数
        (function () {
            console.log('立即执行 自动调用');
        })();
    </script>

函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
函数内的this指向

这些 this的指向 是当我们 调用函数的时候 确定的 调用当时的不用 决定了this的指向不同
一般指向我们的调用者
函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
改变函数内部的this指

JavaScript 为我们专门提供了一些函数方法来帮助我们更优雅的处理函数内部this指向的问题
常有:bind()、call()、apply()

call()方法

call()方法调用一个对象 简单理解为调用函数的方式 但它可以改变函数的 this指向

funcall( thisArg,arr1,arr2,....)
<script>
        // 1.call
        var o = {
            nume: 'andy'
        }
        var sum = 0
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        }
        // call  可以改变this的指向 也可传递参数
        fn.call(o, 1, 2)  //nume: 'andy' 3 

        // call的主要作用可以实现继承
        function Father(uname, age, sex) {
            this.uname = uname;
            this.age = age;
            this.sex = sex;
        }
        function Son(uname, age, sex) {
            Father.call(this, uname, age, sex)

        }
        var son = new Son('李白', 100, '男')
        console.log(son);
    </script>

函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
apply 方法

apply() 方法调用一个函数 简单理解 为调用函数的方式 但是它可以改变this的指向
fun.apply(thisArg ,[argasArray])

  • thisArg :在函数运行时指定的this值
  • argsArray:传递的值 必须包含在数组里面
  • 返回值就是函数的 返回值 因为他就是调用函数
// apply ()
        var a = {
            uname: '唐僧'
        };
        function fun(arr) {
            console.log(this);
            console.log(arr);
        }
        fun.apply(a, ['西游记'])

        // apply的主要应用  可以利用 apply 借助于数学内置对象 求最大值
        // Math.max ()
        var arrr = [1, 2, 3, 4, 5, 10]
        // var max = Math.max.apply(null, arrr)
        var max = Math.max.apply(Math, arrr)
        var min = Math.min.apply(Math, arrr)
        console.log(max, min);


函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
bind方法

bind()方法不会调用函数 但是能改变函数内部的this指向

fun.bind(thisArg,arg1,arg2,...)
  • thisArg :在fun函数运行时指定的this值
  • arg1 arg2 传递的其他参数
  • 返回由指定的this值和初始化改造的源函数拷贝
 // bind ()
        var p = {
            uname: '猪八戒'
        }
        function funn() {
            console.log(this);
        }
        var f = funn.bind(p) //不会调用原来的函数 可以改改变this的指向
        f()
        // 返回的是原函数改变this之后产生的新函数

函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
bind方法应用

<button>点击</button>
    <script>
        var btn = document.querySelector('button')
        btn.onclick = function () {
            this.disabled = true //点击之后 禁用  this 指向的是btn 按钮 
            setTimeout(function () {   //定时器
                this.disabled = false; ///this 的指向 是 btn 这个对象
            }.bind(this), 2000) // this 的指向 是 btn 这个对象
        }
    </script>

函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向函数进阶、函数的调用方式、函数内部的this指向、改变函数内部的this指向
call apply bind 总结

相同点:
都可以改变函数内部的this指向
区别点:

  • call和apply 会调用函数 并且改变函数内部的this 指向
  • call和apply 传递的参数不一样 call 传递参数 aru1 ,aru2… 形式 apply 传递数组形式【arg】
  • bind 不会调用函数 可以改变 函数内部的this指向

主要应用场景

  • call 经常做继承
  • apply 经常跟数组有关 比如借助于数学对象实现数组最大值 最小值
  • bind 不调用函数 但还想改变this指向 比如改变定时器内部 this 指向
上一篇:前端:this指向问题,强制改变this指向


下一篇:Java到底是值传递还是引用传递