JavaScript 对象 -- 我们真的需要模拟类吗?
JavaScript 本身就是面向对象的,不需要模拟。
之前做的模拟面向对象的事情,其实是“模拟基于类的面向对象”。
JavaScript 是基于原型的面向对象。
什么是原型
基于“类”的编程:先有类,再从类去实例化一个对象。
基于“原型”的编程:关注一系列对象实例的行为,再去关注如何将这些对象划分到最近的使用方式相似的原型对象,而不是将他们分成类。
基于原型的面向对象系统通过复制的方式创建对象。
原型系统的复制操作:
- 使新对象持有一个原型的引用
- 复制对象,之后两个对象再无关联
JavaScript 使用了前一种。
JavaScript 的原型
ES6 新增三个操纵原型的方法:
- Object.create()
- Object.getPrototypeOf()
- Object.setPrototypeOf()
早期版本中的类与原型
早期版本中类的定义是一个属性 [[class]]
,可通过 Object.prototype.toString() 访问。
var o = new Object;
var n = new Number;
var s = new String;
var b = new Boolean;
var d = new Date;
var arg = function(){ return arguments }();
var r = new RegExp;
var f = new Function;
var arr = new Array;
var e = new Error;
console.log([o, n, s, b, d, arg, r, f, arr, e].map(v => Object.prototype.toString.call(v)));
// ["[object Object]", "[object Number]", "[object String]", "[object Boolean]", "[object Date]", "[object Arguments]", "[object RegExp]", "[object Function]", "[object Array]", "[object Error]"]
es5 开始,用 Symbol.toStringTag 代替 [[class]]
私有属性。
var o = { [Symbol.toStringTag]: "MyObject" }
console.log(o + ""); // [object MyObject]
new 操作做了哪些事
接受一个构造器和一组调用参数。
略...