一、JavaScript组成部分
1、ECMAScript:
ECMAScript是js语言的标准。
2、DOM :
document object model (文档对象模型)
3、BOM :
browser object model (浏览器对象模型)
详细页面点击原生js操作DOM。
二、数据类型
js有6种数据类型,4种基本数据类型、Object和function类型。六种数据类型,typeof返回的也是6个字符串:number、string、boolean、undefined、object、function。
1、基本【简单】数据类型
五种:字符串(String)数字(number)空(Null)未定义(undefined)布尔(Boolean)
1.1、数字number
var age = 3;
var PI = 3.14;
console.log(age,PI);//3 3.14
console.log(age+PI);//6.140000000000001
console.log(typeof age); // number
console.log(typeof(PI)); // number
//注意下面:
var a = 0.1;
var b = 0.2;
console.log(a + b);//0.30000000000000004
1.1.1、随机数
- 1.生成一个介于某两个值之间的随机数
/**
* 生成一个介于某两个值之间的随机数
* @param min 最小值
* @param max 最大值
* @returns {number} 生成的最技术
*/
var getRandom = function(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
- 2.随机生成n个指定范围内例如【2到32】之间的不重复的数字
function randomRange(min, max,n) {
const arr = [];
for (let i = 0 ; i < n; i++) {
const value = Math.floor(Math.random()*(max - min + 1) + min);
if (arr.indexOf(value) < 0 ) {
arr.push(value);
} else {
i--;
}
}
return arr
};
1.2、字符串
var str = '3456';
var str2 = "welcome to js";
console.log(typeof str2);//string
// 字符串.length
// 字符串[下标] 字符串.charAt(下标)
// 字符串下标从0开始,最后一个下标是长度-1
// 字符串的下标
console.log(str2[0])//w
console.log(str2[8])//t
console.log(str2[12])//s
console.log(str2[str2.length - 1])//s
var str = String("1324565789");
var st = new String("你好,世界。");
console.log(typeof str);//string
console.log(typeof st);//object
1.3、Boolean
var n = false;
console.log(typeof n);// boolean
if (n) {
console.log('真');
} else {
console.log('假');//假
}
1.4、null
用处:如果将来准备存储一个对象,我们可以先给它一个值叫null。
var n = null; // 没有值或者暂时没有值
console.log(typeof n); // object
console.log(number(n));
//Uncaught ReferenceError: number is not defined
1.5、undrfined
var a;
console.log(a);//undefined
console.log(typeof a);//undefine
1.6、Symbol [ES新]
1.7、BigInt[ES新]
2、复杂【引用】数据类型
复杂数据类型,由简单数据类型构成。
2.1、object
var obj = {
name: '张三',
age: 3,
job: function() {
console.log('前端开发');
}
}
console.log(typeof obj);//object
2.2、函数类型
var fn = function() {};
console.log(typeof fn); // function
2.2.1、 数组类型
js的数组和java的数组存储形式不太一样。java数组里存储的数据类型是同一类型的数据,js的数组存储的数据可以是不同类型的数据。
var arr = [true, 'abc', 123, {}, [], function() {}];
console.log(typeof arr[0]);//boolean
console.log(typeof arr[1]);//string
console.log(typeof arr[2]);//number
console.log(typeof arr[3]);//object
console.log(typeof arr[4]);//object
console.log(typeof arr[5]);//function
console.log(typeof arr);//object
2.2.2、 时间Date类型
1.Date.now()
返回自 1970-1-1 00:00:00 UTC(世界标准时间)至今所经过的毫秒数。
2.Date.parse()
解析一个表示日期的字符串,并返回从 1970-1-1 00:00:00 所经过的毫秒数。
注意: 由于浏览器差异和不一致,强烈建议不要使用Date.parse解析字符串。
隐式调用:new Date(dateString).getTime()
3.Date.UTC()
接受和构造函数最长形式的参数相同的参数(从2到7),并返回从 1970-01-01 00:00:00 UTC 开始所经过的毫秒数。
//获取自 Unix 起始时间以来经过的秒数
var seconds = Math.floor(Date.now() / 1000);
2.3、数据类型检查
判断数据类型:typeof(变量)
typeof,返回六个字符串:number、 string、 boolean、 object、undefined、 function
示例:
var age = 3;
var PI = 3.14;
console.log(typeof age); // number
console.log(typeof(PI)); // number
//函数类型
var fn = function() {};
console.log(typeof fn); // function
三、数据类型转换
3.1转字符串
(1)String(变量) :
可以将任何数据类型转成字符中
(2)变量.toString();
不能针对null和undefined类型
var a = 10;
console.log(String(a));//10
console.log(typeof String(a));//string
var b = 'abc';
console.log(String(b));//abc
console.log(typeof String(b));//string
var c = true;
console.log(String(c));//true
console.log(typeof String(c));//string
var n = null;
console.log(String(n));//null
console.log(typeof String(n));//string
var m = undefined;
console.log(String(m));//undefined
console.log(typeof String(m));//string
//toString()方法
console.log(a.toString());//10
console.log(b.toString());//abc
console.log(c.toString());//true
console.log(n.toString());//报错
//Uncaught TypeError: Cannot read property 'toString' of null
console.log(m.toString());//报错
//Uncaught TypeError: Cannot read property 'toString' of undefined
3.2、转数字
3.2.1、Number()
(1)Nunber(varliable); 可以转任何数据类型,只有能转成功或不能转成功之分。转成功就是数字,转不成功就是NaN
var a = 10;
console.log(Number(a));//10
console.log(typeof Number(a));//number
/**
* NaN --- not a number,但是它是数值类型
*/
var b = 'abc';
console.log(Number(b)); // NaN
console.log(typeof Number(b));//number
var c = false;
console.log(Number(c)); // true是1 false是0
console.log(typeof Number(c));//number
//特殊:null转number为0
var n = null;
console.log(Number(n)); // 0
console.log(typeof Number(n));//number
var m = undefined;
console.log(Number(m)); // NaN
console.log(typeof Number(m));//number
console.log(Number('10px'));//NaN
console.log(Number('13.34元'));//NaN
3.2.2、parseInt()
转整数;如果转不成功,则返回NaN。
console.log(parseInt('10px')); // 10
console.log(parseInt('a10px')); // NaN
console.log(parseInt('10px56c'));//10
console.log(parseInt('10.34亿'));//10
3.2.3、parseFloat()
转小数 ; 如果转不成功,则返回NaN
console.log(parseFloat('10px56c'));//10
console.log(parseFloat('10.34亿'));//10.34
console.log(parseFloat('a10.3.4亿'));//NaN
3.2.4、 NaN
注意:
- NaN同谁都不相等,包括它自己
- 任何涉及NaN的操作返回的都是NaN
- typeof查看返回的是number
console.log(NaN == NaN);//false
console.log(null == null);//true
console.log(undefined == undefined);//true
console.log('abc' - 5 + 3);//NaN
console.log(typeof NaN);//number
3.2.5、isNaN(variable)
- isNaN(variable);用于判断这个值是不是非数字,如果是数字,返回false,如果不是数字,返回true
- isNaN()不喜欢数值(包括字符串的数字),但喜欢数值类型的NaN。
console.log(isNaN('Ab'));//true
console.log(isNaN('1a'));//true
//特殊:因为null可以转为数字0
console.log(isNaN(null));//false
console.log(isNaN(function a() {}));//true
//特殊2:NaN类型是数字,但它本身不是数字
console.log(isNaN(NaN));//true
console.log(typeof(NaN));//number
四、隐式类型转换
算数运算符有:+ - * / % ++ --。
- 只要有一边是字符串,哪么另一边就转成字符串,变成字符串连接。
- 如果两边都是数字,则可以正常进行加减乘除取余运算
//情况一:运算符左边字符串的数字,右边数字。
var a = '15';
var b = 5;
//加法操作例外:字符串拼接
console.log(a + b)//155
//其他正常执行
console.log(a - b);//10
console.log(a * b);//75
console.log(a / b);//3
console.log(a % b);//0
//情况二:运算符左边数字,右边数字字符串。
//结果和情况一相同,“+”加法操作仍然是字符串拼接
var a = 15;
var b = '5';
//加法操作例外:字符串拼接
console.log(a + b);//155
//其他正常执行
console.log(a - b);//10
console.log(a * b);//75
console.log(a / b);//3
console.log(a % b);//0
五、运算符
5.1、赋值运算符
var a = 10; // 把10赋给a
a += 10; // a = a + 10,左右两边相加,然后赋给左边
5.2、比较运算符
比较运算符判断两个变量的大小,是否相等
运算符名称 | 符号 |
---|---|
大于 大于等于 | > >= |
小于 小于等于 | < <= |
等于 不等于 | = = != |
全等于 | = = = |
不全等于 | !== |
// == 相等,值是否相等,会发生类型转换
console.log(1 == '1'); // true
console.log(true == 1); // true
//特殊:
console.log(null == undefined);
// true,除此之外,它们不能和其它的值进行比较
// === 全等,值和类型都要相等才相等,不会发生类型转换
console.log(1 === '1'); // false
console.log(true === 1); // false
console.log(null === undefined); // false
console.log(null !== undefined); // true
console.log(null != undefined); // false
5.3、逻辑运算符
“与“”和“或” :连接两个或多个条件。
“非”: 为取反。
名称 | 运算符 | 说明 |
---|---|---|
与 | && | 都为真才为真 |
或 | 有一个为真就为真 | |
非 | ! | 取反 |
if (!!false) {
alert('条件成立');
}
5.3.1、短路运算
- && 和 || 也叫短路运算符
- 短路&&:
只要碰到了假值(false),就会短路,并返回该假值, 只要短路,不会继续执行后面的表达式。 - 短路||:
只要碰到了真值(true),就会短路,并返回该真值, 只要短路,不会继续执行后面的表达式。(一般用作默认值)
注意:假值有以下6个:
- null undefined NaN false 0 ’ ’
5.4、三目运算符
格式:条件 ? 代码一 : 代码二;
如果条件为真,则执行代码一,否则执行代码二
var n = 90 >= 60 ? '及格' : '不及格';
console.log(n);//及格
六、流程控制语句
6.1、if-else
条件如果只是两三个分支,就用if-else
var age = 7;
if (age >= 7) {
console.log('上学');//上学
}
6.2、switch-case-default
条件如果是三个以上的分支,建议使用switch
var n = prompt('请输入成绩');
if (isNaN(n)) {
// 不是数字
alert('哥们,请输入数字');
} else if (n < 0 || n > 100) {
// 不在0--100之间
alert('哥们,请输入0--100的数字');
} else {
// 0--100之间
switch (true) {
case n < 60:
alert('不及格');
break;
case n >= 60 && n < 70:
alert('及格');
break;
case n >= 70 && n < 80:
alert('一般');
break;
case n >= 80 && n < 90:
alert('良好');
break;
case n >= 90 && n < 100:
alert('优秀');
break;
default:
alert('满分');
}
}
7、执行上下文(Execution Context)
7.1概念:
执行上下文时是代码执行时的环境,JS代码在运行前进行编译,那么会生成两部分,一部分是可执行的代码,而另一部分则是执行上下文。
执行上下文构成
7.2 作用
用于跟踪代码运行的运行情况。执行步骤如下:
- 1.一段代码块对应一个执行上下文,被封装成函数的代码被视作一段代码块,或者“全局作用域”也被视作一段代码块。
- 2.当程序运行,进入到某段代码块时,一个新的执行上下文被创建,并被放入执行栈中。当程序运行到这段代码块结尾后,对应的执行上下文被弹出栈。
- 3.当程序在某段代码块中运行到某个点需要转到了另一个代码块时(调用了另一个函数),那么当前的可执行上下文的状态会被置为挂起,然后生成一个新的可执行上下文放入执行栈的顶部。
- 4.执行栈最顶部的可执行上下文被称为 running execution context。当顶部的可执行上下文被弹出后,上一个挂起的可执行上下文继续执行。
7.3、JavaScript引擎处理上下文
- JavaScript引擎会以什么方式去处理多个EC?
答案:堆栈。
堆栈底部永远都是全局上下文(Global Context),而顶部就是当前(活动的)执行上下文。堆栈在EC类型进入和退出上下文的时候被修改(推入或弹出)。
7.4 分类
7.4.1 全局执行上下文EC
-
1.JavaScript代码运行起来会首先进入该环境。
-
2.全局代码是在程序级处理的:例如加载外部的js文件或者本地标签内的代码,并不包括任何function体内的代码。
-
3.全局上下文只有唯一的一个,直到应用程序退出,保存在其中的所有变量和函数定义才会被销毁】
7.4.2 函数EC
当函数被调用执行时,会进入当前函数中执行代码;函数执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁。
当进入 function 函数代码(所有类型的funtions)的时候,ECStack 被压入新元素。
//在初始化(程序启动)阶段,ECStack是这样的:
ECStack = [
globalContext
];
- 1、具体的函数代码不包括内部函数(inner functions)代码
- 2、同步执行,只有栈顶的上下文处于执行中,其他上下文需要等待
- 3、函数中,遇到 return语句 能直接终止 可执行代码(Execution Code) 的执行,因此会直接将 当前EC 弹出栈(类似于数组中的 shift() 方法,因为所弹出的当前EC是ECStack[0]);
- 4、相关代码执行完以后,ECStack只会包含 全局上下文,一直到整个应用程序结束。
- 5、每次某个函数被调用,就会有个新的执行上下文为其创建,即使是调用的自身函数,也是如此
- 6、函数的执行上下文的个数没有限制
7.4.3 eval 执行上下文
7.5 执行上下文生命周期
第一阶段:EC创建阶段
- 1、创建变量对象(Variable Object)
- 2、建立作用域链
- 3、确定 this 的指向
第二阶段:EC执行阶段
- 1、变量对象转化为活动对象 (VO ----->AO)(只在函数环境下才有这个转化)
- 2、变量赋值
- 3、函数引用
- 4、执行其他代码
8、作用域
一个变量可以被定义在局部或者全局作用域中,这建立了在运行时(runtime)期间变量的访问性的不同作用域范围。 任何被定义的全局变量,意味着它需要在函数体的外部被声明,并且存活于整个运行时(runtime),并且在任何作用域中都可以被访问到。 在ES6之前,局部变量只能存在于函数体中,并且函数的每次调用它们都拥有不同的作用域范围。 局部变量只能在其被调用期的作用域范围内被赋值、检索、操纵。