在es6中,咱们能够用class
关键字来定义类,语法以下javascript
class Person { // 构造函数 constructor (name) { // 属性初始化 this.name = name; } // 成员方法 sayName () { console.log(this.name); } // 静态方法 static sayHi () { console.log("Hi~"); } }
其实本质仍是基于javascript原型链机制开发的语法糖
,其中,本人对setter/getter进行一番研究,发现了很多坑。java
class Person { constructor (name, age) { this.name = name; this.age = age; } set name (name) { console.log("setter"); this.name = name; } get name () { console.log("getter"); return this.name; } } var p = new Person("zhang", 25);
很快,咱们就会发现代码报错了es6
这是由于,在构造函数中执行this.name=name
的时候,就会去调用set name
,在set name方法中,咱们又执行this.name = name
,进行无限递归,最后致使栈溢出(RangeError)。函数
咱们稍做修改,让这个代码能够正常执行,达到咱们想要的效果。this
class Person { constructor (name, age) { this.name = name; this.age = age; } set name (name) { console.log("setter"); this._name = name; } get name () { console.log("getter"); return this._name; } // 加一个成员方法 sayName () { console.log(this.name); } } var p = new Person("zhang", 25); p.sayName();
执行结果为spa
到这里就能够明白了,原来只要this.name中的属性名和set name/get name后面的name一致,对this.name就会调用setter/getter,也就是说setter/getter是hook函数
,而真实的存储变量是_name
,咱们能够在代码中直接获取它。code
class Person { constructor (name, age) { this.name = name; this.age = age; } set name (name) { console.log("setter"); this._name = name; } get name () { console.log("getter"); return this._name; } // 加一个成员方法 sayName () { console.log(this.name); } } var p = new Person("zhang", 25); console.log(p._name); // "zhang"
执行结果为blog
注意到结果并无执行getter,由于咱们直接访问了p._name
,而不是p.name
递归
当一个属性只有getter没有setter的时候,咱们是没法进行赋值操做的(第一次初始化也不行),这一点也是至关地坑
。例如图片
class Person { constructor (name) { this.name = name; } // 只有getter get name () { console.log("getter"); return this.name; } } var p = new Person("zhang");
执行结果为
当没有getter和setter时,就能够正常读写属性