[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類的理解和使用