优点:不可能有别的方法访问到传入到构造函数中的原始数据。
缺点:没有解决对象识别的问题(即不知道这个对象是什么类型),不能依赖 instanceOf 操作符来确定对象类型;对于对象的方法没有做到复用。
8. ES6 中的 class
咱们这块以 class 实例来展开讲述:
class Parent { name = "qck"; sex = "male"; //实例变量 sayHello(name){ console.log('qck said Hello!',name); } constructor(location){ this.location = location; } }
我们来看看这段代码通过 babel 编译后的 _createClass 函数:
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; // 对属性进行数据特性设置 descriptor.enumerable = descriptor.enumerable || false; // enumerable设置 descriptor.configurable = true; // configurable设置 if ("value" in descriptor) descriptor.writable = true; // 如果有value,那么可写 Object.defineProperty(target, descriptor.key, descriptor); // 调用defineProperty() 进行属性设置 } } return function (Constructor, protoProps, staticProps) { // 设置到第一个 Constructor 的 prototype 中 if (protoProps) defineProperties(Constructor.prototype, protoProps); // 设置 Constructor 的 static 类型属性 if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
首先该方法是一个自执行函数,接收的一参是构造函数本身,二参是为构造函数的原型对象需要添加的方法或者属性,三参是需要为构造函数添加的静态属性对象。从这个函数就可以看出 class 在创建自定义类型时,用了原型模式。
我们看看编译后的结果是如何调用 _createClass 的:
var Parent = function () { // 这里是自执行函数 _createClass(Parent, [{ // Parent的实例方法,通过修改Parent.prototype来完成 key: "sayHello", value: function sayHello(name) { console.log('qck say Hello!', name); } }]); function Parent(location) { //在Parent构造函数中添加实例属性 _classCallCheck(this, Parent); this.name = "qck"; this.sex = "male"; this.location = location; } return Parent; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
这里调用 _createClass 的地方就证实了我们刚才的想法——确实应用了原型模式:我们的 class 上的方法,其实是通过修改该类 (实际上是函数) 的 prototype 来完成的。
而通过返回的构造函数,我们可以发现:实例属性还是通过构造函数方式来添加的。
最后,我们来看看 _classCallCheck 方法,它其实是一层校验,保证了我们的实例对象是特定的类型。
所以,综上所述,ES6 中的 class 只是个语法糖,它本质上还是用组合使用构造函数模式创建自定义类型的,这也就是为什么我们要学上面那些知识的初衷。
感兴趣的朋友还可以使用本站在线HTML/CSS/JavaScript代码运行工具:测试上述代码运行结果。
更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》