【问题标题】:exploring keyword "this" in javascript在javascript中探索关键字“this”
【发布时间】:2020-04-21 12:49:02
【问题描述】:

我在 javascript 中有以下代码块:

const obj = {
  name: "sri1",
  func1: function() {
    const name = "sri2"

    function a() {
      console.log(this.name)
    }
    a();

  }
}

obj.func1();

为什么我没有得到关于 this 关键字的任何 console.log 状态?我真的很困惑,它既不是 obj 也不是 undefined 也不是 window 对象

【问题讨论】:

  • 做类似a.bind(this)();
  • "忽略 HTML 部分" ...如果 HTML 不相关,请不要将其包含在您的示例中!这次我会为你编辑问题。另请参阅stackoverflow.com/help/minimal-reproducible-example
  • 我知道绑定存在,但为什么我没有得到任何输出,甚至没有错误!
  • 好的,很抱歉添加了 html 部分
  • 好的,我把它编辑成一个可运行的sn-p。我认为它似乎确实产生了输出,尽管不是您期望的值。您可能需要阅读函数中this 的范围,尤其是嵌套函数(或有时称为“闭包”)。你可以从这里开始:stackoverflow.com/questions/346015/javascript-closures-and-this

标签: javascript this


【解决方案1】:

当您的对象具有返回函数的方法时,this 会转义对象范围并引用窗口,除非您绑定它或使用箭头函数。

所以你的this.name 在正常环境中返回的只是一个空字符串。这就是为什么你看不到任何东西——就像@dellink 说的那样。 window.name"" 如果你不设置它。所以你实际看到的只是一个字符串,里面什么都没有。

它在您的示例中记录一些奇怪的属性的原因是因为 Stack Overflow 沙箱。在这里,this 关键字不是指一般的 window 对象,而是指一个不同的对象,确实实际上有一个 name 属性和一些值。

检查一下:

console.log(this.name)

【讨论】:

  • 当我将所有“名称”重命名为“名称”并运行代码时,我得到了未定义,这意味着 window.names 不存在
  • @sriramhegde 你是完全正确的。 window.names 不存在。
  • 那为什么window.name会存在呢?
  • 窗口名称主要用于设置超链接和表单的目标。你可以在这里developer.mozilla.org/en-US/docs/Web/API/Window/namew3schools.com/jsref/prop_win_name.asp阅读更多信息
  • 非常感谢您提供此信息。您消除了我的困惑
【解决方案2】:

棘手的是,当您定义一个函数a 时,它会在全局范围内定义。

var obj = {
  name: "sri1",
  func1: function() {
    const name = "sri2"
    console.log(this); // obj (!) *2
    function a() {
      console.log(this); // window (!) *3
    }
    a();

  }
}
obj.func1();
console.log (a()) // window (!) *1

查看点号 1:a 函数存在。它的上下文是window。这就是首先发生的事情 - 定义函数和变量。

当你调用“obj.func1();”时它确实在obj (*2) 的上下文中调用

当您调用a 函数上下文时再次切换到一个窗口。 (*3)

【讨论】:

    【解决方案3】:
    const obj = {
      name: "sri1",
      func1: function() {  // <-- 1
        const name = "sri2"
    
        function a() { // <-- 2
          console.log(this.name)
        }
        a();
    
      }
    }
    

    通常this 指向浏览器的window 对象。
    但是在对象内部,如果我们用匿名函数定义属性,那么this 指向对象本身。但是函数内部的另一个函数?不,它指向window 对象。

    因此,以您为例。我已经用 cmets 用两个参考点标记了你的代码。

    1. Mark 1 函数,它是对象属性的函数。所以this 指向obj 对象。
    2. 标记 2 函数,它在标记 1 函数内,所以现在,函数 a() 内的 this 指向 window 对象。 (如果您不相信我,请在 function a() 中使用 console.log(this) 进行检查

    如何在内部函数中获取对象的this

    有几种方法可以实现这一点。我只提到其中的几个。

    使用arrow function

    箭头函数不会改变this 指针的引用。它指向函数所在的块this

    const obj = {
      name: "sri1",
      func1: function() {
        const name = "sri2"
    
        const a = () => { // Using arrow function
          console.log(this.name)
        }
    
        a();
      }
    }
    

    将之前的this 保存到一个变量中。

    您可以将this 放入变量that,然后使用that.name 访问该值。

    const obj = {
      name: "sri1",
      func1: function() {
        const name = "sri2"
        const that = this; // Put this into that
    
        function a() {
          console.log(that.name); // Access the name using that.name
        }
    
        a();
      }
    }
    

    调用函数时绑定this

    您可以将this 与要在其中使用的函数绑定。

    const obj = {
      name: "sri1",
      func1: function() {
        const name = "sri2"
    
        function a() {
          console.log(this.name)
        }
    
        const withThis = a.bind(this); // Make a function reference with `this` bindings
        withThis(); // Call the function
      }
    }
    

    使用call()apply()

    call() 方法使用给定的 this 值和单独提供的参数调用函数。

    虽然此函数的语法几乎与 apply(),根本区别在于call() 接受一个参数 列表,而apply() 接受单个参数数组。

    const obj = {
      name: "sri1",
      func1: function() {
        const name = "sri2"
    
        function a() {
          console.log(this.name)
        }
    
        a.call(this); // call() binds the `this`
        // Or
        a.apply(this); // apply() also binds the `this`
      }
    }
    

    【讨论】:

      【解决方案4】:

      您将window.name 登录到您的函数中。如果你不设置它就是''。

      【讨论】:

      • 那么window对象中有name属性吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 2018-06-22
      • 2013-03-20
      相关资源
      最近更新 更多