精华内容
下载资源
问答
  • this指向
    千次阅读
    2022-01-13 16:47:33

    this

    解析器在调用函数时,每次都会向函数内部传递进一个隐含的参数,这个隐含的参数就是 this,this指向的是一个对象,这个对象我们称为函数执行的上下文对象。

    函数内this的指向

    我们都知道,函数的调用有六种形式。

    根据函数的调用方式的不同,this会指向不同的对象:

    -1.以函数的形式(包括普通函数、定时器函数、立即执行函数)调用时,this的指向永远都是window。比如fun();相当于window.fun();

    -2.以方法的形式调用时,this指向调用方法的那个对象

    -3.以构造函数的形式调用时,this指向实例对象

    -4.以事件绑定函数的形式调用时,this指向绑定事件的对象

    -5.使用call和apply调用时,this指向指定的那个对象

    function fun(){
        console.log(this);
        console.long(this.name);
    }
    
    var obj1 = {
        name:'smyh',
        sayName:fun
    };
    
    var obj2 = {
        name:'vso',
        sayName:fun
    };
    
    var name = '全局name属性';
    
    fun();

    打印结果:

    window
    全局name属性

     上面的举例可以看出,this指向的是window对象,所以this。name指的是全局的name。

    function fun(){
          console.log(this);
          console.log(this.name);
    }
    
    var obj1 = {
           name:'smyh',
           sayName:'fun'
    };
    
    var obj2 = {
          name:'cad',
          sayName:'fun'
    };
    
    var name = '全局name属性';
    
    obj2.sayName();
    
    

    打印结果:

    Object
    cad

    上面的举例可以看出,this指向的对象是obj2,所以this.name指的是obj2.name。

    箭头函数中this的指向

    ES6中的箭头函数并不会使用上面的准则,而是会继承外层函数调用的this绑定(无论this绑定到什么)。

    改变函数内部的 this指向

    JS专门为我们提供了一些方法来改变函数内部的this指向。如:call()、apply()、bind()方法。

    更多相关内容
  • this是javascript的一个关键字,随着函数使用场合不同,this的值会发生...但是总有一个原则,那就是this指的是调用函数的那个对象,通过本文给大家介绍JS中改变this指向的方法(call和apply、bind),需要的朋友参考下
  • 在js中setTimeout和setInterval都是用来定时的一个功能,下面这篇文章主要给介绍了JS中setInterval和setTImeout的this指向问题,文中通过示例介绍的很详细,有需要的朋友可以参考借鉴,一起来看看吧。
  • 解决使用attachEvent函数时,this指向被绑定的元素的问题的方法
  • 本文主要介绍了函数四种调用模式以及其中的this指向的相关知识,具有一定的参考价值,下面跟着小编一起来看下吧
  • this指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象,接下来我会深入的探讨这个问题。
  • 2:一般情况下this指向它的调用者 3:es6的箭头函数中,this指向创建者,并非调用者 4:通过call、apply、bind可以改改变this的指向 下面我们具体分析一下 1:在函数调用时  (非严格模式) const func = function () {...
  • 函数的作用域与this指向是js中很重要的一部分,理清这点东西需要个逻辑,看看我的逻辑怎么样… 下面是个提纲,可以直接挑你感兴趣的条目阅读。 • 函数的定义方式:直接定义(window下,内部定义),对象的方法,...
  • 主要介绍了详解vue中的computed的this指向问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 主要介绍了JavaScript中this指向的相关资料,帮助大家更好的理解和学习JavaScript,感兴趣的朋友可以了解下
  • this指向,并改变this指向

    千次阅读 2022-01-19 19:58:37
    不同场景下的this指向问题 window 对象 函数 类

    不同场景下的this指向问题

    window

    在js文件中直接打印this

    console.log(this); // window 
    

    浏览器中如下:
    在这里插入图片描述

    对象

    1、首先创建一个平平无奇 对象,在方法中打印this:

    const obj = {
        name: 'wang',
        age: 18,
        play: 'pingpang',
        baseInfo: function() {
            console.log(this); // obj对象
            console.log(this.name + '的年龄是' + this.age ); // wang的年龄是18
        }
    }    
    obj.baseInfo()
    

    浏览器打印如下:
    baseInfo

    因此:调用对象的方法,this指向对象本身

    2、下一步,我们改造上面obj,改变[‘play’]的值,并创造 一个新属性

    const obj = {
        name: 'wang',
        age: 18,
        play: 'pingpang',
        likes: function() {
            this.play = 'basketball'
            console.log(this); // 更改后的 obj对象
            this.likeType = '有氧'
            console.log(this.name + ' like ' + this.play +'。并喜爱' + this.likeType); // wang like basketball。并喜爱有氧
        }
    }
    
    obj.likes()
    

    打印如下:
    likes
    因此,this指向对象时,改变原有对象的key值,或创建一个新的key,此时this指向被改变之后的对象

    3、上面我们测试了对象中的普通函数,如果换成 箭头函数 呢?继续改造obj:

    const obj = {
        name: 'wang',
        age: 18,
        play: 'pingpang',
        test: () => {
            console.log(this); // window 对象
            this.testA = '语文'
            console.log(this.name + ' 喜欢的课程是' + this.testA); //   喜欢的课程是语文
        }
    }
    
    obj.test()
    

    打印如下:
    test
    因此:调用对象的箭头函数方法,this的指向是window,不能再如第二步改变 play 的值一样改变 name,所以上面打印不是 “wang喜欢的课程是语文” 而是 “喜欢的课程是语文”

    4、如果我们进一步改造obj的方法,测试下在setTimeout里的this指向呢?

    const obj = {
        name: 'wang',
        age: 18,
        play: 'pingpang',
        testSetTimeout: function() {
        	
             setTimeout(function() {
                console.log('setTimeout(function(){})=======', this)  // window
                console.log(this.play)
            },5)
            
            setTimeout(() => {
                console.log('setTimeout(()=>{})=======', this)  // obj
                console.log(this.play)
            },10)
        }
    }
    
    obj.testSetTimeout()
    

    打印如下:
    testSetTimeout
    这里的结果似乎有些出乎意料~
    调用对象的方法:
    setTimeout里回调是普通函数时,this的指向是window
    setTimeout里回调是箭头函数时,this的指向是对象本身

    函数

    创建一个普通函数

    function testFunc(){
        console.log(this);
        this.num1 = 20;
        console.log('this.num1: ', this.num1); // 20
    }
    // 调用1
    testFunc()  // window
    
    // 调用2
    let test2 = testFunc()
    test2()  // window
    

    打印如下:
    func
    因此,在普通函数中,this指向window

    1、创建一个类

    class fatherObj {
        constructor(name, age){
            this.name = name
            this.age = age
        }
        showText(){
            console.log(this) // fatherObj
            return '姓名是:' + this.name + ',年龄是:' + this.age
        }
    }
    const fatherObj_C = new fatherObj('wang', 18)
    
    console.log(fatherObj_C.showText()) // 姓名是:wang,年龄是:18
    

    打印如下:
    fatherclass
    因此,在类里使用this,this指向类本身

    2、进一步改变类的方法 showText,我们来改变name的值来查看变化

    class fatherObj {
        constructor(name, age){
            this.name = name
            this.age = age
        }
        showText(){
            this.name = '小王'
            console.log(this) // 新fatherObj
            return '姓名是:' + this.name + ',年龄是:' + this.age
        }
    }
    const fatherObj_C = new fatherObj('wang', 18)
    
    console.log(fatherObj_C.showText()) // 姓名是:小王,年龄是:18
    

    打印如下:
    在这里插入图片描述
    由此可见,this指向的是更新之后的类

    3、保留第2步的fatherObj类,我们进一步测试,创建它的子类

    class sonObj extends fatherObj {
        constructor(name, age, sex){
            super(name, age)
            this.sex = sex
        }
        showMore(){
            console.log(this)
            return super.showText()+' ,性别是:' + this.sex
        }
    }
    const son_C = new sonObj("xiaowang", 5, 'nv')
    
    console.log('son_C: ', son_C.showMore());
    

    打印如下:
    son
    因此,在类里,this始终指向的是类本身。也很清晰看到,子类sonObj的原型上是父类fatherObj

    改变this的指向

    前置代码,先码个对象和函数吧~

    const testFunc = function(params1, params2) {
        console.log(this)
        console.log('params1: ', params1);
        console.log('params2: ', params2);
        return {name: 'wang'}
    
    }
    const testObj = {
        p1: 11,
        p2: 22,
        showThis(params){
            console.log('showThis=====', this, params)
        }
    }
    

    如果我们调用testFunc()testObj.showThis() ,this的指向应分别是 windowtestObj吧。
    下面,我们来看看改变this的指向~

    call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象

    call

    1、改变testFunc的this指向:

    
    testFunc.call(testObj, 3,4) 
    // {p1: 11, p2: 22, showThis: ƒ}
    // params1:  3
    // params2:  4
    
    testFunc.call(testObj, 'test2')
    // {p1: 11, p2: 22, showThis: ƒ}
    // params1:  test2
    // params2:  undefined
    
    testFunc.call(testObj)
    // {p1: 11, p2: 22, showThis: ƒ}
    // params1:  undefined
    // params2:  undefined
    
    testFunc.call() 
    // window
    // params1:  undefined
    // params2:  undefined
    
    testFunc.call(null)
    // window
    // params1:  undefined
    // params2:  undefined
    
    testFunc.call(undefined) 
    // window
    // params1:  undefined
    // params2:  undefined
    
    testFunc.call(2) 
    // Number{2}
    // params1:  undefined
    // params2:  undefined
    

    2、改变testObj的指向

    testObj.showThis.call(testFunc())
    // Window {}
    // params1:  undefined
    // params2:  undefined
    // showThis===== {name: 'wang'} undefined
    
    
    testObj.showThis.call(testFunc(), 18)
    // showThis===== {name: 'wang'} 18
    

    apply

    apply 和 call 的区别在于,apply的参数要放在数组里传过去,call的参数直接放进去

    testFunc.apply(testObj, [1,2]) 
    // {p1: 11, p2: 22, showThis: ƒ}
    // params1:  1
    // params2:  2
    
    testFunc.apply([1,2])
    // [1, 2]
    // params1:  undefined
    // params2:  undefined
    
    testFunc.apply(undefined)
    // Window {}
    // params1:  undefined
    // params2:  undefined
    

    bind

    bind 除了返回是函数需要自调用外,它的参数和 call 一样。

    testFunc.bind(testObj, 3, 4)()
    // {p1: 11, p2: 22, showThis: ƒ}
    // params1:  3
    // params2:  4
    

    参考文章:
    1、this的指向
    2、call、apply、bind的用法

    展开全文
  • js中的this指向问题经常容易让人混淆,特别是在ES6引入箭头函数后,对于标准函数中的this指向和箭头函数中的this指向就更让人费解。 本文总结了js中标准函数和箭头函数的this指向问题,帮助大家理清js中的this指向...

    js的this指向

    js中的this指向问题经常容易让人混淆,特别是在ES6引入箭头函数后,对于标准函数中的this指向和箭头函数中的this指向就更让人费解。

    • 本文总结了js中标准函数和箭头函数的this指向问题,帮助大家理清js中的this指向。
    • 并且介绍几个改变this指向的方法,改变this指向不管是在js的继承还是js的函数中都是很重要的。

    一 抓住核心

    我在网上看过一些关于this指向的博客,很多都是通过例子就直接开始讲解,虽然这样也可以帮助读者快速了解,但是在这里,我希望由一般到特殊,先指出标准函数和箭头函数中this指向的不同,再通过例子讲解来验证。

    刚开始可能看不太懂,但是经过例子的讲解,就会逐渐理解。

    • 对于标准函数中的thisthis引用的是把函数当成方法调用的上下文对象。标准函数中的this指向是当我们调用函数的时候确定的,调用方式的不同决定了this的指向不同,一般指向我们的调用者。直白点就是:哪个对象调用函数,函数里面的this指向哪个对象。
    • 对于箭头函数中的thisthis引用的是定义箭头函数的上下文。箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了之后不会改变

    二 标准函数中的this

    核心是:哪个对象调用函数,函数里面的this指向哪个对象。

    只不过window作为浏览器中的全局对象,在调用函数时经常是省略的,有时候很多this指向的例子看起来奇怪的原因,就是因为window对象的省略

    下面的表格列出了在标准函数中不同调用方式的this指向,从中也可以间接知道一般在调用什么函数时用到window对象。

    调用方式this指向
    普通函数调用window
    构造函数调用实例对象,原型对象里面的方法也指向实例对象
    对象方法调用该方法所属对象
    事件绑定方法绑定事件对象
    定时器函数window
    立即执行函数window

    函数的不同调用方式决定了this 的指向不同,下面是一些例子:

    ① 普通函数 this 指向window

    <script>
    	username = 'rs';
    	function fn() {
    	    console.log('普通函数的this' + this);
    	    console.log(this.username);
    	}
    	fn();  //相当于window.fn()
    </script>
    //输出结果:
    //普通函数的this[object Window]
    //rs
    

    ② 对象的方法 this指向的是对象 o

    <script>    
            color = 'red';
            var o = {
                color: 'blue',
                sayHi: function() {
                    console.log('对象方法的this:' + this);
                    console.log('color:' + this.color);
                }
            }
            o.sayHi();
    </script>
    //输出结果:
    //对象方法的this:[object Object]
    //color:blue
    

    ③ 构造函数 this 指向 subClass 这个实例对象

    <script>
    	let TestClass=function(){
    	    this.name='111';
    	}
    	let subClass=new TestClass();
    	subClass.name='cn';
    	console.log(subClass.name);//cn
    	let subClass1=new TestClass();
    	console.log(subClass1.name)//111
    </script>
    

    ④ 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象

    <body>
    	<button>点击</button>
    	<script>
            var btn = document.querySelector('button');
            btn.onclick = function() {
                console.log('绑定时间函数的this:' + this);
            };
    	</script>
    </body>
    //点击button,输出结果
    //绑定时间函数的this:[object HTMLButtonElement]
    

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

    <script>
            window.setTimeout(function() {
                console.log('定时器的this:' + this);
    
            }, 1000);
    //定时器前面经常省略window,这点要注意
    //虽然省略了window,但是其调用对象仍然是window,this指向window
    </script>
    //输出结果
    //定时器的this:[object Window]
    

    ⑥ 立即执行函数 this还是指向window

    <script>
            (function() {
                console.log('立即执行函数的this' + this);
            })();
    </script>
    //输出结果
    //立即执行函数的this:[object Window]
    

    三 箭头函数中的this

    核心是:箭头函数不会创建自己的this, 所以它没有自己的this,箭头函数里面的 this 是继承外面的环境 。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。

    有人可能对环境和作用域这样的概念不太熟悉,这里可以这样简单理解,{}内和函数内的就是个局部作用域或者局部环境,最外层就是全局作用域或者全局环境。

    例子①

    var id = 'GLOBAL';
    var obj = {
      id: 'OBJ',
      a: function(){
        console.log(this.id);
      },
      b: () => {
        console.log(this.id);
      }
    };
    obj.a();    // 'OBJ',标准函数,this指向调用者obj
    obj.b();    // 'GLOBAL',箭头函数,继承外面作用域,也就是全局环境的this值 —— window
    

    例子②

    window.color = 'red';
    let o = {
        color: 'blue'
    };
    let sayColor = () => console.log(this.color);
    sayColor(); // 'red'
    
    o.sayColor = sayColor;
    o.sayColor(); // 'red'
    //对象o的方法sayColor是使用箭头函数定义的
    //这个函数中的this就永远指向它定义时所处的全局执行环境中的this
    //即便这个函数是作为对象o的方法调用,this依旧指向Window对象。
    

    例子③

    let obj={
        a:'rs',
        fn:function(){    
            setTimeout(function(){console.log(this.a)},1000);
            //相当于window.setTimeout(function(){console.log(this.a)},1000);
        }
    };
    obj.fn();//undefined
    

    不难发现,虽然 fn() 里面的 this 是指向 obj ,但是,传给 setTimeout 的是标准函数, this 指向是 windowwindow 下面没有 a ,所以这里输出 undefined

    换成箭头函数

    let obj={
        a:'rs',
        fn:function(){    
            setTimeout(()=>{console.log(this.a)},1000);
        }
    };
    obj.fn();//'rs'
    

    这次输出 rs 是因为,传给 setTimeout 的是箭头函数,然后箭头函数里面没有 this ,所以要向上层作用域查找,在这个例子上, setTimeout 的上层作用域是 fn。而 fn 里面的 this 指向 obj ,所以 setTimeout 里面的箭头函数的 this ,指向 obj ,所以输出rs。

    四 改变函数内部this指向

    • JavaScript 为我们专门提供了一些函数方法来帮我们处理函数内部 this 的指向问题,常用的有 bind(),call(),apply()三种方法

    4.1call() 方法

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

    • fun.call(thisArg,arg1,arg2,.....)

    • thisArg: 在 fun 函数运行时指定的 this 值

    • arg1,arg2: 传递的其他参数

    • 返回值就是函数的返回值,因为它就是调用函数

    • 因此当我们想改变 this 指向,同时想调用这个函数的时候,可以使用 call,比如继承

    <body>
        <script>
            // 1. call()
            var o = {
                name: 'andy'
            }
    
            function fn(a, b) {
                console.log(this);
                console.log(a + b);
    
            };
            fn.call(o, 1, 2);
            // call 第一个可以调用函数 第二个可以改变函数内的 this 指向
            // 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('刘德华', 18, '男');
            console.log(son);
        </script>
    </body>
    

    4.2apply()方法

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

    • fun.apply(thisArg,[argsArray])

    • thisArg: 在 fun 函数运行时指定的 this 值

    • argsArray : 传递的值,必须包含在数组里面

    • 返回值就是函数的返回值,因为它就是调用函数

    • 因此 apply 主要跟数组有关系,比如使用 Math.max() 求数组的最大值

    <body>
        <script>
            // 2. apply()  应用 运用的意思
            var o = {
                name: 'andy'
            };
    
            function fn(arr) {
                console.log(this);
                console.log(arr); // 'pink'
    
            };
            fn.apply(o, ['pink']);
            // 1. 也是调用函数 第二个可以改变函数内部的this指向
            // 2. 但是他的参数必须是数组(伪数组)
            // 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值 
            // Math.max();
            var arr = [1, 66, 3, 99, 4];
            var arr1 = ['red', 'pink'];
            // var max = Math.max.apply(null, arr);
            var max = Math.max.apply(Math, arr);
            var min = Math.min.apply(Math, arr);
            console.log(max, min);
        </script>
    </body>
    

    4.3bind()方法

    • bind()方法不会调用函数。但是能改变函数内部 this指向
    • fun.bind(thisArg,arg1,arg2,....)
    • 返回由指定的 this值和初始化参数改造的 原函数拷贝
    • 因此当我们只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind
    <body>
        <button>点击</button>
        
        <script>
            // 3. bind()  绑定 捆绑的意思
            var o = {
                name: 'andy'
            };
    
            function fn(a, b) {
                console.log(this);
                console.log(a + b);
    
    
            };
            //fn.bind(o,1,2); 不会像call和apply那样立即调用
            var f = fn.bind(o, 1, 2);
            f();
            // 1. 不会调用原来的函数   可以改变原来函数内部的this 指向
            // 2. 返回的是原函数改变this之后产生的新函数
    
    
            // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
            // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
             var btn1 = document.querySelector('button');
             btn1.onclick = function() {
                 this.disabled = true; // 这个this 指向的是 btn 这个按钮
                 // var that = this;
                 setTimeout(function() {
                     // that.disabled = false; // 定时器函数里面的this 指向的是window,所以要用that代替
                     this.disabled = false; // bind()之后,定时器函数里面的this 指向的就是btn
                 }.bind(this), 3000); // 这个this在function()外面 指向的是btn这个对象
             }
        </script>
    </body>
    

    4.4三个方法的区别

    • callapply会调用函数,并且改变函数内部的this指向
    • callapply传递的参数不一样,call 传递参数,apply 必须数组形式
    • bind不会调用函数,可以改变函数内部this指向

    4.5注意

    call()、apply()、bind()等方法不能改变箭头函数中this的指向。

    var id = 'Global';
    let fun1 = () => {
        console.log(this.id)
    };
    fun1();                     // 'Global'
    fun1.call({id: 'Obj'});     // 'Global'
    fun1.apply({id: 'Obj'});    // 'Global'
    fun1.bind({id: 'Obj'})();   // 'Global'
    
    展开全文
  • this指向详解 this的指向在函数定义的时候是确定不了的,只有函数执行的时候才确定this到底指向谁 一般情况下this指向调用它的对象 下面我们来看看this被调用时的五种情况 思维导图 分析 1.作为对象方法...

     this指向详解

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才确定this到底指向谁

    一般情况下this指向调用它的对象

    下面我们来看看this被调用时的五种情况

    思维导图

    分析

    1.作为对象方法被调用

    当函数作为对象方法被调用时this指向该对象

         var obj = {
                age: 18,
                fn: function () {
                    console.log(this === obj);//true
                    console.log(this.age);//18
                }
    
            }
            console.log(obj.fn());

    2. 作为普通函数被调用时

     this指向全局对象window

    严格模式下 this被规定不会指向全局 则是undefined

        window.age = 18;
            function fn() {
                console.log(this.age);//18
            }
            fn()

    3.作为构造函数被调用时

    构造函数里面的this有点特殊 首先我们来了解一下构造函数跟普通函数的区别

    //构造函数主要用来初始化对象 为对象的成员变量赋值初始值 他总于new一起使用

    new在构造函数中做了哪些事

    //1.在内存中创建一个新的对象

    //2.让this指向这个新对象

    //3.在构造函数里面的代码,给这个新对象添加属性和方法

    //4.返回这个新对象 所以构造函数里面一般不需要return

    了解之后我们再来看构造函数里面的this

    构造函数里的this指向 new创建的实例化对象(没有return的情况下)

    如果构造函数内出现了return并且是一个object对象那么最终的运算结果返回这个对象

    只要构造函数不返回数据或者返回基本数据类型 this仍然指向实例

       function Fn() {
                this.age = 18;
                //此时a.age是return的结果20
                return {
                    age: 20
                }
            }
            let a = new Fn();
            console.log(a.age);//20

    4.箭头函数里面的this

    箭头函数里面没有自己的this 他只会从自己的作用域链上一层继承this

          this.age = 20;
            var obj = {
                age: 18,
                fn: () => {
                    console.log(this.age);//20
                }
    
            }
            obj.fn()

     

    5.call&& apply&&bind

    在function的原型上有三个方法 call apply bind,所有函数都是Function的实例,所以所有的函数都可以调用这三个方法,而这三个方法都是用来改变this指向的

    call或apply调用

    • 都是把函数立即执行改变函数中的this指向(第一个参数是谁this就是谁)
    • apply同理 唯一的区别就是传参的格式不一样,apply把传递给函数的形参以数组的形式管理起来,最终的效果和call一样,也是把数组中的每一项作为实参,一个个的传递给函数
    • 真实项目中建议大家使用call,因为其性能好一些(三个及以上参数,call的性能明显比apply好一些)
    • this存储的值 null.undefined.对象
    • 一个也不写,非严格模式下是window 严格模式下是undefined
    • null 严格模式下是null非严格模式下是window
        function fn(x, y) {
            console.log('加油');
            console.log(this);//this指向window
            console.log(x + y);
        }
        var o = {
            name: 'andy'
        }
        fn.call()//call 呼叫 可以调用函数
        fn.call(o, 1, 2)//第一个值是this指向, 后边实参
        fn.apply(o, [10, 20])//apply传递数组
        fn.call(10, 20)//this-->new Numbe(10) x-->20 y-->undefined 
    

    apply的应用小技巧 :获取数组中的最大值

        let arr = [10, 20, 58, 79, 66]
        console.log(Math.max(arr));//NaN,要求传递数字,不是直接传递数组
        console.log(Math.max(...arr));//es6中的展开运算符
        console.log(Math.max.apply(Math, arr));

     重新call方法

    •     fn基于__proto__找到Function.prototype.call 把call方法执行
    •     在call方法执行的时候
    •     content: obj要改变的this指向, params;[10, 20]执行函数传递的实参 this: fn要执行的函数
    •     它干的事情是立即把fn(this)函数执行,并且让fn(this)中的this指向obj, 把10,20(params)传递给fn(this),接收fn执行的返回结果,作为最后结果返回

     思路:给content设置一个属性(例如:xxx,新增的属性不要和原始content中的属性冲突(symbbol唯一值属性)) 让属性值等于要执行的函数(即:this[fn]),后面基于content.xxx()执行,这样即把函数执行了 ,也让函数的的this改成了content

       Function.prototype.call = function call(content, ...params) {
            // this-->fn content-->obj params-->[10,20]
            // 思路:给content设置一个属性(例如:xxx,新增的属性不要和原始content中的属性冲突(symbbol唯一值属性)) 让属性值等于要执行的函数(即:this[fn]),后面基于content.xxx()执行,这样即把函数执行了 ,也让函数的的this改成了content
            if (content == null) content = window//this指向为null时指向window
            // 如果是原始值,字符串设置属性值之后获取不到要变成object
            if (! /^objet|funcion$/.test(typeof content)) content = Object(content)//
            let self = this,
                key = Symbol('KEY'),
                result;
            content[key] = self;
            result = content[key](...params)
            // delete content[key]//新增的属性用完后记得移除
            Reflect.deleteProperty(content, key)//es6中可以基于Reflect.deleteProperty移除对象的某个属性
            return result
        }
    
        const fn = function fn(x, y) {
            console.log(this, x, y);
            return x + y
        }
        let obj = {
            name: 'obj'
        }
        let res = fn.call(obj, 10, 20)
    
        console.log(res);
        // fn基于__proto__找到Function.prototype.call 把call方法执行
        // 在call方法执行的时候
        // content: obj要改变的this指向, params;[10, 20]执行函数传递的实参 this: fn要执行的函数
        //它干的事情是立即把fn函数执行,并且让fn中的this指向obj, 把10,20传递给fn,接收fn执行的返回结果,作为最后结果返回
    
    

    bind

    call VS bind

    call是立即把函数执行,而bind只是预处理函数中的this和参数,不会立即执行

    // 点击按钮 ,fn方法执行,我们想让其中的this变成obj ev事件对象也存在 在传递10/20

         <button id="sumit">点击</button>
    const sumit = document.querySelector("#sumit")
        const fn = function fn(x, y, ev) {
            console.log(this, ev);
        }
        let obj = {
            name: 'obj'
        }
        sumit.onclick = fn;//点击按钮时this-->sumit x-->PointerEvent事件对象
        // 点击按钮 ,fn方法执行,我们想让其中的this变成obj ev事件对象也存在 在传递10/20
        // sumit.onclick = fn.call(obj, 10, 20)//这样处理是错误的,因为call把函数立即执行了
        sumit.onclick = function (ev) {
            //先把事件行为绑定匿名函数,先执行匿名函数(获取ev对象)在匿名函数执行的时候this-->sumit,我们在让真正处理的fn函数执行,此时可以基于call方法改变this'了
            fn.call(obj, 10, 20, ev)
    
        }
        sumit.onclick = fn.bind(obj, 10, 20)//这样就可以了

    重写bind 

     <button id="sumit">点击</button>
     Function.prototype.bind = function bind(context, ...params) {
            let self = this;
            // this-->fn contexxt-->obj params-->[10,20]
            return function proxy(...args) {
                // args-->ev this-->sumit
                return self.call(context, ...params.concat(args))
            }
        }
        const sumit = document.querySelector("#sumit")
        const fn = function fn(x, y, ev) {
            console.log(this, ev);
        }
        let obj = {
            name: 'obj'
        }
       sumit.onclick = fn.bind(obj, 10, 20)

    总结

    函数中的this指向

    1. 普通函数下this是window  严格模式下是undefined
    2. 对象或方法this指向调用者
    3. 构造函数里面的this指向实例对象(原型对象里面的this也指向实例对象 在本篇中没有展开)
    4. 箭头函数没有自己的this
    5. call和apply可以改变this指向

    再来补充几条

    1. 绑定点击事件里面的this指向的是调用者
    2. 定时器里面的this指向window
    3. 立即执行函数里面的this指向window

    由此我们可以得出)函数执行的时候,看它前面有没有点,如果有,点前面是谁,this就是谁,如果没有,就是window

    ----------------------------------------------完结散花-----------------------------------------------------------------------

    ----------------接受大佬们的批改和指点 ,欢迎留言------------------------------------------------------------------

    展开全文
  • js代码-封装函数 f,使 f 的 this 指向指定的对象
  • 1、谁最终调用函数,this指向谁。  ① this指向的,永远只可能是对象!!!!!!  ② this指向谁,永远不取决于this写在哪!!而是取决于函数在哪调用。  ③ this指向的对象,我们称之为函数的上下文context...
  • thisthis 指向看看箭头函数的案例call、apply和bind方法的用法以及区别来几个面试题试试 this 指向 1.普通函数的this指向它的调用者,如果没有调用者则默认指向window. 2.箭头函数的this: 指向箭头函数定义时所处...
  • js this指向

    2021-01-08 17:44:05
    JavaScript this指向总结 在JavaScript中this永远指向当前函数的主人,即函数的调用对象或事件的调用对象,大致分为以下几种情况。 单独的this或者全局函数中的this指向window对象 console.log(this);//this => ...
  • JavaScript有关this指向问题
  • js中this指向的四种规则+ 箭头函数this指向 四种规则分别是:默认、隐式、显式(call、apply、bind)、new 对象
  • 函数内的this指向 下表中列出的这些this的指向,是当我们调用函数的时候确定的。调用方式的不同决定了this的指向不同,一般情况下会指向函数的调用者(谁调用指向谁)。 调用方式 this指向 普通函数调用 ...
  • 在学习javascript中我们往往会被this的指向问题弄的头昏转向,今天我们就来学习一下this的指向问题,和改变this指向的方法。 一.this的指向问题 在学习this的指向问题之前我们需要明白两点: 1:this永远指向一个...
  • JAVAscript中的this指向this指向的修改

    千次阅读 热门讨论 2021-04-08 19:09:09
    JAVAscript中的this指向this指向的修改 this 关键字 一般在函数中使用,表示哪个对象执行了当前函数。 每一个函数内部都有一个关键字是 this 。 函数内部的 this 只和函数的调用方式有关系,和函数的定义方式没有...
  • 如在全局作用域调用一个含this的对象,此时当前对象的this指向的是window。为了让this的指向符合自己的意愿,JavaScript提供了两个方法用以改变this的指向,它们是call和apply,当然也有利用闭包来实现的方法。本文...
  • 记得初学 JavaScript 时,其中 this指向问题曾让我头疼不已,我还曾私自将其与闭包、原型(原型链)并称 JS 武林中的三大魔头。如果你要想在 JS 武林中称霸一方,必须将这三大魔头击倒。个人认为在这三大魔头中,...
  • 刚开始学习 JavaScript 的时候,this 总是最能让人迷惑,下面我们一起看一下在 JavaScript 中应该如何确定 this指向this 是在函数被调用时确定的,它的指向完全取决于函数调用的地方,而不是它被声明的地方...
  • 2:一般情况下this指向它的调用者 3:es6的箭头函数中,this指向创建者,并非调用者 4:通过call、apply、bind可以改改变this的指向 下面我们具体分析一下 1:在函数调用时  (非严格模式) const func = function () {...
  • 这篇文章主要介绍了JavaScript This指向问题详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 各位小伙伴在面试中被面试官问道this指向问题一定不少吧,同时...
  • 2,箭头函数的this指向 父级程序的this指向 如果父级程序有this指向(父级程序也是函数),this指向的就是父级程序的this指向 如果父级程序没有this指向(数组,对象....),this指向的是window 复习this指向 **************...
  • this指向.html

    2021-03-09 09:37:00
    看的很多视频总结的this指向问题 有代码展示、 四种绑定对应的四种调用

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 820,017
精华内容 328,006
关键字:

this指向

友情链接: LIONSIMBA-master.zip