重学前端进修笔记(六)--JavaScript范例有哪些你不知道的细节?

笔记申明

重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时刻开的一个专栏,
天天10分钟,重构你的前端学问系统,笔者主要整顿进修历程的一些要点笔记以及感悟,完全的可以到场winter的专栏进修【原文有winter的语音】,若有侵权请联络我,邮箱:kaimo313@foxmail.com。

JavaScript范例有哪些你不知道的细节?

winter提了几个题目测试:能回复对几个?

  • 1、为何有的编程范例请求用 void 0 替代 undefined?
  • 2、字符串有最大长度吗?
  • 3、0.1 + 0.2 不是即是 0.3 么?为何 JavaScript 里不是如许的?
  • 4、ES6 新到场的 Symbol 是个什么东西?
  • 5、为何给对象增加的要领能用在基本范例上?

假如有点犹疑,无妨看看下面的引见,或许找找材料复习一下。

范例

  1. Undefined
  2. Null
  3. Boolean
  4. String
  5. Number
  6. Symbol
  7. Object

1、Undefined、Null

Undefined:

  • Undefined 范例示意未定义,它的范例只要一个值,就是 undefined
  • 任何变量在赋值前是 Undefined 范例、值为 undefined
  • JavaScript 的代码 undefined 是一个变量,而并不是是一个关键字,这是 JavaScript 言语公认的设想失误之一
  • 为了防备无意中被改动,可以运用 void 0 来猎取 undefined 值。

Null:

  • Null 范例也只要一个值,就是 null,它的语义示意空值
  • 与 undefined 差别,null 是 JavaScript 关键字
  • 在任何代码中,都可以用 null 关键字来猎取null值

2、String

  • String 用于示意文本数据
  • String 有最大长度是 2^53 – 1
  • 字符串的最大长度,实际上是受字符串的编码长度影响的。

Note: 现行的字符集国际规范,字符是以 Unicode 的体式格局示意的,每个 Unicode 的码点示意一个字符,理论上,Unicode 的局限是无穷的。UTF 是 Unicode 的编码体式格局,划定了码点在计算机中的示意要领,罕见的有 UTF16 和 UTF8。Unicode 的码点通经常使用 U+??? 来示意,个中 ??? 是十六进制的码点值。0-65536(U+0000 – U+FFFF)的码点被称为基本字符地区(BMP)。

3、Number

  • JavaScript 中的 Number 范例有 18437736874454810627(即 2^64-2^53+3) 个值
  • NaN,占用了 9007199254740990,这原本是相符 IEEE 划定规矩的数字
  • Infinity,无穷大
  • -Infinity,负无穷大
  • 依据双精度浮点数的定义,Number 范例中有用的整数局限是-0x1fffffffffffff 至 0x1fffffffffffff,所以 Number 没法准确示意此局限外的整数
  • 依据浮点数的定义,非整数的 Number 范例没法用 ==(=== 也不可)来比较

关于javaScript中 0.1 + 0.2 == 0.3 ? 这个题目的诠释:

console.log( 0.1 + 0.2 == 0.3);
>> false

输出效果为false,申明双方不相等,这是浮点运算特性致使的,实际上,这里毛病的不是结论,而是比较的要领,准确的比较要领是运用javaScript供应的最小精度值:

我们可以查找MDN文档的Number可以找到属性EPSILON

Number.EPSILON:两个可示意数字之间的最小距离

console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);
>> true

如许的比较输出效果为true搜检等式摆布双方差的绝对值是不是小于最小精度,才是准确的比较浮点数的要领

4、Symbol

关于Symbol的引见,我准备用ES6文档-阮一峰来做一些引见,详细的可以参考文档

4.1、ES6 引入Symbol的缘由

ES5 的对象属性名都是字符串,这轻易形成属性名的争执。ES6引入了一种新的原始数据范例Symbol,示意举世无双的值。从根本上防备属性名的争执。

4.2、引见

通常属性名属于 Symbol 范例,就都是举世无双的,可以保证不会与其他属性名发作争执。

4.2.1、Symbol 值经由过程Symbol函数天生,先来一段代码:

let s = Symbol();
typeof s
>> "symbol"

上面代码中,变量s就是一个举世无双的值。sSymbol数据范例。

4.2.2、Symbol函数可以接收一个字符串作为参数,示意对 Symbol 实例的形貌

let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1
>> Symbol(foo)
s2
>> Symbol(bar)

s1.toString()
>> "Symbol(foo)"

s2.toString()
>> "Symbol(bar)"

上面代码中,s1s2是两个 Symbol 值。假如不加参数,它们在控制台的输出都是Symbol(),不利于辨别。有了参数今后,就即是为它们加上了形貌,输出的时刻就可以分清,究竟是哪个值。

4.2.3、假如 Symbol 的参数是一个对象,就会挪用该对象的toString要领,将其转为字符串,然后才天生一个 Symbol 值。

const obj = {
    a: '123123',
    toString() {
        return 'iuoisigud';
    }
};
const sym = Symbol(obj);

sym // Symbol(iuoisigud)

4.2.4、Symbol函数的参数只是示意对当前 Symbol 值的形貌,因而雷同参数的Symbol函数的返回值是不相等的。

// 没有参数的状况
let s1 = Symbol();
let s2 = Symbol();

s1 === s2 // false

// 有参数的状况
let s1 = Symbol('foo');
let s2 = Symbol('foo');

s1 === s2 // false

4.2.5、Symbol 值不能与其他范例的值举行运算,会报错。

let sym = Symbol('My symbol');

"your symbol is " + sym
// TypeError: can't convert symbol to string
`your symbol is ${sym}`
// TypeError: can't convert symbol to string

