JavaScript 中的 public fields vs accessors

直奔主题,给出如下代码:

class A {
  x = 1;
}
class B extends A {
  get x() {
    return 2;
  }
  set x(v) {}
}

const a = new A();
const b = new B();

console.log(a.x);
console.log(b.x);

猜猜它们分别打印什么?

下面的代码呢:

class A {
  constructor() {
    this.x = 1;
  }
}

class B extends A {
  get x() {
    return 2;
  }
  set x(v) {}
}

const a = new A();
const b = new B();
console.log(a.x);
console.log(b.x);

再下面的代码呢:

class A {
  x = 1;
  get x() {
    return 2;
  }
  set x(v) {}
}
const a = new A();
console.log(a.x);

你猜对了吗?

对于 public field,我们观察它在 chrome devtools 下的展现:

JavaScript 中的 public fields vs accessors

可以看到 xA 对象的实例变量,不在其 prototype 上。

而对于 x accessor

JavaScript 中的 public fields vs accessors

x accessor 出现在了 A 对象实例的 Prototype 上。

所以可作出如下结论:

Fields are part of the instance object.  Accessors are part of the object’s prototype.(fields 是对象实例的一部分,而 accessors 是对象原型的一部分。)

进而得出:

So fields are hit before methods/accessors. (fields 总是比 methods/accessors 先被访问。)

所以上面的几个问题,答案就容易推导了。

对于第一个问题,因为 x=1 作用于对象实例,而 get x 作用于对象 prototype,因此 x=1 先被访问,两个打印的都是 1

对于第二个问题,a.x1 ,而 b.x2。比较迷惑的是为什么 b.x2,因为在 contructor 方法里,this 指向的是构造完的对象,即 B 的实例,此时的 this 的 prototype 中有个 x accessor,因此当调用 this.x=1 时,实际上是调用了 set x(v){} 这个accessor(如果不信,可以在 set x(){} 中加一句 console.log 观察)。由于该 set x 是空方法,因此 get x 会一直返回 2

对于第三个问题,和第一个问题一样,x=1 优先于 get x 被访问,故打印 1

(文章参考自一则推文讨论 https://twitter.com/davidmarkclem/status/1430914451268677635)


原文始发于微信公众号(背井):JavaScript 中的 public fields vs accessors

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/246893.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!