[TOC]
>[success] # Symbol的一些构造方法
<br/>
>[success] ## Symbol.hasInstance
1. 应用场景:判断`数据类型`
~~~
以前我们想检索一个'数据'是'某种数据类型'都是用'typeof',如下:
let arr = [] // 定义一个数组
console.log(typeof arr) // object
上面我们想要的是'Array'类型,但是结果却是'Object',这时候用'typeof'就不行了,这时候
用'Symbol.hasInstance'判断即可,用'instanceof'也可以。'ES6只是将instanceof作为Symbol.hasInstance的简写方法'
let arr = [] // 定义一个数组
console.log(arr instanceof Array) // true
等同于下面代码
let arr = [] // 定义一个数组
console.log(Array[Symbol.hasInstance](arr)) // true
~~~
2. 定义一个无实例的函数
~~~
2.1 首先定义一个'有实例的函数',看一下是什么样子的,下面的'obj1是Object1类的实例'
function Object1(){
// 空函数
}
Object1.prototype.test = function(){
console.log('啊啊啊')
}
let obj1 = new Object1() // 实例化对象
console.log(obj1 instanceof Object1) // 打印 true,证明obj1是Object1类的实例
console.log(Object1[Symbol.hasInstance](obj1)) // true
2.2 接下来定义一个'无实例的函数',下面的'obj2'实际上确实是'Object2'类的实例,在调用过
'Object.defineProperty()'方法之后,'instanceof '就会返回'false',证明'obj2'不是'Object2'
的实例。
function Object2(){
// 空函数
}
Object.defineProperty(Object2, Symbol.hasInstance, { // 给MyObject对象定义一个熟悉名为'Symbol.hasInstance'的熟悉,值为一个函数
value: function(v){
return false
}
})
let obj2 = new Object2() // 实例化对象
console.log(obj2 instanceof Object2) // 打印 false,证明obj2不是Object2的实例
console.log(Object2[Symbol.hasInstance](obj2)) // false
~~~
3. 通过值来检查是否为实例
~~~
// 1. class类中应用的场景
class MyClass {
static [Symbol.hasInstance](num) { // 静态方法(静态方法不需要实例化对象就可以使用, 例如MyClass[Symbol.hasInstance](4))
return num % 2 === 0
}
[Symbol.hasInstance](num) { // 动态方法
return num % 2 === 0
}
}
console.log(1 instanceof MyClass); // false
console.log(2 instanceof MyClass); // true
console.log(2 instanceof new MyClass()); // true
// 2. 对象中的应用场景
const obj = {
[Symbol.hasInstance](num) {
return num % 2 === 0
}
}
console.log(1 instanceof obj); // false
~~~
~~~
我们可以通过'Object.defineProperty'方法'改写一个不可写属性
所以其实可以'重写'所有'内建函数(如Date和Error)'默认的'Symbol.hasInstance'属性
~~~
<br/>
>[success] ## Symbol.isConcatSpreadable
~~~
'Symbol.isConcatSpreadable'用来'配置'某'数组'作为'concat()'方法的参数时,是否'展开其数组'元素。
~~~
1. Symbol.isConcatSpreadable用法
~~~
// 设置Symbol.isConcatSpreadable前
const alpha = ['a', 'b', 'c'];
const numeric = [1, 2, 3];
let alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // ["a", "b", "c", 1, 2, 3]
// 设置Symbol.isConcatSpreadable后
numeric[Symbol.isConcatSpreadable] = false; // 收起数组
alphaNumeric = alpha.concat(numeric);
console.log(alphaNumeric); // ["a", "b", "c", [1, 2, 3]]
// 等同于下面的扩展运算符写法
let a = ['a', 'b', 'c']
let b = [1, 2, 3]
let c = [...a, ...b] // 展开数组
console.log(c) // [ 'a', 'b', 'c', 1, 2, 3 ]
let d = [...a, b] // 收起数组
console.log(d) // [ 'a', 'b', 'c', [ 1, 2, 3 ] ]
~~~
- Javascript基础篇
- Array数组
- 数组插入值
- filter()
- forEach()
- push()
- pop()
- unshift()
- shift()
- valueOf()
- 面向对象思想
- Javascript 面向对象编程(一):封装
- Javascript面向对象编程(二):构造函数的继承
- Javascript面向对象编程(三):非构造函数的继承
- 解构
- 数组的解构赋值
- 对象的解构赋值
- 函数参数解构
- 字符串的解构赋值
- 数值和布尔值的解构赋值
- 圆括号问题
- 字符串.
- split()
- charAt()
- charCodeAt()
- concat()
- indexOf()
- lastIndexOf()
- match()
- replace()
- includes()
- 初识递归
- 渲染ul-li树形结构
- 异步函数解决方案
- 1. callback回调函数
- 2. ES6 - Promise
- JavaScript高级程序设计(书)
- 在html中使用JavaScript
- script标签的位置
- 延迟脚本
- 异步脚本
- <noscript>元素
- 基本概念
- 严格模式
- 变量详解
- 数据类型
- typeof操作符
- undefined类型
- Null类型
- Boolean类型
- Number类型
- 深入了解ES6(书)
- var 、let 、 const
- 字符串与正则表达式
- 字符串
- 正则表达式
- 函数
- 函数形参默认值
- 使用不具名参数
- 函数构造器的增强能力
- 扩展运算符
- name属性
- 明确函数的多重用途
- 块级函数
- 箭头函数
- 尾调用优化
- 扩展的对象功能
- 对象类别
- 对象字面量语法的扩展
- ES6对象新增方法
- 重复的对象属性
- 自有属性的枚举顺序
- 更强大的原型
- 解构:更方便的数据访问
- 为什么要用解构?
- 对象解构
- 数组解构
- 混合解构
- 参数解构
- Symbol与Symbol属性
- 创建Symbol
- Symbol的使用方法
- Symbol全局私有属性
- Symbol与类型强制转换
- Symbol属性检索
- Symbol的一些构造方法
- Set集合与Map集合
- Set集合
- Weak Set集合(弱引用Set集合)
- Map集合
- JS标准内置对象
- Object 构造函数及属性
- Object 构造方法
- Symbol 内建对象类的函数及属性
- Set 构造函数及属性
- Weak Set 构造函数及属性
- JS杂项
- 类数组对象
- Class类的理解和使用