this-> call,apply,bind

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }

        html,body{
            height: 100%;
            overflow: hidden;
            background: -webkit-linear-gradient(top left,lightblue,lightpink);
        }
    </style>
</head>
<body>
    <script>
        /**
         *  this的几种情况
         *    + 事件绑定
         *    + 函数执行
         *       + 自执行函数
         *       + 回调函数
         *       + ...
         *    + 构造函数执行
         *    + 基于call / apply / bind 改变函数中的this
         *    + 箭头函数中没有自己的this,所用到的this是使用上下文中的
         * */  
         // Function.prototype -> call / apply / bind 所有的函数都可以调取这三个方法


        //  window.name = "WINDOW";
        //  let obj = {
        //      name:"Eric",
        //      age:29
        //  }

        //  function fn(x,y){
        //      console.log(this.name,x+y);
        //  }

        // fn() // this -> window  "WINDOW"

        //  obj.fn();  // obj.fn is not a function

        // this->obj Eric 
        // fn.call(obj)   // (fn先基于__proto__找到Function.prototype.call,
                       //  把call方法执行的时候,call方法内部实现了一些功能,会把fn执行,
                       //  并且让fn中的this变为第一个实参值)

        // fn.call(obj,10,20)  // this->obj x->10 y = 20 Eric 30
        // fn.call() // this -> window 严格模式下是 undefined
        // fn.call(null) // this -> window 严格模式下是 null
 
        //  ============================
        //  apply 的作用和细节上 和call 一样, 只有一个区别,传递给函数实参的方式不一样
        // fn.apply(obj,[ 10,20 ]) // 最后结果和 call 是一样的,只不过apply方法执行的时候要求:传递给函数的实参信息
                                // 都要放置在一个数组汇中,但是apply内部也会向call方法一样,把这些实参信息一项项的传递给函数

        
        
        //  需求1 获取数组中的最大值 
        // let arr = [10,30,15,36,23]; 
 
        // 0 
        //  let max = Math.max(...arr)
        //  console.log(max);

        // 1
        // arr.sort((a,b)=>{
        //     return  b - a
        // })
        // let max = arr[0]
        // console.log(max); 

        // 2 
        // var max = arr[0]
        // for(var i=0;i<arr.length;i++){
        //     if(max < arr[i]){
        //         max = arr[i]
        //     }
        // }
        // console.log(max); 

        // 3
        // let max = arr.reduce((result,item)=>{ 
        //     return item > result ? item : result
        // })
        // console.log(max); 




        // ================================
        // function sum(){
        //     /**
        //      * arguments: 实参集合, 它是一个类数组,不是Array的实例,所以不能调用Array.prototype
        //      * 上的方法,但是结构和数组非常的相似, 都是 索引 + length
        //      * 
        //      * */  
        //     // console.log(arguments);

        //     // let arr = Array.from(arguments)  // 1
        //     // let arr = [...arguments]         // 2

        //     // let arr = []
        //     // for(let i=0;i<arguments.length;i++){
        //     //     arr.push(arguments[i])
        //     // }

        //     let arr = [].slice.call(arguments) 
        //     return arr.reduce((result,item)=>{
        //         return result + item
        //     })  
        // }
        // let total = sum(10,20,30,40,10)
        // console.log(total);


        // ========================================
        // window.name = "WINDOW";
        //  let obj = {
        //      name:"Eric",
        //      age:29
        //  }

        //  function fn(x,y){
        //      console.log(this,x,y);
        //  }
 
         /**
          *  this -> body
          *  x = Event
          *  y undefined
         */
        //  document.body.onclick = fn;

         /**
          * this->window 
          * x -> undefined
          * y -> undefined
         */
        //  setTimeout(fn,1000) 


        /**
         *  call/apply 在处理的时候,会立即执行
         * 
        */
        // document.body.onclick = fn.call(obj,10,20)
        // setTimeout(fn.call(obj,10,20),1000) 
 
        // 预先处理思想
        // document.body.onclick = function(ev){
        //     fn.call(obj,10,20)
        // }

        // setTimeout(function(){
        //     fn.call(obj,10,20)
        // },1000) 


        // bind 不会立即执行,只是处理了 this 和参数
        // document.body.onclick = fn.bind(obj,10,20)
        // setTimeout(fn.bind(obj,10,20),1000) 

        // =======================
        // 箭头函数没有自己的this 
        let obj = {
            name:"Eric",
            age:29,
            fn:function(){
                return function(){
                    console.log(this);
                }
            }
        } 
        let f = obj.fn();
        f() // this -> window

    </script>
</body>
</html>
posted @ 2021-07-21 14:54  13522679763-任国强  阅读(23)  评论(0)    收藏  举报