JavaScript —— Symbol数据类型的拓展

JavaScript —— Symbol数据类型的拓展

上一篇文章学习了Symbol的基本用法和作用,但对于Symbol的构造器对象,里面还有很多内置方法我们可以研究一下,让我们一起看看吧!

上一篇文章:《传送地址》

在这里插入图片描述

一、Symbol.hasInstance

hasInstance?看起来好眼熟。难道它跟我们的某些API有关系?

没错!他就是instanceof!当我们使用这个API判断类型的时候,就会调用这个类型构造器的内置对象属性。我们可以举个例子:

class myObject {
  static [Symbol.hasInstance](obj) {
	return obj.constructor === Object
  }
}

console.log({} instanceof myObject) // true
// 相当于 myObject[Symbol.hasInstance]({})
console.log([] instanceof myObject) // false
// 相当于 myObject[Symbol.hasInstance]([])

上面这个例子,我们自己替myObject这个类实现了对应instanceof的内置方法,一般JavaScript的数据类型都内置有这个构造器对象属性,如果没有,则返回false

class myObject {
        
}
console.log({} instanceof myObject) // false

二、Symbol.iterator

当JavaScript的一些数据类型含有Symbol.iterator内置对象属性时,我们把由这种数据类型创建的对象称为可迭代对象

其作用是,当可迭代对象被for...of语句调用时,返回默认的迭代器。在ES6中,ArraySetMapstring都是可迭代对象,他们都被内置了Symbol.iterator对象属性。

什么意思呢?我们举个例子:

const arr = [1, 2, 3, 4, 5];
for (let a of arr) {
  console.log(a);
}

// 输出 1
// 输出 2
// 输出 3
// 输出 4
// 输出 5

其实我们可以把它拆分出来,实际上在执行for...of语句时,本质是下面这样的:

const iterator = arr[Symbol.iterator]();

console.log(iterator.next()); // Object {value: 1, done: false}
console.log(iterator.next()); // Object {value: 2, done: false}
console.log(iterator.next()); // Object {value: 3, done: false}
console.log(iterator.next()); // Object {value: 4, done: false}
console.log(iterator.next()); // Object {value: 5, done: false}
console.log(iterator.next()); // Object {value: undefined, done: true}

执行for...of循环的时候,先调用了arr数组的Symbol.iterator方法,由此来获取迭代器对象。接下来就是调用iterator.next()方法将迭代器对象的value属性赋值到a当中,5次迭代之后,该对象的done属性为true,然后循环结束。

当然,我们也可以为自己的类定义集合且来实现可迭代对象:

class myArray {
  constructor() {
	this.myArr = [];
  }
  add(data) {
	this.myArr.push(data);
	return this;
  }
  *[Symbol.iterator]() {
	for (let a of this.myArr) {
	  yield a;
	}
  }
}

// 1.创建对象
const otherArr = new myArray();
// 2.调用事先定义好的方法
otherArr.add(1);
otherArr.add(2);
otherArr.add(3);
otherArr.add(4);
otherArr.add(5);
// 3.使用for...of调用可迭代对象
for (let b of otherArr) {
  console.log(b);
}

// 输出 1
// 输出 2
// 输出 3
// 输出 4
// 输出 5

反之,如果我们没有为类定义好内置的对象迭代属性,我们使用for...of,就会报错:

class myArray {
  constructor() {
	this.myArr = [];
  }
  add(data) {
	this.myArr.push(data);
	return this;
  }
}

// 1.创建对象
const otherArr = new myArray();
// 2.调用事先定义好的方法
otherArr.add(1);
otherArr.add(2);
otherArr.add(3);
otherArr.add(4);
otherArr.add(5);
// 3.使用for...of调用可迭代对象
for (let b of otherArr) {
  console.log(b);
}

// 输出 Uncaught TypeError: otherArr is not iterable,即 otherArr 不是可迭代对象

三、总结

其实也没有什么好总结的,只是,我们要知道是这个数据类型Symbol它的一些能力即可。上面两点只是我临时起意,就码来玩玩,大家有兴趣的可以继续研究最上面的那个截图~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值