问题回顾
-
'a'-'a' NaN ==字符串转化为数NaN 转化为布尔 空0 非空1==
-
==''-'' 0==
-
null == undefined true
-
null === undefined false null object undefined undefined
console.log('aa' == true) //false console.log('true' == true) //false console.log('1' == true) //true //任何值和布尔等于 toNumber(boolean) //判断闰年 (x % 400 == 0) ||((x % 4 == 0) && (x % 100 != 0)) //判断100以内质数 (x != 2 && x % 2 == 0)||(x != 3 && x % 3 == 0)||(x != 5 && x % 5 == 0)||(x != 7 && x % 7 == 0) NaN = 888 undefined = 999 //可以赋值 但值不变
Equality Comparison
-
x==y
-
‘aa’==3 false aa转换成NaN
- asi auto semicolon insert
- 当一行的第一个字符是+ - / [ ( 这几个符号时 他前面一行必须加分号
- 前置分号 foo ;(2+3)
变量声明及赋值语句
-
变量名不能包含空格 变量名不能以数字开头 不能包含标点符号 可以包含$和_
-
function 的类型为function
console.log
获取console 变量的log属性
-
Math.trunc()
Math.floor()
Math.ceil()
Math.max(1,3,4)
Math.round() 四舍五入
-
confirm() 返回boolean prompt('您的年龄?',"28")
-
alert()
var x = +prompt()
//将string 转换为 number
var a = 1,b=2,c=3;
var z=(a+1,b+2,a+b)
z=3
-
Number() 把参数转换为数字并返回
null 0
undefined NaN
'' 0
'FADS' NaN
console.log(a) //3.14 console.log(typeof (a)) //string -
isNaN 是否是一个数值类型的值/不能被转换为数值
is Not a Number
‘fasa’ true
NaN true
‘ ’ false
Number.isNaN()
是否是NaN这个值
整数在计算机中的表示
-
方便计算减法
5 - 3 = 5 + (-3)
0101
1101
0010
-
-99 怎么表示 2 ^31^-99 写成2进制 前面加1即可 2 ^31^-1-99 +1 取反加一
-
000 +8 =8 001+ 7 =8 010 +6 = 8
位运算符
-
只支持整数 先被转换为32位整数
- 小数会舍掉小数部分
- 超过32位 会保留右边32位
a|b 每一位对齐 或运算 只支持整数 转换成32位数 会把小数去掉 保留右边32个比特
a&b
~a 取反 ==符号位也取反==
a^b 异或 相同为0 不同为1
a >> 2 保留符号位
a << 2
a >>> 2 (不保留符号位)
0b 二进制
a.toString(2) 数字转化为二进制
0x hex
0o 八进制
任何数与自己按位异或都得到0
任何数与0按位异或都将得到自身
2147483649.5|0 取整
0开头的数是八进制
a = 2147483647
console.log(a.toString(2))
//1111111111111111111111111111111
c = 2147483648
console.log(c | 0)
//- 2147483648
a = -5
console.log(a >> 2)
// -2
console.log(a >> 3)
// -1
console.log(a >> 32)
// -5 a>>32%32
console.log(a >> 35)
// -3 a>>35%32
console.log(a >>> 3)
//536870911
let a = 'aAcd'
console.log(a.charCodeAt(0))
//97
console.log(a.charCodeAt(1))
//65
continue 跳出循环体 进行下一次循环
for(fad;fa;跳到这里)
c++ 会改变c的类型 转换成数值类型
c+=1 不转换类型
parseInt('99 fafsdas',16) 153 转换为16进制
switch语句
switch (4) {
case 1:
console.log('a')
break
default:
console.log('d')
case 2:
console.log('b')
break
case 3:
console.log('c')
break
}
// d
// b
switch (2) {
case 1:
console.log('a')
break
case '2':
console.log('b')
break
case 3:
console.log('c')
break
default:
console.log('d')
}
// d 数字2和字符串2 用的是===
牛顿法求根
x^2^= n 即 f(x) = x^2^ - n
当x= x0 时 切线斜率 k = f(‘x0) =2x0
y = x0^2^ - n
k =( x0^2^ - n ) / ( x0 - x1 )=2x0
x1 = (x0^2^ + n) / 2x0
通过不断迭代逼近根
//使用牛顿法实现平方根的计算
function sqrt(n) {
var r = n
//i是迭代次数 精确度
for (var i = 0; i < 10; i++) {
r = (r * r + n) / (2 * r)
}
return r
}
console.log(sqrt(20))
向下取整
var mySqrt = function(x) {
var tmp = x;
while (x * x > tmp)
x = ((x + tmp / x) / 2) | 0;
return x;
};
最大公约数
//求最大公约数 辗转相除法
function largestCommonFactor(m, n) {
while (m !== n) {
if (m < n) {
var t = m
m = n
n = t
}
m = m - n
}
return m
}
function largestCommonFactor(m, n) {
let t = 1;
while (t != 0) {
t = m % n
m = n
n = t
}
return m
}
函数声明
var square = function (x) {
return x * x;
}
//等号右面是一个表达式 有求值结果 求值结果就是函数自己
console.log(square(12))
var power = function (base, exponent) {
var result = 1
for (var count = 0; count < exponent; count++)
result *= base;
return result
}
console.log(power(2, 10))
var a = function() {
console.log(x) //这里访问了全局的x
}
var a = function() {
x = 10
console.log(x) //这里访问了局部的x 屏蔽全局的x
}
-
return 后面没有表达式 返回undefined
-
result 变量在函数每次调用时重新创建
-
函数局部性 仅仅对参数和函数内部var定义的变量生效
-
判断2的方 2方2进制形如 10 100 1000 n&(n-1)
水仙花数
//水仙花数 //求位宽 var digitWidth = function (n) { let width = 0 do { n = (n - n % 10) / 10 width++ } while (n != 0) return width } //求a的n次方 var power = function (a, n) { var result = 1 for (var i = 0; i < n; i++) { result *= a } return result } var isNarcissistic = function (n) { var width = digitWidth(n) var sum = 0 var t = n do { var digit = t % 10 sum += power(digit, width) t = (t - digit) / 10 } while (t != 0) return (sum == n) ? true : false } //求1000以内的水仙花数 for (var i = 1; i < 1000; i++) { if (isNarcissistic(i)) { console.log(i) } }var x = 155 digitWidth(x)//这里没有传递x进去 传递的是x的值155 //3 //x不变仍未155var isPrime = function (n) { let a = Math.sqrt(n) for (i = 2; i <= a; i++) { if (n % i == 0) { return false } } return true } //素数两性定理:大于3的素数只分布在6n+1和6n-1两数列中 var isPrime = function (n) { if (n < 2) { return false } if (n == 2 || n == 3) { return true } if (n % 2 == 0) { return false } if (n % 6 !== 5 && n % 6 !== 1) { return false } let sqrt_n = Math.sqrt(n) for (let i = 3; i <= sqrt_n; i += 2) { if (n % i == 0) { return false } } return true } var countPrimes = function (n) { var count = 0 for (let i = 2; i < n; i++) { if (isPrime(i)) { count++ } } return count } //埃拉托斯特尼筛法 画图筛选去掉从2开始 找素数,先留2 然后2*2 去掉4 2*2+2去掉6 8,10 再找3 留3 去掉3*3 3*3+3 //核心就是去掉2,3,5,7的倍数 //let signs = new Uint8Array(n); //创建长度为n的数组 并且用0填充 var countPrimes = function (n) { let count = 0; let signs = new Uint8Array(n); for (let i = 2; i < n; i++) { if (!signs[i - 1]) { count++; for (let j = i * i; j <= n; j += i) { signs[j - 1] = true; } } } return count; };//判断是否为2的幂 var isPowerOfTwo = function(n) { if(n <= 0) { return false } return (n & (n - 1)) == 0 }; //考虑2进制 //判断是否为2的幂 return 1162261467 % n == 0 // 3的19次方 整形能表示的最大的3的幂 只能模3为0回文数
判断完全平方数
//二分法
var isPerfectSquare = function(num) {
if(num == 1) return num
let low = 1
let high = num
let middle
while(high - low > 1) {
middle = (high + low) / 2 | 0
if(middle * middle == num){
return true
}
else {
(middle * middle > num)? high = middle : low = middle
}
}
return false
};
七进制
var convertToBase7 = function(num) {
let sum = 0
let positive = 1
let base = 1
if (num < 0) {
positive = 0
num = -num
}
while(num > 0){
digit = num % 7
sum += digit * base
num = (num - digit) / 7
base *= 10
}
return positive ? sum : -sum
};
判断weekday(某年某月第一天是星期几)
function isLeapYear(year) {
if (year % 400 == 0) {
return true
}
if (year % 100 == 0) {
return false
}
if (year % 4 == 0) {
return true
}
return false
}
function weekday(year, month) {
//公元元年是1年
var sum = 0
var y = year - 1
sum = y * 365 + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400)
for (var m = 1; m < month; m++) {
sum += getDayOfMonth(m, year)
}
return (sum + 1) % 7
}
function getDayOfMonth(month, year) {
if (m == 2) {
if (isLeapYear(y)) {
return 29
} else {
return 28
}
} else {
switch (m) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12: return 31
default: return 30
}
}
}
作用域
var x = 5
var a = function () {
x = x + 5
return x
}
a()
console.log(x)
// 10
var x = 5
var a = function () {
x = x + 5
return x
}
a()
console.log(a())
console.log(x)
//15
- 对于任何一个变量的访问,都从代码中书写该变量的位置开始查找,逐级往上层作用域查找。
function foo() {
var a = 8
bar()
}
var a = 9
function bar() {
console.log(a)
}
foo()
// 9 从bar定义的位置看
- var只有函数作用域 单纯的{}括起来的不能算作用域 没有块级作用域
- let 声明的变量有块级作用域 es6
声明提升 hoist
function f() {
var x = 2
var digit//提升到了这里
var i //提升了
var x
x = 2
for(var i = 1;i < 10;i++) {
var digit = 5
// var定义的会提升 指定以一次 digit =5
}
}
function f () {
console.log(a)
//undefined
var a = 8
console.log(a)
//8
}
function f() {
i = 4
console.log(i)
for (var j = 0; j < 1; j++) {
var i = i + 1
}
console.log(i)
}
f()
// 4 5
function f() {
for (var i = 0; i < 4; i++) {
}
console.log(i)
}
f()
// 4
//let 声明的标量是块级作用域
var a = 8
if (true) {
let a = 9
a = 10
console.log(a)
//10
}
console.log(a)
//8
var a = 8
if (true) {
a = 10
console.log(a)
//10
}
console.log(a)
//10
let a = 8
if (true) {
var a = 9
a = 10
console.log(a)
}
console.log(a)
//会报错 let声明的变量不能再var
function f() { //Temper Dead Zone TDZ
console.log(a)
let a = 8
console.log(a)
}
//报错 不能在初始化变量前访问他
var a = 8
console.log(a * a)
var a = 8
console.log(a * a)
var a = 8
console.log(a * a)
// 64 64 64
let a = 8
console.log(a * a)
let a = 8
console.log(a * a)
//报错
a = function () {
return 8
}
console.log(Math.max(a, 9))
// NaN a是函数不是返回值 函数可以作为值被传递
a = function () {
return 8
}
console.log(Math.max(a(), 9))
//9
函数声明
var a = function(){
//表达式 表达式的求值结果是函数
}
function a {
//语句 没有求值结果
// 定义变量a 变量a指向一个函数
//这种方式定义的方法可以晚于调用 不在正常控制 流中
}
var a = function(){return 8}()
// a = 8 表达式后面() 调用这个函数
//函数声明不要写在if里 如果写 写成这种 不要写成直接声明的
if(true){
a = function(){
}
}
var a = 8
function a(){
return 0
}
//a ???
// var a 提升
// function a(){ 提升
// return 0
// }
// a = 8
// a为8
var b = function c() {
//c只能在这里使用 代表函数自己 递归
}
// 在这里只能使用 b
调用栈
- 计算机存储上下文(执行环境的地方叫做调用栈) 函数执行完跳到那里去 2.函数间的关系
可选参数值
- 传的参数多了,会被忽略,传的参数少了会被分配undefined
function power(base, exponent) {
if (exponent == undefined)
exponent = 2;
var result = 1;
for (var count = 0; count < exponent; count++)
result *= base;
return result;
}
- 所有参数被放在arguments 这个只能在函数内部访问的特殊变量中。arguments[0]表示第一个参数,arguements.length 表示实际传入的参数个数,它是一个类数组对象,array like object