function countCapturingGroups(r){
r = new RegExp(`|${r.source}`);
const result = ''.match(r);
return result.length - 1;
}
const result = countCapturingGroups(/fo(.)b(..)/);
console.log(result); // 2
class Person {
constructor(name) {
this.name = name;
}
hello() {
return `Hello, my name is ${this.name}.`;
}
}
如果你有其它面向对象语言的经验,应该很容易理解这段代码。
不过 JS 的构造函数特别,它支持 return 一个其它对象,作为 new SomeClass() 的结果。(如果不 return 或者 return 一个空对象,那么 new SomeClass() 得到的就是 SomeClass 的实例。)
也就是说,原则上,我们可以这么做:
class Person {
constructor(name) {
this.name = name;
return {name: 'Meathill'};
}
}
const person = new Person('张三');
console.log(person.name); // 'Meathill'
结合 Proxy
理解了上一节的内容,我们就很容易得到这样一个类:
class Person {
constructor(name) {
this.name = name;
return new Proxy(this, {
get(target, property) {
if (property in target) {
return target[property];
}
console.warn('Sorry, I can't do that.');
}
}
}
}
在这个类的构造函数里,我返回了一个 Proxy 实例,代理了对真正 Person 实例的访问。当访问的属性/方法在实例上时,就返回需要的属性/方法,否则的话,输出警告。
实际上,Proxy 的 get 和 set 的功能远不止如此,上面的代码只是一些演示。
用途
魔法属性/方法主要有以下用途:
对象 a 要使用一部分对象 b 的功能,但是又不方便直接用原型链。比如上一篇文章的场景,我提供类 VElement 作为接口,实际完成工作的是另一个沙箱中的 Element。