数据类型的认识
/* 九大数据类型
* 基本数据类型(原始值类型):
number NaN、Infinity
string 单引号、双引号、反引号包起来的内容
boolean true、false
null
undefined
symbol 创建唯一值
bigint
* 引用数据类型
object
{} 普通对象
[] 数组对象
/^$/ 正则对象
Math 数学方法对象
Data 日期对象
arguments 类数组对象
实例对象
...
function
*/
// NaN : not a number 不是一个有效数字,但是它属于number类型
// console.log(typeof NaN) => 'number'
// NaN 跟任何其他值都不相等,包括它自己
// 检测一个值是否为有效数字:isNaN() true为非有效数字,false为有效数字
// if(isNaN(n)) {
// 条件成立:证明 n 不是一个有效数字
// }
// console.log(isNaN(NaN)) // => true
// Object.is([val1], [val2]):检测两个值是否相等
console.log(Object.is({}, {})); // =>false,因为地址不一样,特别的,检测NaN与NaN是否相等结果为 true
console.log(Object.is(NaN, NaN)) // =>true,特别的用Object.is()检测NaN跟NaN是一样的
console.log(Object.is(Symbol(1),Symbol(1))); // => false
console.log(Number.MAX_SAFE_INTEGER); // js中最大的安全数,超过这个值的,需要用bigint处理(在超大值后面加一个n就是bigint类型)
console.log(typeof 987416874615165549641n); // =>'bigint'
// 练习题1
let res = parseFloat('left: 200px'); // NaN
if(res === 200) {
alert(200);
}else if(res === NaN) { // NaN 跟任何值都不相等
alert(NaN);
}else if(typeof res === 'number') { // NaN 是number类型
alert('number'); // =>弹出这个
} else {
alert('Invalid Number')
}
// => 答案:'number
// ========== 为啥分为两大类型(两大类型的区别)?========
/*
JS代码可以运行的环境:
浏览器(引擎/内核)
node.js
webview
...
JS代码想要被执行,首先得先有一个环境
浏览器之所有能够运行代码,是因为提供了一个供代码运行的环境 =>栈内存 ECStack(执行环境栈)
=> 栈内存:计算机中分配出来的一块内存
代码执行分为:全局代码、函数中的代码、私有块中的代码...
不同环境下的代码执行都有自己的上下文(执行环境)
------------------------------------------------------------
EC(G)全集执行上下文 global:全局变量、方法存在的环境(类似于各国人民生活在各自国家)
VO(G)全局变量对象:代码在当前上下文中执行的时候,创建的变量总会存储在当前上下文中指定的变量对象中,所以变量对象就是用来存储当前上下文中 创建 的变量的
var a = 13;
// =等号赋值的详细步骤:
1、创建一个值 12,把它存储起来(基本类型值是直接存储在内存中的)
2、声明一个变量,把它村吃到当前上下文所属的变量对象VO中
3、最后将二者进行关联(定义)
var a; 声明变量,但是此时并没有赋值,所以是未定义,默认值是undefined
一个变量只能关联一个值,但是一个值可能被多个变量关联
===========================================================
如果是应用类型值:
1、不会直接存储在栈内存中,而是重新开辟一个堆内存(也是计算机内存中分配的空间),用来存储该值的键值对,每一个堆内存都有一个16进制的地址
2、在堆内存中分别存储键值对
3、把16进制地址存放到栈内存中,跟变量进行关联
*/
var a = {
n: 12
};
var b = a;
b.n = 13;
console.log(a.n); // => 13
// ----------练习题-------------
var a = {},b = '0', c = 0;
a[b] = '测试';
a[c] = '改变';
console.log(a[b]); // => "改变"
/* var a = {}, b = Symbol('1'), c = Symbol(1);
a[b] = '测试';
b[c] = '改变';
console.log(a[b]); // =>"测试" 因为Symbol是创建唯一值 */
/* var a = {}, b = {n:'1'}, c = {n: 2};
a[b] = '测试';
a[c] = '改变';
console.log(a[b]); // =>"改变" 引用值作为属性名会默认代用toString方法,被转为 "[object object]" */
var a = {n:1};
var b = a;
a.x = a = {n: 2};
console.log(a.x); // => undefined
console.log(b); // => {n:1,x: {n: 2}}
// => 这个题的注意点:
// 1、连等操作是从右往左赋值
// 2、成员访问.比赋值=的优先级高
var x = [12,31];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y); // =>[100, 200]
}
fn(x);
console.log(x); // =>[100,31]
// 倒计时
/*
思路:手动给定一个日期(时间)targetTime,从服务器获取服务器时间,oldTime(只获取一次)
隔一秒就计算这两个时间的差值,判断其差值是否为0,如果为0则说明倒计时结束,否则继续计算
技术:ajax、setInterval
*/
let oldTime;
let targetTime = '2020/10/12 17:30:00';
let xhr = new XMLHttpRequest();
xhr.open('get', '../js/data.json', false);
xhr.onreadystatechange = function() {
// console.log(xhr)
if(xhr.readyState == 4 && xhr.status == 200) {
oldTime = new Date(xhr.getResponseHeader('date'));
console.log(oldTime.getTime())
}
}
xhr.send(null);
let timer = null;
let old = oldTime.getTime();
let now = new Date(targetTime).getTime();
function Countdown() {
if(now - old > 0) {
let ch = now - old;
let h = Math.floor(ch/(60*1000*60));
let m = Math.floor((ch-h*60*1000*60)/ (60*1000));
let s = Math.floor((ch-h*60*1000*60 - m*60*1000)/ 1000);
console.log(h, m, s);
document.getElementById('app').innerHTML = `距离下班还有${h>10?h: '0'+h}小时${m>10?m:'0'+m}分钟${s>10?s:'0'+s}秒`
}else {
clearInterval(timer);
document.getElementById('app').innerHTML = '下班啦~';
}
old = old + 1000;
}
timer = setInterval(Countdown, 1000)