You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If preferredType is number, then (我将 spec 中的这一步和下一步对调了,便于记忆)
Let methodNames be « "valueOf", "toString" ».
Else,
Let methodNames be « "toString", "valueOf" ».
For each element name of methodNames, do
Let method be ? Get(o, name). (示例 8)
If IsCallable(method) is true, then (示例 7 中这里是 false)
Let result be ? Call(method, o). (示例 6.a)
If Type(result) is not Object, return result. (示例 6.b)
Throw a TypeError exception. (示例 7)
// 示例 1// 1. 调用ToNumber(arg), 参数是一个Object类型// 2. 调用ToPrimitive(arg, number), 虽然定义了Symbol.toPrimitive,但其值是undefined// 3. 调用OrdinaryToPrimitive(arg, number),先调用valueOf(),结果是对象本身,忽略;// 再调用toString(),结果是"[object Object]",返回该字符串。// 4. 调用ToNumber("[object Object]")Number({// 或者这个属性不存在[Symbol.toPrimitive]: undefined,});// NaNNumber({[Symbol.toPrimitive]: null,});// 结果同上,原因参考上面// 示例 2Number({[Symbol.toPrimitive]: ()=>{return123;},});// 123// 示例 3Number({[Symbol.toPrimitive]: 123,// Symbol.toPrimitive属性不是一个函数导致TypeError});// TypeError: xxx is not a function// 示例 4Number({[Symbol.toPrimitive]: (hint)=>{if(hint==="string"){return"abc";}else{// hint is "number" or "default"return123;}},});// 123. 如果是String(...), 结果就是abc// 示例 5Number({[Symbol.toPrimitive]: ()=>{return{};// 返回值不是原始类型导致TypeError},});// TypeError: Cannot convert object to primitive value// 示例 6// 123. 原因:OrdinaryToPrimitive先调用valueOf,结果是一个数组,它是Object类型,忽略;// 再调用toString,结果是" 123 ",返回该字符串,再调用ToNumber,最终结果是123Number({// 6.avalueOf(){return[];},// 6.btoString(){return" 123 ";},});// 123// 示例 7// TypeError. 原因:valueOf和toString都不是函数,会到最后一步Number({valueOf: 123,toString: "abc",});// TypeError: Cannot convert object to primitive value// 示例 8// TypeError. 原因:这个对象没有valueOf和toString属性,会到最后一步Number(Object.create(null));// TypeError: Cannot convert object to primitive value
String
以String(value)方式被调用时 (前面没有new):
注意与`${value}`, value + ""之间的比较,三者异同点请看后面
如果参数不存在,结果是""
If value is not present, let s be empty string.
Else,
If NewTarget is undefined and Type(value) is Symbol, return SymbolDescriptiveString(value). (如果 Description 是undefined,结果是"Symbol()",否则是"Symbol(" + value.[[Description]] + ")")
If Type(x) is Number and Type(y) is String, return x == ToNumber(y).
If Type(x) is String and Type(y) is Number, return ToNumber(x) == y.
If Type(x) is either Number, String, or Symbol and Type(y) is Object, return x == ? ToPrimitive(y).
If Type(x) is Object and Type(y) is either Number, String, or Symbol, return ? ToPrimitive(x) == y.
Return false.
===和!==会用到 Strict Equality Comparison (抽象运算,简化)
If Type(x) is different from Type(y), return false.
If Type(x) is Number, then
If x is NaN, return false.
If y is NaN, return false.
If x is +0 and y is -0, return true.
If x is -0 and y is +0, return true.
If x is the same as y, return true. (注意进制不同,比如0xa和10是一样的)
Return false.
Return SameValueNonNumber(lval, rval).
SameValueNonNumber(x, y) (抽象运算)
Assert: Type(x) is not Number.
Assert: Type(x) is the same as Type(y).
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Boolean, then
If x and y are both true or both false, return true; otherwise, return false.
If Type(x) is String, then
If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.
If Type(x) is Symbol, then
If x and y are the same Symbol value, return true; otherwise, return false. (注意 Symbol 类型值的唯一性)
If x and y are the same Object value, return true. Otherwise, return false.
如错误或者不严谨的地方,请斧正,感谢。
Chapter 1. Types, type conversion, operators
In JavaScript, variables don't have types, but values do.
Types
undefined
null
true
,false
{}
[]
function foo() {}
new Set()
new Map()
new Error('msg')
new Date()
JSON.stringify
JSON.floor
/^foo$/gmi
, g: global, m: multiline, i: case-insensitivetypeof
operator检查值的类型,结果是字符串。
null
.typeof {}
,typeof []
. 又比如typeof JSON
,typeof Math
, 不能用作函数.typeof function(){}
. 又比如typeof String
,typeof Object
,typeof Array
,typeof Function
, 能用作函数.undefined
,可以用foo === undefined
null
,可以用foo === null
undefined
或null
,可以用foo == null
foo === true
或foo === false
typeof foo == "number"
typeof foo == "string"
typeof
对 Object 的判断很粗放),可以用Object.prototype.toString.call(foo).slice(8, -1).toLowerCase()
Array.isArray(foo)
typeof foo == "function"
Type conversion
Boolean
以
Boolean(value)
方式被调用时 (前面没有new
)ToBoolean(argument) (抽象运算,运算结果是
true
或者false
)false
.false
.0
,-0
, orNaN
, returnfalse
; otherwise returntrue
.""
(空字符串), returnfalse
; otherwise returntrue
.true
.true
.Number
以
Number(value)
方式被调用时 (前面没有new
)ToNumber(argument) (抽象运算,运算结果是 Number 类型值或者 Exception)
NaN
.0
.NaN
会更合适。true
, return1
. If argument isfalse
, return0
.0
, 如果看起来是数字(可能是二进制 Binary,八进制 Octal,十六进制 heXadecimal),return 十进制 decimal 数字 (输入是科学记数法的字符串,输出可能是十进制数字,也可能是科学计数法数字),否则 returnNaN
."-0"
->-0
.1. Let primValue be ? ToPrimitive(argument, number). (指定了 preferredType)
2. Return ? ToNumber(primValue).
ToPrimitive(input[, preferredType]) (抽象运算)
Symbol.toPrimitive
属性的值,如果属性不存在或属性值是undefined
或null
,返回undefined
,见示例 1;如果是函数,返回函数,见示例 2;否则抛出 TypeError,见示例 3)OrdinaryToPrimitive(o, preferredType) (抽象运算)
String
以
String(value)
方式被调用时 (前面没有new
):undefined
,结果是"Symbol()"
,否则是"Symbol(" + value.[[Description]] + ")"
)ToString(argument) (抽象运算,运算结果是 String 类型值或者 Exception)
"undefined"
."null"
.true
, return"true"
. If argument isfalse
, return"false"
.-0
->"0"
1. Let primValue be ? ToPrimitive(argument, string). (指定了 preferredType)
2. Return ? ToString(primValue).
Logical operators (与 ToBoolean 相关)
&&
(logical and, 逻辑与),||
(logical or, 逻辑或)leftOperand && rightOperand
或leftOperand || rightOperand
!
(logical not, 逻辑非)!operand
Conditional operator (与 ToBoolean 相关)
? :
ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
Binary arithmetic operators (主要与 ToNumber 有关)
+
(addition),-
(subtraction),*
(multiplication),/
(division),%
(remainder)会调用:ApplyStringOrNumericBinaryOperator(lval, opText, rval) (抽象运算,简化)
Unary arithmetic operators (与 ToNumber 有关)
++
(increment operator, 分为 postfix increment operator 和 prefix increment operator),--
(decrement operator,分为 postfix 和 prefix)以 postfix increment operator 为例:
LeftHandSideExpression++
Relational operators (主要与 ToNumber 有关)
<
(less than),<=
(less than or equals),>
(greater than),>=
(greater than or equals)会调用:Abstract Relational Comparison (抽象运算,简化)
undefined
视为false
)Equality operators
==
(double equals),!=
,===
(triple equals),!==
==
和!=
会用到 Abstract Equality Comparison (抽象运算,简化)===
和!==
会用到 Strict Equality Comparison (抽象运算,简化)0xa
和10
是一样的)SameValueNonNumber(x, y) (抽象运算)
SameValue(x, y) (抽象运算,
Object.is(x, y)
会用到它)SameValueZero(x, y) (抽象运算,
String.prototype.includes
,Array.prototype.includes
,Map
,Set
会用到它)The text was updated successfully, but these errors were encountered: