定义函数的三种形式/06-this与函数的四种模式-借调模式(上下文模式)/ 函数.call(新对象)-函数.apply(新对象)-函数.bind(新对象)/

01-定义函数的三种形式

    <script>
        // 1. 有名函数
        fn1()
        function fn1() {
            console.log('我是有名函数')
        }

        // 特点:多次调用,可以先调用后定义(变量提升)

        // 2. 匿名函数(函数表达式)
        let fn2 = function () {
            console.log('我是匿名函数')
        }
        // 变量名当名字(与有名唯一的区别:无法提升函数)

        // console.log(fn1, fn2)

        // 3. 函数虽然是我们自己写的:系统最终需要系统加工:系统都是通过Function函数(顶级构造函数)产生的
        // 语法:new Function('参数1','参数2'...)
        // 1. 所有参数:都必须加引号
        // 2. 参数数量不确定

        let fn3 = new Function()
        // console.log(fn3)


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

        // 如果用Function实现
        let fn5 = new Function('a', 'b', 'return a + b')
        // Function对于参数的处理
        // 最后一个实参:永远代表函数体
        // 前面的实参:都是变量(形参变量)

        console.log(fn4, fn5)

        // 'a', 'b', 'return a + b',如何构造函数?
        let fn6 = function (a, b) {
            return a + b
        }

        // 如果想知道底层原理:eval():给字符串,能够解析成代码:eval()慎用,容易被攻击


        // 结论
        // 三种形式可以产生函数:有名、匿名、new Function()
        // 所有的函数:最终都是由Function产生的(new Function())得到的
    </script>

注意:
1.有名函数,特点:多次调用,可以先调用后定义(变量提升)
2.匿名函数(函数表达式),变量名当名字(与有名唯一的区别:无法提升函数)
3.如果用Function实现
// Function对于参数的处理
// 最后一个实参:永远代表函数体
// 前面的实参:都是变量(形参变量)



02-this与函数的四种模式-复习三种

    <script>
        // 1. 普通函数调用:定义函数,调用函数,this指向window:本质是window在调用
        function fn1() {
            console.log(this)
        }
        fn1()           // window.fn1()

        // 函数表达式也一样
        let fn2 = function () {
            console.log(this)
        }
        fn2()

        // 目前为止:所有的回调函数,里面的this全部指向window
        function fn3() {
            console.log(this)
        }

        function callBack(fn) {
            fn()    // window.fn()
        }
        callBack(fn3)

        // 2. 方法调用模式:方法就是定义在对象里面的函数(赋值给属性)
        let obj = {
            name: '张三',
            say: function () {
                console.log(this)   // 指向obj
            },
            boyfriend: {
                name: '男朋友',
                say: function () {
                    console.log(this)   // boyfriend
                }
            }
        }

        obj.say()

        obj.boyfriend.say()

        // 3. 构造函数调用模式:一定是new,new会产生对象,构造函数里面的this指向新产生的对象
        function Student(name, age) {
            this.name = name
            this.age = age

            console.log(this)
        }

        new Student('李四', 18)
        new Student('王五', 19)

    </script>

注意:
1.普通函数调用:定义函数,调用函数,this指向window:本质是window在调用
1.1.函数表达式也一样
2. 方法调用模式:方法就是定义在对象里面的函数(赋值给属性)
3. 构造函数调用模式:一定是new,new会产生对象,构造函数里面的this指向新产生的对象


03-this与函数的四种模式-借调模式(上下文模式)

    <script>
        // 1. 普通函数调用:定义函数,调用函数,this指向window:本质是window在调用
        function fn1() {
            console.log(this)
        }
        fn1()           // window.fn1()


        // 2. 方法调用模式:方法就是定义在对象里面的函数(赋值给属性)
        let obj = {
            name: '张三',
            say: function () {
                console.log(this)   // 指向obj
            },
            boyfriend: {
                name: '男朋友',
                say: function () {
                    console.log(this)   // boyfriend
                }
            }
        }

        obj.say()

        // 借调本质:我想要做某个功能,但是发现已经有人做好了这个功能,但是功能是别人的:只能借

        let newObj = { name: '小偷', skill: '偷东西' }

        // 感受借调效果:call(借调函数)
        fn1.call()              // 借调成功:运行了:没有改变里面的this

        fn1.call(newObj)        // 借调成功:改变了主人:改变了里面的this

        obj.say()
        obj.say.call(newObj)    // 只要是函数:一定可以借调

        // 小结
        // 1. 是函数一定可以借调
        // 2. 借调的目的分良种
        // 2.1 希望代码执行:借与不借没什么太大区别
        // 2.2 改变函数里面的this指向

    </script>

注意:
1. 普通函数调用:定义函数,调用函数,this指向window:本质是window在调用
2. 方法调用模式:方法就是定义在对象里面的函数(赋值给属性)



04-函数借调-call()-apply()-bind()

    <script>
        // 函数借调:修改内部的this,让代码按照自己的需求来实现相关的功能

        // 借调有三种方式实现
        /*
            call、apply:这两种都属于一次性借调(多次使用,多次借调)
            bind:绑定,可以重复使用
        */

        // 富婆 重金求子
        let richWoman = {
            name: '前端',
            getChild: function () {
                console.log(this.name + '小白')
                // console.log(this)
            }
        }

        // 正常调用
        richWoman.getChild()

        // 后端 小白
        // 借调(偷)
        let ds = { name: '后端' }

        // 借调语法
        /*
            函数.call(新对象)
            函数.apply(新对象)

            函数.bind(新对象)
        */

        // call和apply都是一次性借调
        richWoman.getChild.call(ds)
        richWoman.getChild.apply(ds)

        // 如果要多次使用:必须重新借调
        richWoman.getChild()        // 前端
        richWoman.getChild.call(ds)


        // bind:一次性绑定,可以多次调用:不是直接执行函数,而是返回一个新函数(this发生永久性的修改)
        let newGetChild = richWoman.getChild.bind(ds)
        console.log(newGetChild)

        newGetChild()
        newGetChild()

        // 如果被借调的函数重新按照正常方式执行:都是原来的结果
        richWoman.getChild()

        // 扩展:bind如果只要借调一次,就不要保存到变量
        richWoman.getChild.bind(ds)()

    </script>

注意:
1.call和apply都是一次性借调
2.bind:一次性绑定,可以多次调用:不是直接执行函数,而是返回一个新函数(this发生永久性的修改)

转:借调的三种模式的区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值