表达式、类型转换
1、Float转为bit
- 1.1 64位浮点数默认隐藏了一个1.(十进制不可能以0开始,二进制只有0,1,不以0开头,必然是1,所以隐藏了一个1)。
符号位 + 指数部分 + 小数部分 - 1.2 正0和负0
num/0 — Infinity(-Infinity)
2、Express 表达式
-
2.1 运算符优先级 优先级
表达式生成树- Member 属性访问
a.b
a[b]
foostring
super.b — 构造函数中
super[‘b’]
new.target
new Foo()
function foo(){ console.log(new.target); } new foo()
- new
new Foo
- Member 属性访问
-
2.2 Reference 引用
delete
assign -
2.3 Expressions
- call
foo()
super()
foo()[‘b’] member优先级降低
foo().b
foo()abc
- call
-
2.4 Left Handside & Right Handside (LeftHandSideExpression:ECMA-262.pdf 201 页 12.3)
a.b = c
等号坐边要求是Reference- update (UpdateExpression:ECMA-262.pdf 178 页 11.9.1)
a++
a–
–a
++a
- update (UpdateExpression:ECMA-262.pdf 178 页 11.9.1)
-
2.5 Unary 单目运算符
delete a.b
void foo() void 0; void后面跟任何值都行。
typeof a null
+a
-a
~a
!a ! 做类型转换
await乘法 * / %
加法 + -
位运算 << >>
比较 < > <= >= instanceof in
Logical 逻辑 || &&
三目
2种加法 number类型 string类型
1种乘法 number类型 -
2.6 装箱 Number String Object Symbol
Object.getPrototypeof(Object(Symbol(“1”))) == Symbol.prototype -
2.7 拆箱
1+{}
1+{valueOf(){return 2}}
1+{toString(){return 2}}
1+{valueOf(){return 2},toString(){return 2}} 先valueOf
1+{Symbol.toPrimitive{return {}},valueOf(){return 2},toString(){return 2}} 先toPrimitive ECMA-54页new Date().toJSON() ECMA-464页
-
2.7 练习
stringToNumber
进制问题
科学计数法问题NumberToString
用户权限高于前端代码的权限。
语句、对象
1、简单语句
ExpressionStatement 表达式语句
EmptyStatement
DebuggerStatement
ThrowStatement
ContinueStatement
BreakStatement
ReturnStatement
2、复合语句
BlockStatement
Iteration
while
do…while
for
for…in
for…of
标签、循环、break、continue
LabelledStatement
IterationStatement
ContinueStatement
BreakStatement
SwitchStatement
[[type]]: break continue
[[value]]:–
[[target]] : label
try…catch…finally
[[type]]: return
[[value]]:–
[[target]] : label
3、声明语句
FunctionDeclaration 函数声明
GeneratorDeclaration
AsyncFunctionDeclaration
AsyncGeneratorDeclaration
VariableStatement 变量 717页
ClassDeclaration
LexicalDeclaration
Generator跟异步编程没有关系
Runtime
- Completion Record 完成记录 语句完成的结果
[[type]]: normal break continue return throw
[[value]]:Types 7种类型,也可能是empty
[[target]] : label - Lexical Enviorment
4、JS对象类型
唯一性、标识性、行为
class base 基于类
分类&&归类
Prototype
eg: 狗咬人 – 行为改变状态
Object in JS
key — value
[[value]] get
writable set
enumerable enumerable
configurable configurable
Object API
{} . [] Object.defineProperty
Object.create Object.setPrototypeOf Object.getPrototypeOf
new class extends
new function prototype
特殊对象
function Object
使用new的对象用class实现。
按照 ECMAScript 标准,一些特定语句(statement) 必须以分号结尾。分号代表这段语句的终止。但是有时候为了方便,这些分号是有可以省略的。这种情况下解释器会自己判断语句该在哪里终止。这种行为被叫做 “自动插入分号”,简称 ASI (Automatic Semicolon Insertion) 。实际上分号并没有真的被插入,这只是个便于解释的形象说法。
var 最好写在函数内最前面或变量第一次出现的地方
/**
作业就做了一个
* 将数字的字符串形式转为Number类型
* @param {*} string 数字的字符串表示
* @param {*} x 进制(二进制、8进制、十进制、16进制)
*
* 0b
* 0
* 0x
*
* 这里不考虑进制的前缀
*/
function convertStringToNumber(string, x) {
string = string.toLowerCase();//全部转为小写
if (x === 16) {//十六进制
return hexadecimal(string)
}
return notHexadecimal(string, x) //2 8 10 进制
}
/**
* 科学计数法
* @param {*} string
*/
function scientificCounting(string) {
let chars = string.split('e'); //科学计数法被分为2部分
let jishu = notHexadecimal(chars[0], 10);//基数部分
console.log(chars[1][0]);
let zhishu = 0;
if (chars[1][0] === '+') {
zhishu = index(chars[1].replace(chars[1][0], ''), '+')
} else if (chars[1][0] === '-') {
zhishu = index(chars[1].replace(chars[1][0], ''), '-')
} else {
zhishu = index(chars[1], '+')
}
console.log(zhishu);
return jishu*zhishu
}
/**
* 科学计数法的指数部分
* @param {*} num
* @param {*} type
*/
function index(num, type) {
let len = notHexadecimal(num);//指数部分 转成10进制
let number = 1;
for (let i = 0; i < len; i++) {
if (type === '+') {
number *= 10
} else {
number /= 10
}
}
return number
}
/**
* 十六进制的转换
* @param {*} string
*/
function hexadecimal(string) {
if (!/^[0123456789abcdef]*$/.test(string)) return NaN
let chars = string.split('');
let charNumber = {
a: '10',
b: '11',
c: '12',
d: '13',
e: '14',
f: '15'
}
let number = 0;
let i = 0;
// console.log('chars',chars);
while (i < chars.length && chars[i] !== '.') {
number = number * 16;
if (charNumber[chars[i]]) {
chars[i] = charNumber[chars[i]]
}
// console.log(chars[i]);
number += notHexadecimal(chars[i], 10)
i++
}
if (chars[i] === '.') {
i++
}
let fraction = 1;
while (i < chars.length) {
fraction = fraction / 16;
if (charNumber[chars[i]]) {
chars[i] = charNumber[chars[i]]
}
number += notHexadecimal(chars[i], 10)
i++
}
return number;
}
/**
* 2 8 10 进制的转换
* @param {*} string
* @param {*} x 默认10进制
*/
function notHexadecimal(string, x = 10) {
if (x === 2) {
if (!/^[01]*$/.test(string)) return NaN
}
if (x === 8) {
if (!/^[01234567]*$/.test(string)) return NaN
}
if (x === 10) {
let isScientificCounting = string.match(/e/g);
//有一个字母e 不能再开头和结尾
if (isScientificCounting && isScientificCounting.length === 1 && string[0] !== 'e' && string[string.length - 1] !== 'e') {
return scientificCounting(string)
}
if (!/^[0123456789]*$/.test(string)) return NaN;
}
let chars = string.split('');
let number = 0;
let i = 0;
while (i < chars.length && chars[i] !== '.') {
number = number * x;
number += chars[i].codePointAt(0) - '0'.codePointAt(0)
i++
}
if (chars[i] === '.') {
i++
}
let fraction = 1;
while (i < chars.length) {
fraction = fraction / x;
number += (chars[i].codePointAt(0) - '0'.codePointAt(0)) * fraction
i++
}
return number;
}
// console.log(convertStringToNumber('050',10)); //50
// console.log(convertStringToNumber('050')); // 50
// console.log(convertStringToNumber('010',2)); //2
// console.log(convertStringToNumber('020',2)); // NaN
// console.log(convertStringToNumber('010',8)); //8
// console.log(convertStringToNumber('090',8)); // NaN
// console.log(convertStringToNumber('010',16)) //16
// console.log(convertStringToNumber('011',16)) //17
// console.log(convertStringToNumber('00a',16)) //10
// console.log(convertStringToNumber('00b',16)) //11
// console.log(convertStringToNumber('00c',16)) //12
// console.log(convertStringToNumber('00d',16)) //13
// console.log(convertStringToNumber('00e',16)) // 14
// console.log(convertStringToNumber('00f',16)) //15
// console.log(convertStringToNumber('01A',16)) //26
// console.log(convertStringToNumber('0ab',16)) //171
// console.log(convertStringToNumber('12e5', 10)) //1200000
// console.log(convertStringToNumber('12e+5', 10))//1200000
console.log(convertStringToNumber('12e-5', 10))