Javascript最开始被设计出来,是为了解决一些Web上的简单交互的,但随着网络的发展,要解决的问题越来越复杂,在JS编程中,代码总是显得怪里怪气,不过好在在ES6中,增加了Class语法,虽然它本质上属于语法糖,但是至少JS像是真正的面向对象语言了。
在阅读本篇之前,希望能先阅读一下关于JS构造函数和继承相关的文章。
1、通过class关键字,可以定义类。
2、每个类中必须包含构造方法(constructor方法),构造方法对应的就是es5中的构造函数,如果没有显示声明constructor方法,JS会自动添加一个空的constructor方法。
3、类中的this关键字则代表实例对象。
4、同构造函数一样使用new关键字实例化一个对象,且必须使用new关键字
5、类内部定义的方法,前面不用加function,后面不可以加逗号 ,方法会自动定义在类的prototype属性中。
class Spanner {
constructor(material) {
this.material = material;
};
aboutMaterial() {
console.log(`这是一个${this.material}${Spanner.name}`);
};
};
console.log(new Spanner('铁'));
var Spanner = function () {
function Spanner(material) {
_classCallCheck(this, Spanner);
this.material = material;
}
_createClass(Spanner, [{
key: 'aboutMaterial',
value: function aboutMaterial() {
console.log('这是一个' + this.material + Spanner.name);
}
}]);
return Spanner;
}();
这里省略了两个函数_classCallCheck和_createClass,
Spanner('铁');
Spanner.call({},'铁');
6、类的内部定义的所有方法都是不可枚举的
7、类的内部默认是严谨模式
在Class基本语法中的内容是ES6中比较明确的内容,目前各浏览器对ES6的支持大不相同,而且ES的语法还在不断的变化中,下面的代码是在Chrome浏览器中测试过的,其他浏览器不一定适用。虽然如此,也不用过分担心浏览器的差异问题,以后我们用ES6基本会在框架中使用,相信会有很好的解决方案。
首先,参考class中定义方法的形式来定义一个属性,理所当然我认为该属性会成为一个原型属性
class Spanner {
constructor(material) {
this.material = material;
};
//定义一个属性
productName='扳手';
//定义一个方法
aboutMaterial() {
console.log(`这是一个${this.material}${Spanner.name}`);
};
};
console.log(new Spanner('铁'));
结果有点出乎意料,在firefox中根本不支持这种语法,实际上这是ES7的语法,Chrome中,productName成为了自有属性,在代码解析成ES6语法时,可以看到实际上是在构造函数的内部调用了一个函数_defineProperty,作用是将属性添加到对象中。
这样做的效果和在构造函数中用this直接定义是一样的,而效率更低,所以不建议这样做。
定义类的时候,如果需要静态方法,可以参考构造函数的方法,添加静态属性,这种方式和给函数添加静态属性是一样的。
class Spanner {
};
Spanner.width='10cm';
Spanner.operation=function () {
return '静态方法被调用了';
}
console.log(Spanner.width); //10cm
console.log(Spanner.operation()); //静态方法被调用了
使用static关键字定义静态方法和静态属性,目前大部分浏览器不支持。
class Spanner {
static width = '10cm';
static operation = function () {
return '静态方法被调用了';
}
};
console.dir(Spanner);
console.log(Spanner.width); //10cm
console.log(Spanner.operation()); //静态方法被调用了
这个方法只是让class的封装更美好的语法糖,实际上和方法1是一样的,解析成
ES6是这样的:
class Spanner {}
_defineProperty(Spanner, "width", '10xm');
_defineProperty(Spanner, "operation", function () {
return '静态方法被调用了';
});
在构造函数中可以定义私有的属性和方法,在class中要怎么处理呢?
答案是ES6中的classES6没有提供私有属性、私有方法的语法。
和从前一样,又要开始模拟了,下面介绍两个封装到class中的方法。
1、用命名方式来区别
用下划线表示私有属性和私有方法,这种写法只是一种约定,约定这种方式定义的是私有属性,不要用常规的方式调用。
class Spanner {
constructor(material) {
this.material = material;
this.productName='扳手';
};
_privateV='私有属性';
_privateF(){
return '调用了私有方法'
}
publicF() {
return this._privateF();
};
};
let s=new Spanner('Fe');
console.log(s.publicF()); //调用了私有方法
console.log(s._privateF()); //调用了私有方法
2、在属性名之前,使用#表示
class Spanner {
constructor(material) {
this.material = material;
this.productName='扳手';
};
#privateV='私有属性';
#privateF(){
return '调用了私有方法'
}
};
console.log(new Spanner('Fe'));
这种写法目前还是一直提案,Chrome中支持#定义私有属性,不支持私有方法,关于私有属性的用法就先说到这里,等学习框架的时候还会遇到的。