这个'这个'在转让期间丢失了上下文,但不完全?

时间:2017-11-13 05:39:55

标签: javascript variables scope this

在以下示例中,有一个简单的对象。为我创建了两个实例来测试变量范围。

test1a (和test2a)被分配给方法 ShowNum 时,它的行为与单独调用 oneObj.ShowNum()时的行为相同。但是,当 test1b 分配给方法 ShowNum2 时,它的行为与直接调用 oneObj.ShowNum2()的行为不同。

这对我来说有点令人费解,因为看起来这个'这个'在转让期间,范围正在丢失,但同时它并没有丢失,因为' num'仍然找到(并且num对象实例是唯一的,因为this.num2是)。

这种行为有什么深奥的解释?

function TestObject ()
{
    var num   = 25;
    this.num2 = 50;
    this.ShowNum  = function () {return num;}
    this.ShowNum2 = function () {return this.num2;}
    this.SetNum   = function (newnum) {num = newnum;}
}
var oneObj = new TestObject();
var twoObj = new TestObject(); twoObj.SetNum(100); twoObj.num2 = -12;

var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2;
var test2a = twoObj.ShowNum;
var test2b = twoObj.ShowNum2;

console.log(oneObj.ShowNum());
console.log(oneObj.ShowNum2());
console.log(test1a());
console.log(test1b());

console.log(twoObj.ShowNum());
console.log(twoObj.ShowNum2());
console.log(test2a());
console.log(test2b());

结果:

25
50
25
undefined

100
-12
100
undefined

编辑: 如回复所指出的,这个问题确实看起来像是> here的变体。 我本能的期望是var test1b = oneObj.ShowNum;应该暗示 var test1b = oneObj.ShowNum2.bind(oneObj);使其在各种语言中保持一致的行为(如Mahesha999中提到的那样)

  

与其他关键字相比,此关键字在JavaScript中的行为有所不同   语言。在面向对象语言中,this关键字引用   该类的当前实例。在JavaScript中,这是值   主要由函数的调用上下文决定   (context.function())以及它的调用位置。

现在我不想进一步推动,我认为这件事已经结束了。

1 个答案:

答案 0 :(得分:0)

  

原因:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Condition": {
                "StringLike": {
                    "ec2:ResourceTag/Name": "*public*"
                }
            },
            "Action": [
                "ec2:Run*",
                "ec2:Terminate*",
                "ec2:Cancel*",
                "ec2:Create*",
                "ec2:Delete*",
                "ec2:Modify*",
                "ec2:Start*",
                "ec2:Stop*"
            ],
            "Resource": "arn:aws:ec2:ap-southeast-2:106625493890:subnet/*",
            "Effect": "Deny",
            "Sid": "DenyInstanceActionsForPublicSubnets"
        },

// you are not assigning the whole object , but just passing refernce to the function var test1a = oneObj.ShowNum; var test1b = oneObj.ShowNum2; // so from here it will lose the context of this 就像

test1a

function () {return num;} 就像

test1b

这里,如果你直接分配函数,这里function () {return this.num2;} 不再指向父函数了。因为你刚刚分配了函数

您可以通过将console.log放在内部来检查,

this
  

调试:运行以下代码段,您就会明白:

this.ShowNum2 = function () { console.log(this); return this.num2;}

  

解决方案:

function TestObject ()
{
    var num   = 25;
    this.num2 = 50;
    this.ShowNum  = function () {return num;}
    this.ShowNum2 = function () { console.log(this); return this.num2;}
    this.SetNum   = function (newnum) {num = newnum;}
}
var oneObj = new TestObject();
var twoObj = new TestObject(); twoObj.SetNum(100); twoObj.num2 = -12;

var test1a = oneObj.ShowNum;
var test1b = oneObj.ShowNum2;
var test2a = twoObj.ShowNum;
var test2b = twoObj.ShowNum2;

console.log(oneObj.ShowNum());
console.log(oneObj.ShowNum2());
console.log(test1a());
console.log(test1b());

console.log(twoObj.ShowNum());
console.log(twoObj.ShowNum2());
console.log(test2a());
console.log(test2b());

//.bind(parent_object);

var test1b = oneObj.ShowNum2.bind(oneObj);
var test2b = twoObj.ShowNum2.bind(twoObj);