关于闭包或者是作用域的问题

发布于 2022-09-07 12:12:37 字数 717 浏览 36 评论 0

function student () {
    var name = 'xxx';
    var getName = function () {
        return name
    }
    var setName = function (newName) {
        name = newName;
    }
    return {
        getName: getName,
        setName: setName,
        name: name
    }
}
var studentA = student();
console.log(studentA.getName())
studentA.setName("aaa");
console.log(studentA.getName())
console.log(studentA.name);

为啥输出了是

clipboard.png

按道理不是名字已经变成aaa了吗?


更具指导是要在get和set里面都加上this.name就可以了,请问是为什么,我之前写的两个name不是同一个作用域?


我知道了,我把闭包分配的空间和return的空间混淆在一起了,所以没用this是对闭包的 空间的修改然后用this是对这个return的对象的修改

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

灼痛 2022-09-14 12:12:37

首先,你的function里面返回来的是一个新的object对象,然后name是直接拷贝你已经在楼上几个得知了。
接着我们看一下this的指向:

function student () {
  var name = 'xxx';
  var getName = function () {
    return name
  };

  var setName = function (newName) {
    name = newName;
    
    return this;
  };

  return {
    getName: getName,
    setName: setName,
    name: name,
  };
}
var studentA = student();
var whoAmI = studentA.setName("aaa");

console.log(whoAmI); // {getName: ƒ, setName: ƒ, name: "xxx"}

恩恩,this指向了这个return的object对象,为什么呢?因为这个object其实是引用传递给了studentA,studentA调用了这个方法,this自然就指向了studentA。

为了证明这点,我们不从studentA调用,我们直接在内部调用:

function student () {
  var name = 'xxx';
  var getName = function () {
    return name
  };

  var setName = function (newName) {
    name = newName;
    
    return this;
  };

  const whoAmI = setName("aaa");
  console.log(whoAmI); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

  return {
    getName: getName,
    setName: setName,
    name: name,
  };
}
var studentA = student();

是的,独自调用setName,返回来的this就是指向window的(或者说任何没有指定作用域的函数声明都会指向window)。

所以你现在知道了,studentA调用getNamesetName,this都是指向这个object,那么改变这个object的name不就如楼上所说:

setName方法里写 this.name = newName。 就可以了。另外,getName 也要加上 this.name

如果能让你更加理解,你应该分解return

// 操作studentA就是在操作这个result
const result = {
    getName: getName,
    setName: setName,
    name: name,
};

return result;
梦中的蝴蝶 2022-09-14 12:12:37

name是原始类型,return的那一刻把name的值拷贝了了一份返回了,以后name的任何修改都影响不到你的返回值

剑心龙吟 2022-09-14 12:12:37

setName方法里写 this.name = newName。 就可以了
另外,getName 也要加上 this.name

我早已燃尽 2022-09-14 12:12:37

这里面其实有两个name属性:

  1. 一个是函数student的私有属性。
  2. 一个是执行student函数返回的对象。

getNamesetName方法设置的都是student的私有属性name
而最后一行输出的是返回对象的name属性。
由于name属性是值类型,所以不会像引用类型一样,出现一处引用改变,其他引用这个对象的变量也改变的情况。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文