博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[译]浅显易懂的 this 取值规则
阅读量:7064 次
发布时间:2019-06-28

本文共 2258 字,大约阅读时间需要 7 分钟。

翻译自文章。

确定什么是 this 并非难事。总的来说,通过查找函数被调用时的位置(和方法)就可以决定。遵循以下规则,按优先级排列。

规则

  1. 通过 new 关键字调用构造函数,函数内的 this 是一个全新的对象。

    function ConstructorExample() {    console.log(this);    this.value = 10;    console.log(this);}new ConstructorExample();// -> {}// -> { value: 10 }
  2. 通过 applycallbind 调用一个函数,函数内的 this 就是传入的参数。

    function fn() {    console.log(this);}var obj = {    value: 5};var boundFn = fn.bind(obj);boundFn();     // -> { value: 5 }fn.call(obj);  // -> { value: 5 }fn.apply(obj); // -> { value: 5 }
  3. 如果一个函数作为对象的方法调用,即使用 . 符号调用该函数, this 是调用该函数的对象。换句话说,当 . 处于被调用函数的左边,则 this 就是左边的对象。

    var obj = {    value: 5,    printThis: function() {        console.log(this);    }};obj.printThis(); // -> { value: 5, printThis: ƒ }
  4. 如果函数作为普通函数调用,意味着调用方式不符合以上任意一种, this 就是全局对象。在浏览器中就是 window

    function fn() {    console.log(this);}// If called in browser:fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

    *这个规则可以类比于规则3——不同之处在于这个函数自动挂载到了 window 对象上,所以可以这么理解,当我们调用 fn() 时其实调用的事 window.fn() ,所以 this 就是 window

    console.log(fn === window.fn); // -> true
  5. 如果符合上述多个规则,则越前面的规则会决定 this 的值。
  6. 如果函数是一个 ES2015 箭头函数,会忽略上述所有规则, this 设置为它被创建时的上下文。为了找到 this 的值,需要找到函数被创建时的环境中 this 的值。

    const obj = {    value: 'abc',    createArrowFn: function() {        return () => console.log(this);    }};const arrowFn = obj.createArrowFn();arrowFn(); // -> { value: 'abc', createArrowFn: ƒ }

    我们返回去看规则3,当我们调用 obj.createArrowFn() 时, createArrowFn 中的 this 就是 obj 对象,我们用 . 符号调用。如果我们在全局中创建一个箭头函数, this 就是 window

应用规则

下面在几个例子中应用一下我们的规则。试一下通过两种不同的方式调用函数时 this 的值。

找到应用的规则

var obj = {    value: 'hi',    printThis: function() {        console.log(this);    }};var print = obj.printThis;obj.printThis(); // -> {value: "hi", printThis: ƒ}print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

obj.printThis() 很显然应用的是规则3——使用 . 符号。 print() 应用了规则4,在调用 print() 时,我们没有使用 newbind/call/apply. 符号,所以这里的 this 是全局对象 window

多重规则应用

如上文提到,当应用多个规则时,优先应用前面的规则。

var obj1 = {    value: 'hi',    print: function() {        console.log(this);    },};var obj2 = { value: 17 };

如果规则2和3同时应用,规则2优先。

obj1.print.call(obj2); // -> { value: 17 }

如果规则1和3同时应用,规则1优先。

new obj1.print(); // -> {}

关于工具库

一些 JavaScript 库有时候会在函数中主动绑定它认为最有用的内容到 this 上。比如在 JQuery中,在触发事件时 DOM 元素被绑定到了 this 上。在使用工具库时发现取值不符合上述规则时,请查看库文档。很可能使用了 bind 语法。

该文章首发于我的

转载地址:http://ebill.baihongyu.com/

你可能感兴趣的文章
自行控制loadrunner的socket协议性能测试 (转)
查看>>
【ASP】简单Url编码和Url解码实例
查看>>
整理OpenResty+Mysql+Tomcat+JFinal+Cannal+HUI
查看>>
android搜索框列表布局,流程及主要步骤思维导图
查看>>
一场惊天跨国跨时区作弊案,除了需要爆表智商,还需要啥?
查看>>
工程师笔记|浅析AI平台的架构设计
查看>>
开店仅1年,为何能在一天实现 “三销冠”
查看>>
人工智能火了,为啥医疗成为最先受益者?
查看>>
雷军带领小米老员工公园步行 称这些人是小米最宝贵财富
查看>>
滴滴公布自查进展:免去黄洁莉顺风车事业部总经理职务
查看>>
中国PPP管理库项目累计投资额13.2万亿元
查看>>
甘肃崆峒古镇“文化赶集”:非遗“上台”贺新春
查看>>
俄罗斯食品来中国“过年”
查看>>
市场监管总局:保健食品应标注不具疾病预防治疗功能
查看>>
GitHub 上开源的区块链项目 90% 死亡了
查看>>
澳网张帅首夺大满贯 女双携斯托瑟挑落卫冕冠军
查看>>
“平潭-高雄”货运直航开通 三大优势凸显
查看>>
“共度欢乐春节”摄影图片展在阿斯塔纳开幕
查看>>
新光大ArtPark9亮相 以“艺术”再造生活方式
查看>>
关于Python数据分析,这里有一条高效的学习路径
查看>>