• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

JS的this指向问题史上

武飞扬头像
BlueSeaYo
帮助1

一句话概括this指向:谁调用this就指向谁

这句话可能太过广义,那么请看以下的各种this指向场景

1.箭头函数(=>)

        箭头函数this的指向不会发生改变,也就是说在创建箭头函数时就已经确定了它的this的指向了;它的指向永远指向箭头函数外层的 this。

  1.  
    function fn1() {
  2.  
    console.log(this);
  3.  
     
  4.  
    let fn2 = () => {
  5.  
    console.log(this);
  6.  
    }
  7.  
    fn2(); //this->window
  8.  
    }
  9.  
    fn1();//this->window
  10.  
     
  11.  
    //因为fn1函数中this的指向是window,所以fn2箭头函数this指向fn1函数也就是间接指向window
  12.  
     

2.直接调用

在函数被直接调用时,this 将指向全局对象。在浏览器环境中全局对象是 Window,在 Node.js 环境中是 Global。

全局作用域中:this永远指向window

函数作用域中:

  • 如果函数直接被调用  this指向window  函数名()       
  • 被对象的对象.属性()调用  函数中的this指向这个对象 
  1.  
     
  2.  
    var obj = {
  3.  
     
  4.  
    fn: function fn1() {
  5.  
    console.log(this);
  6.  
    },
  7.  
    }
  8.  
    obj.fn(); //this->obj

3.对象.属性()调用

        这里说的this指向就是上文中代码中的例子,有兴趣可以自行多尝试一下此场景中的this

4.new

        当使用 new 关键字调用函数时,函数中的 this 一定是 JS 创建的新对象。

可能你会有所疑问:“如果使用 new 关键调用箭头函数,是不是箭头函数的 this 就会被修改呢?”。

我们可以在控制台尝试一下:

  1.  
    fun = () => {}
  2.  
    new fun() // throw error

从控制台中可以看出,箭头函数不能当做构造函数,所以不能与 new 一起执行。

5.bind

        bind 是指 Function.prototype.bind()->原型里的方法

多次 bind 时只认第一次 bind 的值

例子:

  1.  
    function fn() {
  2.  
    console.log(this)
  3.  
    }
  4.  
     
  5.  
    fn.bind(1).bind(2)() // 1

注意:箭头函数中 this 不会被修改

  1.  
    fun = () => {
  2.  
    // 这里 this 指向取决于外层 this
  3.  
    console.log(this)
  4.  
    }
  5.  
     
  6.  
    fun.bind(1)() // Window

bind 与 new

        注意:new优先

  1.  
    function func() {
  2.  
    console.log(this, this.__proto__ === func.prototype)
  3.  
    }
  4.  
     
  5.  
    boundFunc = func.bind(1)
  6.  
    new boundFunc() // Object true

bind 函数中 this 不会被修改

  1.  
    function func() {
  2.  
    console.log(this)
  3.  
    }
  4.  
     
  5.  
    boundFunc = func.bind(1)
  6.  
    boundFunc.apply(2) // 1 bind优先

总结:将参数一个一个地进行传递,在被函数调用时不会立马执行函数,返回有一个新函数,新函数中的this指向改变,不影响原来的函数的this指向

6.apply 和 call

        作用:改变this指向

        区别:调用时传递参数形式不同

  • call:将参数一个一个地进行传递(改变函数中的this指向 指向第一个参数;并且执行函数)
  • apply:将参数用数组的形式传递(改变函数中的this指向 指向第一个参数;并且执行函数)

使用:

        

  1.  
    function Person(name,age){
  2.  
    this.name = name;
  3.  
    this.age = age;
  4.  
    }
  5.  
    var person = new Person("xiaoming",100);
  6.  
    var obj = {}
  7.  
    Person.apply(obj,['xiaoming',300]);//Person {name: 'xiaoming', age: 100};
  8.  
    Person.call(obj,'xiaozhang',300);//Person {name: 'xiaoming', age: 100};
  9.  
    console.log(person)

箭头函数中 this 不会被修改

  1.  
    func = () => {
  2.  
    // 这里 this 指向取决于外层 this
  3.  
    console.log(this)
  4.  
    }
  5.  
     
  6.  
    func.apply(1) // Window

7.不在函数里        

        不在函数中的场景,可分为浏览器的 <script /> 标签里,或 Node.js 的模块文件里。

  1. 在 <script /> 标签里,this 指向 Window。
  2. 在 Node.js 的模块文件里,this 指向 Module 的默认导出对象,也就是 module.exports

非严格模式

严格模式是在 ES5 提出的。在 ES5 规范之前,也就是非严格模式下,this 不能是 undefined 或 null。所以在非严格模式下,通过上文各种场景得知,如果得出 this 指向是 undefined 或 null,那么 this 会指向全局对象。在浏览器环境中全局对象是 Window,在 Node.js 环境中是 Global。

        非严格模式代码我就不运行了结果了,感兴趣的朋友可以自行复制打印在控制台看看运行结果~~~

  1.  
    function fn() {
  2.  
    console.log("function fn:", this)
  3.  
    ;(() => {
  4.  
    console.log("arrow function: ", this)
  5.  
    })()
  6.  
    }
  7.  
     
  8.  
    fn()
  9.  
     
  10.  
    fn.bind(null)()
  11.  
     
  12.  
    fn.bind(undefined)()
  13.  
     
  14.  
    fn.bind().bind(2)()
  15.  
     
  16.  
    fn.apply()
学新通

全文总结:谁调用this就指向谁!

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbckbi
系列文章
更多 icon
同类精品
更多 icon
继续加载