zoukankan      html  css  js  c++  java
  • JavaScript-改变this指向

    一、this指向的详解

    概括:this的指向到底是指向哪里?通常来说,只有当函数执行的时候才可以确定this指向的到底是谁,简单的也可以这么说:this最终指向的是那个调用它的对象。

    常见的一般有以下几种情况:

    第一种:在一个函数中有this,但是函数没有被上一级对象所调用,所以此时的this指向的是window(注意在严格模式下则不是),如以下代码:

    function blue() {
    var blue = "蓝源";
    console.log(this.blue);//undefind
    console.log(this);//window
    }
    blue();//this指向调用它的那个对象,在这里相当于window

    第二种:在函数中有一个this,而且该函数被上一级对象所调用,所以此时的this指向的是调用该函数的上一级对象,如以下代码:

    var o = {
    name: "blue",
    fn: function(){
    console.log(this.name);//blue
    console.log(this);//指向o对象
    }
    }
    o.fn();//此时this指向的是调用函数的对象o。

    第三种:有一个函数中有this,函数中有多个对象,尽管这个函数是被最外层的对象调用,但是其中的this指向的只是它的上一级对象,如以下代码:

    var o = {
    name: "blue",
    a: {
    fn: function(){
    console.log(this.name);//undefind,这里有两个对象o和a,调用的时候都指向上一层对象a,这里找不到声明的name
    }
    },
    fn1: function(){
    console.log(this.name);//blue
    }
    }
    o.fn1();
    o.a.fn();

    第四种(特殊情况):如果函数中有return,而且return返回的是一个对象,那么调用时候的this指向不再是指向调用这个函数的实例了,而是指向这个函数返回的对象,如以下代码:

    function fn() 
    {
    this.name = 'blue';
    return {};
    }
    var a = new fn;
    console.log(a.name); //undefined,这里指向的是return返回的对象,是一个空对象

    二、改变this指向的方法

    第一种:使用call()

    var a = {
    user:"blue",
    fn:function(){
    console.log(this.user); //blue
    }
    }
    var b = a.fn;
    b.call(a); //若不用call,则b()执行后this指的是Window对象

    call方法除了第一个参数以外还可以添加多个参数,如下:

    var a = {
    user:"blue",
    fn:function(c,d){
    console.log(this.user); //blue
    console.log(e+ee); //3
    }
    }
    var b = a.fn;
    b.call(a,1,2);

    第二种:使用apply()

    var a = {
    user:"blue",
    fn:function(){
    console.log(this.user); //blue
    }
    }
    var b = a.fn;
    b.apply(a);

    apply方法和call方法很类似,也可以接收多个参数,但是第二个参数必须是数组,如下:

    var a = {
    user:"blue",
    fn:function(e,ee){
    console.log(this.user); //blue
    console.log(c+d); //11
    }
    }
    var b = a.fn;
    b.apply(a,[10,1]);

    第三种:使用bind()

    bind和call,apply的使用方法有些不同,如果我们还是按照上面的方法写代码,会发现一些问题,如下:

    var a = {
    user:"blue",
    fn:function(){
    console.log(this.user);
    }
    }
    var b = a.fn;
    b.bind(a); //代码没有被打印

    为什么代码没有被打印呢?这就是不同的地方所在,实际上执行bind之后返回的是一个函数,想下面这样写才是正确的:

    var a = {
    user:"blue",
    fn:function(){
    console.log(this.user); //blue
    }
    }
    var b = a.fn;
    var c = b.bind(a);
    c();

    bind()方法也可以接收多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的,如下:

    var a = {
    user:"blue",
    fn:function(e,d,f){
    console.log(this.user); //blue
    console.log(e,d,f); //10 1 2
    }
    }
    var b = a.fn;
    var c = b.bind(a,10);
    c(1,2);

    总结:

    call(),apply()以及bind()方法都可以改变this指向,只是所使用的场景有点不一样,bind()改变后的函数想什么时候调用就什么时候调用,call和apply都是改变指向后立即调用此方法。

  • 相关阅读:
    谋哥:这个时代没有比程序员更适合创业
    《人人都可以创业》连载1:创业很简单,从心开始
    谋哥:悟马道长第一句话之“不要赚屌丝的钱”
    谋哥:App开发者的苦逼不值得怜悯!
    我们都傻不啦叽为《围住神经猫》免费推广!
    谋哥:转型之痒与App推广之痛
    学习IOS开发项目篇--如何让程序在后台保持挂起状态
    学习IOS开发项目篇--SDWebImage基本使用
    学习IOS开发网络多线程篇--NSThread/GCD/
    学习IOS开发UI篇--UICollectionViewController的基本使用
  • 原文地址:https://www.cnblogs.com/guchengnan/p/9618444.html
Copyright © 2011-2022 走看看