javascript 的七種基本數據類型


六種基本數據類型

  • undefined
  • null
  • string
  • boolean
  • number
  • symbol(ES6)

一種引用類型

  • Object

為什么要引入 Symbol?

ES5的對象中的屬性名是字符串,容易造成屬性名的沖突,如果有一種機制,保證每個屬性的名字都是獨一無二的,就可以從根本上防止屬性名的沖突。

Symbol怎么生成?

symbol值通過Symbol函數生成,生成的symbol是一個類似於字符串的原始類型的值

const sym = Symbol(param);
// param 可以為字符串或者對象

知識點:

1.使用new命令會報錯,這是因為生成的Symbol是一個原始類型的值,不是對象,不能添加屬性。

2.如果傳入的參數為對象,會調用toString方法,再轉為字符串

3.Symbol的值不能與其他的值進行運算,Symbol可以顯式的轉為字符串、布爾值,但不能轉為數值。

4.Symbol函數的參數只是表示對當前 Symbol 值的描述,因此傳入的參數不同,Symbol的返回值也是不相等的。

Symbel值作為對象屬性名時,怎樣使用?

let mySymbol = Symbol();

// 第一種寫法
let a = {};
a[mySymbol] = 'Hello!';

// 第二種寫法
let a = {
  [mySymbol]: 'Hello!'
};

// 第三種寫法
let a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });

// 以上寫法都得到同樣結果
a[mySymbol] // "Hello!"

注意:
Symbol每一個值都是不相等的,意味着可以作為標識符,用於對象的屬性名,能保證不會出現同名的屬性,注意作為屬性名時不能使用點運算符。

const mySymbol = Symbol();
const a = {};

a.mySymbol = 'Hello!';
a[mySymbol] // undefined
a['mySymbol'] // "Hello!"
// a的屬性名實際上是一個字符串而不是Symbol的值。

屬性值的遍歷

JSON.stringify是在序列化過程中會自動轉換成對應的原始值;
Object.getOwnPropertySymbols方法返回一個數組,成員是當前對象的所有用作屬性名的 Symbol 值;
Object.getOwnPropertyNames(obj)一個對象,其自身的可枚舉和不可枚舉屬性的名稱被返回。
keys 方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用[for...in]循環遍歷該對象時返回的順序一致 。
Reflect.ownKeys方法可以返回所有類型的鍵名,包括常規鍵名和 Symbol 鍵名。

obj
// {ccc: "aaa", Symbol(a): "hello", Symbol(b): "world"};
JSON.stringify(obj)
// "{"ccc":"aaa"}"
Object.getOwnPropertyNames(obj)
// ["ccc"]
Object.keys(obj)
// ["ccc"]
Object.getOwnPropertySymbols(obj);
// (2) [Symbol(a), Symbol(b)]
Reflect.ownKeys(obj)
// (3) ["ccc", Symbol(a), Symbol(b)]

 

如果我希望使用同一個Symbol值?

let s1 = Symbol.for('foo');
let s2 = Symbol.for('foo');

s1 === s2 // true

 

Symbol.for()Symbol()這兩種寫法,都會生成新的 Symbol。它們的區別是,前者會被登記在全局環境中供搜索,后者不會。

let s1 = Symbol.for("foo");
Symbol.keyFor(s1) // "foo"

let s2 = Symbol("foo");
Symbol.keyFor(s2) // undefined

 

Symbol.keyFor方法返回一個已登記的 Symbol 類型值的key。
注意:

  1. 需要注意的是,Symbol.for為 Symbol 值登記的名字,是全局環境的,可以在不同的 iframe 或 service worker 中取到同一個值。

內置的 Symbol 值?

Symbol.hasInstance

對象的Symbol.hasInstance屬性,指向一個內部方法。當其他對象使用 instanceof運算符,判斷是否為該對象的實例時,會調用這個方法。比如, foo instanceof Foo在語言內部,實際調用的是Foo[Symbol.hasInstance](foo)

class MyClass {
  [Symbol.hasInstance](foo) {
    return foo instanceof Array;
  }
}

 

Symbol.isConcatSpreadable

對象的Symbol.isConcatSpreadable屬性等於一個布爾值,表示該對象用於Array.prototype.concat()時,是否可以展開。
下面代碼說明,Symbol.isConcatSpreadable默認等於 undefined,可以展開。
Symbol.isConcatSpreadable = true || undefined => 展開
Symbol.isConcatSpreadable = false => 不展開

let arr1 = ['c', 'd'];
['a', 'b'].concat(arr1, 'e') // ['a', 'b', 'c', 'd', 'e']
arr1[Symbol.isConcatSpreadable] // undefined

let arr2 = ['c', 'd'];
arr2[Symbol.isConcatSpreadable] = false;
['a', 'b'].concat(arr2, 'e') // ['a', 'b', ['c','d'], 'e']

 

類似數組的對象正好相反,默認不展開。它的Symbol.isConcatSpreadable屬性設為true,才可以展開。

let obj = {length: 2, 0: 'c', 1: 'd'};
['a', 'b'].concat(obj, 'e') // ['a', 'b', obj, 'e']

obj[Symbol.isConcatSpreadable] = true;
['a', 'b'].concat(obj, 'e') // ['a', 'b', 'c', 'd', 'e']

Symbol.species

對象的Symbol.species屬性,指向一個構造函數。創建衍生對象時,會使用該屬性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM