This in JavaScript

栏目: JavaScript · 发布时间: 5年前

内容简介:这篇文章我们来理解下js中的在开始之前,我们先定义几个规则

这篇文章我们来理解下js中的 this 关键字

在开始之前,我们先定义几个规则

  1. 函数作为方法调用, 也就是用 . 的方式
  2. new 的方式
  3. applycallbind 的方式
  4. 函数作为自由函数调用

第一种规则,函数作为方法调用

this 指向的就是调用方法的对象

let obj = {
    name: 'len',
    sayName: function() {
        console.log(this)
    }
}

obj.sayName() // { name: 'len', sayName: [Function: sayName] }
复制代码

第二种规则

this 指向的就是新创建的对象,我们都知道,使用 new 关键字的时候,会创建一个新的对象

let obj = {
    name: 'len',
    sayName: function() {
        console.log(this)
    }
}

new obj.sayName() // sayName {}
复制代码

第三种规则

这时候, this 指向的就是调用bind,apply,call方法的第一个参数(下面例子中的 obj )

function fn() {
    console.log(this)
}

let obj = {
    value: 5
}

let boundFn = fn.bind(obj)

boundFn() // { value: 5 }
fn.call(obj) // { value: 5 }
fn.apply(obj) // { value: 5 }
复制代码

第四种规则

在浏览器中, 这时候 this 指向的就是就是window对象

function foo() {
    console.log(this)
}

foo() // Window{}
复制代码

规则中的组合情况

const obj = {
    value: 'hi',
    printThis: function() {
        console.log(this)
    }
}
const print = obj.printThis

// 规则1,this指向的就是obj
obj.printThis()  // {value: 'hi', printThis: f} 
// 规则4,this指向的就是Window
print() // Window {}
复制代码
const obj1 = {
    value: 'hi',
    printThis: function() {
        console.log(this)
    }
}

const obj2 = {value: 17}

// 规则1和3的组合, 规则3的优先级大于规则1
obj1.print.call(obj2) // {value: 17}

// 规则1和规则2的组合,规则2的优先级大于规则1
new obj1.print() // {}
复制代码

闭包中的this

var name = 'window'
let object = {
    name: 'len',
    sayName: function() {
        return function() {
            return this.name
        }
    }
}

console.log(object.sayName()()) // window
复制代码

上面为什么打印window呢?我们拆开来看

let firsr = object.sayName()
first() // 这是作为单独函数调用的,也是就是上面的'规则4',所以this自然就指向window了
复制代码

es6箭头函数的this

箭头函数没有自己的this,请看:

// es6
function foo() {
    setTimeout(() => {
        console.log(this)
    })
}

// es5
function foo() {
    var _this = this
    setTimeout(function() {
        console.log(_this)
    }, 1000)
}

foo() // Window{}
new foo() // foo{}
这样就又回到了上面的规则了。
复制代码

上面es5代码是我用在线babel编译es6代码得到的。从上面我们可以看出,箭头函数是没有自己的this的,它实际上是保存了父级作用域的this,然后在箭头函数里面调用的都是父级作用域的this。也正是因为箭头函数没有this,所以自然而然我们就不能使用call,apply,bind来改变this的指向了。

最后,来个面试题

class Animal() {
    constructor(type) {
        this.type = type
    }
    
    say(val) {
        setTimeout(() => {
          console.log(this);
          console.log(this.type + " says " + val);
        }, 1000)
    }
}

// es6的class里面的方法都是定义在prototype上的
console.log(Animal.prototype) // 在浏览器中 {constructor: f, say: f}

const animal = new Animal('animal')
animal.say('hi') // 1s later console log "Animal{type: 'animal'}" and "animal says hi"
复制代码

我们将上面的改动一下

class Animal() {
    constructor(type) {
        this.type = type
    }
    
    say(val) {
        // 这里没有使用箭头函数,这里的setTimeout形成了一个闭包,this指向的是window
        setTimeout(function() {
          console.log(this);
          console.log(this.type + " says " + val);
        }, 1000)
    }
}

const animal = new Animal('animal')
animal.say('hi') // Window {} / undefined says hi
复制代码

总结: js中的this还是挺好理解。只要自己用心去理解,相信你可以做到的。好了,就到这了,如果觉得文章有什么问题,可以在下面留言探讨下。毕竟都是在学习,没有不出错的。谢谢理解!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据挖掘技术

数据挖掘技术

[美]MichaelJ.A.B / 别荣芳、尹静、邓六爱 / 机械工业 / 2006-7 / 49.00元

本书是数据挖掘领域的经典著作,数年来畅销不衰。全书从技术和应用两个方面,全面、系统地介绍了数据挖掘的商业环境、数据挖掘技术及其在商业环境中的应用。自从1997年本书第1版出版以来,数据挖掘界发生了巨大的变化,其中的大部分核心算法仍然保持不变,但是算法嵌入的软件、应用算法的数据库以及用于解决的商业问题都有所演进。第2版展示如何利用基本的数据挖掘方法和技术,解决常见的商业问题。 本书涵盖核心的数......一起来看看 《数据挖掘技术》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具