// 返回一个新范围对象
function range(from, to) {
// 继承对象为range函数的methods属性
let r = Object.create(range.methods);
// 定义起点和终点
r.from = from;
r.to = to;
return r;
}
// 所有范围对象继承的方法
range.methods = {
// 适用于文本,日期和数字
includes(x) { return this.from <= x && x <= this.to; },
// 该生成器函数使得实例可以迭代
*[Symbol.iterator]() {
for (let x = Math.ceil(this.from); x <= this.to; x++) yield x;
},
// 返回字符串表示
toString() {
return '(' + this.from + '...' + this.to + ')'
}
}
//
let r=range(1,3);
console.log('includs:',r.includes(2));
console.log('toString:',r.toString());
console.log('---',[...r]) // 通过迭代器转换为数组
// 如果new.target是undefined,那么包含函数就是作为普通函数
// 被调用的,没有使用new关键字。
// 在构造函数中模拟该特性
function C(){
if(!new.target) return new C();
// 这里是初始化代码
}
// 这个技术只适用于以这种老方式定义的构造函数。使用class关
// 键字创建的类不允许不使用new调用它们的构造函数
// 如果不想以构造函数作为媒介,直接测试某个对象原型链中是
// 否包含指定原型,可以使用isPrototypeOf()方法。
console.log('print:',range.methods.isPrototypeOf(r));
console