有谁知道为什么输出是“奥巴马”不是“克林顿”?

时间:2017-07-21 22:13:04

标签: javascript this

function setName(obj){
    obj.name = "Obama";
    obj = {name:"Clinton"};
}
var president = {name:"Bush"};
setName(president);
console.log(president.name);

当我将“obj.name =”Obama“;”更改为“this.name =”Obama“;”

function setName(obj){
    this.name = "Obama";
    obj = {name:"Clinton"};
}
var president = {name:"Bush"};
setName(president);
console.log(president.name);

输出变成“布什”。

5 个答案:

答案 0 :(得分:3)

this不是obj。 您可以尝试这样理解:

function setName(obj){
  console.log(this.name);
}

它不会给你obj。 好吧,如果你真的认为使用obj一词不好,试试这个:

function setName(obj){
  setName.arguments[0].name = "Obama";
  obj = {name:"Clinton"}; // I don't touch this.
}

答案 1 :(得分:2)

您正在替换局部变量obj,其范围在函数内部。它只不过是对象的引用。因此,更新obj = { name: "Clinton" };不会影响函数外的任何状态。

但更改对象的名称会影响其内容。这就是你得到“奥巴马”的原因。

this.name = "Obama"president没有相关影响,因为this不是president

答案 2 :(得分:2)

您正在修改对象引用而不是对象本身。

这一行正在修改初始对象。 Obj当前指向的是初始对象,它与总统指向的对象相同。

obj.name = "Obama";

下一行将变量分配给新的对象引用。它不再是指初始对象。变量总统仍然指着最初的对象,因此你得到了奥巴马"而不是"布什"

obj = {name:"Clinton"};

答案 3 :(得分:2)

我添加了一些评论,以帮助了解正在发生的事情。

function setName(obj){

    // change obj's name property to Obama
    obj.name = "Obama";

    // change the reference to obj to a new object inside setName.
    // this does not affect the original object being passed in.
    obj = {name:"Clinton"};
}
var president = {name:"Bush"};
setName(president);
console.log(president.name);


function setName2(obj){

    // change this's name property to Obama. this is set to window/global, not obj.
    this.name = "Obama";

    // change the reference to obj to a new object inside setName.
    // this does not affect the original object being passed in.
    obj = {name:"Clinton"};
}
var president2 = {name:"Bush"};
setName2(president2);
console.log(president2.name);

答案 4 :(得分:0)

在第一种情况下:

当使用president对象调用setName时,它首先将对象的名称设置为Obama。由于您将对象作为参数传递,因此所有更改的属性也将更改为初始对象。当覆盖整个对象Scanner input = new Scanner(new File(fileName),"Unicode"); 时,您将丢失该引用,并且您不会返回该对象,因此它不会发生任何变化。这个名字在第一步就落到了奥巴马身上,它将留在奥巴马身上。

在第二种情况下:

与上面相同,this-context与setName范围有关。您没有使用setName作为Object,或者它不是Object的一部分,所以这里并没有真正可用的this-context。您可以使用call:

附加一个
obj = {name:"Clinton"};

第一个参数是this-context,其他参数是方法的参数。但是,我建议不要这样做。

在对象上使用的setName:

要在对象上使用方法setName,您可以执行以下操作:

setName.call(president, null);

由于您正在使用function President(name) { this.name = name; } President.prototype.setName = function(name) { this.name = name; } var president = new President('Clinton'); president.setName('Obama'); ,因此您需要创建一个新的此上下文,并在创建Object时将name属性设置为Clinton。

此外,这可能有效:

new