4.2.6、Symbol 值可以显式转为字符串,也可以转为布尔值,然则不能转为数值。

let sym = Symbol('My symbol');

String(sym) // 'Symbol(My symbol)'
sym.toString() // 'Symbol(My symbol)'

let sym = Symbol();
Boolean(sym) // true
!sym  // false

Number(sym) // TypeError
sym + 2 // TypeError

4.2.7、其他的一些属性可以去看ES6文档-阮一峰

4.3、注重

Symbol函数前不能运用
new敕令,不然会报错。这是因为天生的
Symbol 是一个原始范例的值,不是对象。也就是说,因为
Symbol 值不是对象,所以不能增加属性。基本上,它是一品种似于
字符串的数据范例

5、Object

Object 是 JavaScript 中最庞杂的范例,也是 JavaScript 的中心机制之一。

为何给对象增加的要领能用在基本范例上?

回复:“运算符供应了装箱操纵,它会依据基本范例组织一个暂时对象,使得我们能在基本范例上挪用对应对象的要领。”

比方原型上增加要领,也可以应用于基本范例:

Symbol.prototype.hello = () => console.log("hello");

var a = Symbol("a");
console.log(typeof a); //symbol,a 并不是对象
a.hello(); //hello,有用

6、范例转换

6.1、臭名远扬的“ == ”运算

  • 因为 JS 是弱范例言语,所以范例转换发作非常频仍
  • “ == ”试图完成跨范例的比较,它的划定规矩庞杂到险些没人可以记着。

6.2、转换划定规矩

《重学前端进修笔记(六)--JavaScript范例有哪些你不知道的细节?》

6.3、StringToNumber

字符串到数字的范例转换,存在一个语法结构,范例转换支撑十进制、二进制、八进制和十六进制

比方:

Number('0xFF')
>> 255

6.4、装箱转换

装箱(boxing):值范例实例到对象的转换,它暗示在运行时实例将照顾完全的范例信息,并在堆中分派。

每一种基本范例 NumberStringBooleanSymbol 在对象中都有对应的类,所谓装箱转换,恰是把基本范例转换为对应的对象,它是范例转换中一种相称主要的品种。

例子:应用一个函数的
call 要领来强制发作
Symbol装箱

var symbolObject = (function() {
    return this;
}).call(Symbol("a"));

console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true

例子:运用内置的 Object 函数,我们可以在 JavaScript 代码中显式挪用装箱才能。

var symbolObject = Object(Symbol("a"));

console.log(typeof symbolObject); //object
console.log(symbolObject instanceof Symbol); //true
console.log(symbolObject.constructor == Symbol); //true

每一类装箱对象皆有私有的
Class 属性,这些属性可以用
Object.prototype.toString 猎取:

var symbolObject = Object(Symbol("a"));

console.log(Object.prototype.toString.call(symbolObject));
>> [object Symbol]

6.5、拆箱转换

拆箱(unboxing):是将援用范例转换为值范例

6.5.1、在 JavaScript 规范中,划定了 ToPrimitive 函数,它是对象范例到基本范例的转换

toPrimitive(input, preferedType)

input是输入的值,preferedType是希冀转换的范例,它可所以字符串,也可所以数字。

inputTypeResult
Undefinedinput argument
Nullinput argument
Booleaninput argument
Numberinput argument
Stringinput argument
Object疏忽 第二个参数 hint PreferredType 直接挪用内置要领 [[DefaultValue]]

6.5.2、假如转换的范例是number,会实行以下步骤:参考博客

  1. 假如input是原始值,直接返回这个值;
  2. 不然,假如input是对象,挪用input.valueOf(),假如效果是原始值,返回效果;
  3. 不然,挪用input.toString()。假如效果是原始值,返回效果;
  4. 不然,抛出毛病。

6.5.3、假如转换的范例是String,2和3会交流实行,即先实行toString()要领。

例子1:先将两个操纵数转换为string,然后举行拼接

[] + []
>> ""

[] -----> ''
[] -----> ''

[] + [] = ''

例子2:先将两个操纵数转换为string,然后举行拼接

[] + {}
>> "[object Object]"

// 诠释
[] -----> ''
{} -----> '[object Object]'

[] + {} = '[object Object]'

例子3:js诠释器会将开首的 {} 看做一个代码块,而不是一个js对象

{} + []
>> 0

// 真正介入运算的是 + []
// {} + [] 等价于 + []

7、范例范例

  • List 和 Record: 用于形貌函数传参历程。
  • Set:主要用于诠释字符集等。
  • Completion Record:用于形貌非常、跳出等语句实行历程。
  • Reference:用于形貌对象属性接见、delete 等。
  • Property Descriptor:用于形貌对象的属性。
  • Lexical Environment 和 Environment Record:用于形貌变量和作用域。
  • Data Block:用于形貌二进制数据。

8、补充浏览

typeof 的运算效果,与运行时范例的划定有许多不一致的处所(typeof 的设想是有缺点的)

《重学前端进修笔记(六)--JavaScript范例有哪些你不知道的细节?》

个人总结

在整顿学问点的时刻,我就发明,我多是真的划水酱_(:3」∠)_,内里大部分的东西很隐约,有点都不清不楚的,另有的没有听过,看来要好好打打基本了,如今前端的生长过于太快了,而本身的基本又不稳固,能随着winter进修是我的荣幸,不过在这里要谢谢一个大佬的引荐,stormzhang,民众号也是这个,我的进修模范来的,哈哈哈哈哈。

    原文作者:凯小默
    原文地址: https://segmentfault.com/a/1190000019034540
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