为什么"这个"在通过引用传递函数后调用函数时,不同的内部对象?

时间:2018-04-08 18:06:40

标签: javascript object this pass-by-reference

简而言之:为什么直接调用的函数和通过引用传递的函数具有不同的"这个"使用对象时Javascript中的上下文?

总之:我定义了一个对象,以及一些方法 prototypes ,其中使用关键字" this & #34;访问Objects属性。我实例化对象,我能够调用方法,一切都按预期工作。问题是这些方法中的任何一个都可以抛出异常,我想单独捕获每个异常。为了避免重复代码,我实现了一个 runCatch 函数,我将对该函数的引用传递给该函数,并在发生错误时调用该函数。在 runCatch 中,我基本上执行了引用的方法,并将其包含在 try-catch 中,但是像这样, " "关键字指向" 窗口"对象而不是对象本身。因此,根据我对Javascript上下文的理解,如果我使用 new 关键字初始化对象,那么" this "原型函数中的上下文应始终引用Object本身。

以下是正在发生的事情的一个小例子:

https://jsbin.com/gugohubori/edit?html,js,output

HTML:

var users = [User]()

let data = """
[{"U_ID":"1","Email":"test","Password":"test","UserType":"Teacher"}]
""".data(using: .utf8)

do{
    users = try JSONDecoder().decode(Array<User>.self, from: data!)
}catch{
    print(error.localizedDescription)
}

print(users.first?.Email)

使用Javascript:

<div>Object Value (Direct Call): 
<span id="val1"></span>
<div>Object Value (Passed by Reference): 
<span id="val2"></span>

以前代码的结果是:

对象值(直接呼叫):IT工作

对象值(通过引用传递):undefined

有人可以解释为什么&#34; 这个&#34;的背景根据你所说的不同而不同?从示例中使用 callbyref 函数来获得正确的&#34; this &#34;指向对象的引用?

编辑:混淆来自哪里?因此,对我来说,主要的困惑似乎是当你创建一个常规对象&#34; {} &#34;该对象中 this 的上下文是执行它的上下文。但是当您使用 new 关键字创建对象时,该对象内部方法的上下文将绑定到对象本身,无论它们在何种上下文中被调用。但无论出于何种原因,当函数作为变量传递并在其他地方调用时,有界上下文会丢失(@Carloluis很好地解释了这一点)。

编辑关于重复任何人都可以澄清为什么这个问题被标记为重复?我知道这个变量Javascript中的混淆是广泛流行的,似乎是一个微不足道的问题,但在此之前我一直在研究。链接为重复问题的帖子并不能解决我的问题,而是以通用方式解释&#34; this &#34;变量和上下文,但从未解释为什么用 new 实例化的对象在作为引用传递时最终会丢失其对象上下文。我认为来自@Carloluis的答案比标记为重复的另一个无关问题的链接更清晰。

2 个答案:

答案 0 :(得分:1)

问题是JavaScript中的this关键字值取决于函数的调用方式。

  

与其他语言相比,函数的此关键字在JavaScript中的行为略有不同。

详细了解MDN

您可以认为函数调用中的this指向&#34; dot&#34;之前的对象,并且如果调用中没有任何.它将指向windows对象(当您将obj.getValue的引用传递给callbyref函数时就是这种情况。

&#13;
&#13;
function MyObject(){
  this.value = "IT WORKS"
}

MyObject.prototype.getValue = function(){
  return this.value;
}

const myObject = new MyObject();
console.log(myObject.getValue()); // this -> { value: 'IT WORKS' }

const getValueRef = myObject.getValue;
console.log(getValueRef()); // this -> Windows object

// -- Using the `.bind` function to attach the this context
// In the new function this is permanently bound to the first argument of bind, regardless of how the function is being used.
const getValueRefBound = myObject.getValue.bind(myObject);
console.log(getValueRefBound()); // this -> myObject
&#13;
&#13;
&#13;

在上一个代码段中添加了一个示例,说明如何将this上下文绑定到稍后的函数执行,尽管它是如何使用的。

<强> Function.prototype.bind()

  

bind()方法创建一个新函数,在调用时,将其this关键字设置为提供的值,并在新的函数前面提供任何给定的参数序列函数被调用。

您还可以查看此帖子Understanding Scope and Context in JavaScript

答案 1 :(得分:0)

上下文。

//Creates new instance
var obj = new myobject();
//Calls the method in the instance's context
//When a function is called as a method of an object, this is the object
obj.getValue();

//Grabs the reference to the method
var callback=obj.getValue;
//Calls the referenced method in current context, which is window
callback();

您可以尝试,添加一个新方法,将this返回或打印到控制台。

如果您需要始终将this作为对象,则应使用callback.call(obj,param)apply(obj,params)