局部变量以某种方式创建,无论是全局变量

时间:2017-10-27 09:51:54

标签: javascript



var construct = function() {
  var self = this;

  var view = {
    name: "self"
  };

  self.vm = {
    attached: attached,
    view: view
  }

  function attached() {
    alert('view.name: ' + view.name);
    view = {
      name: "attached"
    };
    alert('view.name(after attached): ' + view.name);
    alert('self.vm.view.name: ' + self.vm.view.name);
    alert('this.view.name: ' + this.view.name);
  }

  self.vm.attached();

  return self.vm;
}()




正如您所看到的,我们有一个变量' view'在全局(与selv.vm对象相关)上下文中。 view通过引用传递给self.vm对象。

知道了这一点,我们可以假设'附加'方法将更改全局变量,因此self.vm.view将指向一个新对象。

将创建一个新的局部变量,无论那里是否具有相同名称的全局变量。

有点出乎意料的行为不是吗?任何想法为什么会这样?

3 个答案:

答案 0 :(得分:2)

将其简化为一个简单的例子:



var a = {name: 'one'};
var b = {view: a};

// See what b.view holds
console.log(b.view);

// Change a and look again
a = {name: 'two'};
console.log(b.view);




我们更改了引用a指向的对象。但是b.view仍然保留对原始对象的引用(a在重新分配之前指向的对象)

答案 1 :(得分:2)

function attached()内,您基本上将view变量重新分配给新创建的对象。您没有更改现有对象,该对象仍然存在。由于self.vm.view保留了对view初始值的引用,因此当您执行self.vm.view.name时,您会看到这些值。

如果您想要更改原始对象中的值,您需要执行

view.name = "attached";

答案 2 :(得分:1)

这是因为view是指针。

var construct = function() {
  var self = this;

  // this create a new object, with the property name being "self"
  // and "view" as a pointer to that object
  var view = {
    name: "self"
  };

  self.vm = {
    attached: attached,
    // here the property "view" of the "vm" object points to the variable "view", which itself points to the original object (the one with name="self")
    view: view
  }

  function attached() {
    // the pseudo-global "view" object is called, it reaches out to the object it points to and gives us the name: "self"
    alert('view.name: ' + view.name);
    // now we are changing "view" to point to a NEW object, with the property name="attached"
    view = {
      name: "attached"
    };
    // view points to the new object, it's name is "attached"
    alert('view.name(after attached): ' + view.name);
    // the "view" property of self.vm still points to the original object, the one with the name "self"
    alert('self.vm.view.name: ' + self.vm.view.name);
    alert('this.view.name: ' + this.view.name);
  }

  self.vm.attached();

  return self.vm;
}()

也要看一下这个问题:Javascript by reference vs. by value。也许它可以比我更好地解释事情。

这是一个棘手的主题。