原生javascript知识点
JAVASCRIPT
1.变量
1.1概念
变量源于数学,是计算机语言中存储计算结果或表示值抽象概念
计算机有个地方叫内存,变量都会将值存入到内存中,变量就是指向这个值的名字
1.2命名规则
1. 由字母数字下划线和$组成
2. 不能以数字开头
3. 严格区分大小写
4. 不能使用关键字和保留字
关键字和保留字
ECMA-262第3版描述的关键字
break | do | instanceof | typeof |
---|---|---|---|
case | else | new | var |
catch | finally | return | void |
continue | for | switch | while |
debugger* | function | this | with |
default | if | throw | delete |
in | try |
ECMA-262第3版描述的保留字
abstract | enum | int | short |
---|---|---|---|
boolean | export | interface | static |
byte | extends | long | super |
char | final | native | synchronized |
class | float | package | throws |
const | goto | private | transient |
debugger | implements | protected | volatile |
double | import | public |
ECMA-262第5版本非严格模式
class | enum | extends | super |
---|---|---|---|
const | export | import |
ECMA-262第5版严格模式
implements | package | public | interface |
---|---|---|---|
private | static | let | protected |
yield |
2.数据类型
2.1字符串string
- 概念:由零个或者多个16位Unicode字符组成的字符序列。
- 定义方式:使用单引号''和双引号""定义字符串
单双引号的特点
- 单双引号没有区别,都不解析变量
- 单双引号可以相互嵌套
- 不可以嵌套自身,除非使用转义字符\转义
// 单引号
var str1 = '老板,瓜甜吗?';
// 双引号
var str2 = "滚犊子,这是苦瓜";
// 关于单引号嵌套双引号
var str3 = '王健林说:"先定一个小目标,先赚它一个亿"';
// 双引号嵌套单引号
var str4 = "俊哥说自己很'帅',大家都笑了";
// 关于嵌套自身
var str5 = ''单引号'' // 最外层的一组单引号定义字符串,内层的一组单引号作为普通单引号字符串,为了避免语法报错和歧义,使用转义字符转义
-
特点:
1. 字符串是不可以改变的,一旦创建,值不能改变,如果改变,要先销毁原来的字符串,用新值填充
var name = '俊哥'; name += '很帅'; // 俊哥很帅
2.转为字符串
第一种方法: str.toString() 除null和undefined之外,所有的数据都可以通过 数据.toString()转为字符串 //会报错 第二种方法: String():将任何值都可以转为字符串 对象=>字符串:[Object Object] 其他数据=>原型输出
3.特殊字符串
\n 换行 \t 制表符 \r 回车 \ 斜杠(\有转义的意思,需要展示,使用\转义自身) \unnnn 16进制代码nnnn表示一个Unicode字符(n为0-F)
2.2 数值(Number)
1. 整数
// 十进制
var num1 = 12;
// 八进制(第一位必须是0)
// 0 1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 20 21 22 23 24
var num2 = 070; // 等价于 十进制56
注意:八进制在严格模式下报错
// 十六进制(第一位必须是0x)
// 0 1 2 3 4 5 6 7 8 9 a b c d e f 10
var num3 = 0xA; // 等价于 十进制10
注意:八进制和十六进制的数值最终都会转换为十进制数值进行 算数计算
2. 浮点数
var num1 = 1.1;
var num2 = 0.8;
var num3 = .4; // 不推荐
注意:
1. 0.1 + 0.2 = 0.30000000000000004
2. 0.8 - 0.2 = 0.20000000000000007
这是基于IEEE754的数值进行计算的通病,有计算损耗
所以:请不要使用浮点数进行精确计算
3. NaN(Not a Number)
概念:表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
3 - 'a' // 不知道结果,NaN
4 * 'b' // 不知道结果,NaN
5 / 'z' // 不知道结果,NaN
4 + 'x' // 结果:4x(此时+ 是连接运算符)
4. 其他数据转换为数值
-
Number转换规则
字符串=>数值 ''=>0 纯数字字符串=>原型输出(***) 普通字符串=>NaN(***) '0xf'=>15(支持十六进制字符串转换为十进制) 布尔值=>数值(***) true=>1 false=>0 数值=>数值 原型输出 null=>0(***) undefined=>NaN(***) 对象=>数值 调用对象的valueOf()方法进行检测,检测结果是NaN 继续调用对象toString()方法,再按前面的规则返回字符串值
-
parseInt转换规则
从第一个字符开始查找,直到找到第一个非法数字截止,找到的即是转换结果 'abc'=>NaN '23ab'=>23 true=>NaN null=>NaN '32.18'=>32 undefined=>NaN 特殊: '0xf'=>15(可以转换16进制) 进制之间的转换 parseInt('10',2) // 2 parseInt('10',8) // 8 parseInt('10',10) // 10 parseInt('10',16) // 16 parseInt('AF',16) // 175
-
parseFloat转换规则
从第一个字符开始查找,直到找到第一个非法字符(除数字和第一个小数点)截止,找到的即是转换结果 'abc'=>NaN '23ab'=>23 true=>NaN null=>NaN undefined=>NaN 25=>25 '32.18'=>32.18
2.3 布尔值(Boolean)
-
true:真
-
false:假
只有以下7个值转换为布尔值为假,其他为真
'' //空字符 0 0.0 NaN false null undefined
2.4 未定义(undefined)
- 未定义的变量
- 定义但是未赋值的变量
// 定义但是未赋值
var str;
console.log(str); // undefined
// 由typeof 检测未定义的变量
console.log(typeof abc); // undefined
如果不用typeof检测,直接打印输出一个未定义的变量,在JS中会直接报错
注意:两种未定义的情况
console.log(a); //如果a在整个代码中都未定义过,那么JS报错a is not defined
console.log(a); //程序都是顺序执行,虽然a还是未定义,但是整个代码中有a的存在,程序不会报错,执行出来是undefined
var a;
跟函数比较相似
浏览器在执行script代码的时候,先将script内部的函数和变量值全部"登记",然后才去执行具体的每一行代码
执行到console.log(abc)的时候,没有"登记"过abc,则abc直接报错,说没有定义该变量,而且终止了代码的执行
执行到第一个console.log(a)的时候,曾经"登记"过a变量,但是a变量在下面定义的,于是浏览器认为说a属于定义了但是未赋值的状态,就赋值为undefined, 不会报错
函数跟变量不一样的地方是:
函数提前登记之后,可以直接提前调用,但是变量值提前调用只是不报错,拿不到下面定义的值
2.5 对象(object)
-
null
console.log(typeof null);
-
array数组
var arr = ['a','b','c']; console.log(typeof arr);
-
对象
var obj = {}; console.log(typeof obj);
属性Object.keys(传入的对象); 并且以数组形式输出
var obj = {a:1,b:2,c:3}
Object.keys(obj) //['a','b','c']
2.6 函数(function)
function demo(){}console.log(typeof demo); // function
3. 运算符
3.1 算术运算符
1. 普通算数运算符: + - * / %
var num1 = 8;
var num2 = 5;
console.log(num1 + num2); // 13
console.log(num1 - num2); // 3
console.log(num1 * num2); // 40
console.log(num1 / num2); // 1.6
console.log(num1 % num2); // 3 等价于 8/5=1...3
注意:当/ % 的除数为0时,5/0 5%0 测试结果为Infinity Infinity 无穷大的意思
当/ % 的除数为0时 测试类型是 typeof(5/0) 或typeof(5%0) 为NaN
2. 特殊算数运算符: ++ --
- 认识++和--
// ++:让自身自增1
var num1 = 5;
num1++;
console.log(num1); // 6
var num2 = 8;
++num2;
console.log(9);
// --:让自身自减1
var num3 = 4;
num3--;
console.log(num3); // 3
var num4 = 2;
--num4;
console.log(num4); // 1
总结:
1.i++,i-- 是先运算在+ -
++i,--i是先+ -,再运算
2. 不管++在变量之前,还是在变量之后,都是让自身增加1
不管--在变量之前,还是在变量之后,都是让自身减小1
- 区分++/--在前和在后的区别
var num1 = 5;
// num1++:++在变量num1之后,先执行console.log,再执行自身自增1
console.log(num1++); // 5
console.log(num1); // 6
var num2 = 3;
// ++num2:++在变量num2之前,先执行自身自增1,在执行console.log
console.log(++num2); // 4
console.log(num2); // 4
// 举例
var num3 = 4;
var num4 = 8;
// 解释:num4++(++在后),num4会先和num3运算得出计算结果,然后自身再自增1为9,所以+运算的结果是12,运算结束num4的值变为9
console.log(num3 + num4++); // 12
console.log(num3,num4); // 4 9
总结:
2. ++在变量前,先自增1再运算
++在变量后,先运算再自增1
--在变量前,自减1再运算
--在变量后,先运算再自减1
==============================================
注意:这里大家会考虑,都算完了,再自减1有毛线的作用?
减1之后,对之后的运算会产生影响,请看例子
var num5 = 1;
var num6 = 3;
console.log(num5 + num6++ + num6); // 1 + 3 + 4 = 8
第一个+运算执行的是:1 + 3
num6++:自身自增1
第二个+运算执行的是:4 + 4(中间num6++,num6变为了4)
==============================================
3.2 赋值运算符 = += -= *= /= %=
// 将4赋值给num变量
var num = 4;
console.log(num); // 4
// 将num1自增5,再赋值给自身
var num1 = 3;
num1 += 5; // 等价于 num1 = num1 + 5
console.log(num1); // 8
// 将num2自减5,再赋值给自身
var num2 = 14;
num2 -= 5; // 等价于 num2 = num2 - 5
console.log(num2); // 9
// 将num3自乘5,再赋值给自身
var num3 = 3;
num3 *= 5; // 等价于 num3 = num3 * 5
console.log(num3); // 15
// 将num4自除5,再赋值给自身
var num4 = 10;
num4 /= 5; // 等价于 num4 = num4 / 5
console.log(num4); // 2
console.log(typeof 7/0) //NaN
// 获取num5跟5取余的结果,再赋值给自身
var num5 = 13;
num5 %= 5; // 等价于 num5 = num5 % 5
console.log(num); // 3
console.log(typeof 7%0) //NaN
3.3 比较运算符 == === != !== > < <= > >=
1. 相等比较:== ===
var num1 = 3;
var num2 = 3;
console.log(num1 == num2); // true
var num3 = 4;
var num4 = 2;
console.log(num3 == num4); // false
var num5 = 7;
var num6 = '7';
// ==:只比较值大小,不比较类型
console.log(num5 == num6); // true
var num7 = 7;
var num8 = '7';
// ===:比较值和类型,都相等结果为true
console.log(num7 === num8); // false
// 特例
console.log(null == undefined); // true
console.log(null === undefined); // false
null==0 //false
0==undefined //false
2. 不相等比较: != !==
var num1 = 4;
var num2 = 5;
console.log(num1 == num2); // false
// num1和num2不相等返回true
console.log(num1 != num2); // true
var num3 = 3;
var num4 = '3';
console.log(num3 === num4); // false
// num3和num4值和类型有一个不相等返回true
console.log(num3 !== num4); // true
3. 大于小于比较: > >= < <=
var num1 = 5;
var num2 = 19;
console.log(num1 > num2); // false
// num1>num2成立或者num1==num2成立都可以返回true
console.log(num1 >= num2); // false
console.log(num1 < num2); // true
// num1<num2成立或者num1==num2成立都可以返回true
console.log(num1 <= num2); // true
3.4 逻辑运算符
1. 逻辑与:&& - 两真为真,其余都为假
console.log(true && true) // true
console.log(true && false) // false
console.log(false && true) // false
console.log(false && false) // false
本质是:
// 将&&两侧的值"隐式"转为布尔值进行判断
console.log(3 && 'a') // a
console.log('abc' && 23) // 23
console.log('abcd' && null); // null
console.log(0 && '么么哒') // 0
***console.log(undefined && null) // undefined***
***注意:
如果&&两侧都为真,那么以后面的为结果;
如果&&两侧都为假,那么以前面的为结果。
2. 逻辑或:|| - 两假为假,其余都为真
console.log(true || true); // true
console.log(true || false); // true
console.log(false || true); // true
console.log(false || false);// false
本质是:
console.log(23 || 8); // 23
console.log('ab' || null) // ab
console.log(undefined && '萌萌哒'); // 萌萌哒
console.log(null && undefined); // undefined
*注意:
如果||两侧都为真,那么以前面的为结果
如果||两侧都为假,那么以后面的为结果
3. 取反
console.log(!true); // false
console.log(!false);// true
本质是:
console.log(!23); // false
console.log(!null); // true
console.log(!0); // true
3.5 条件运算符(三元运算符)
var result = 布尔值 ? 布尔值为真走这 : 布尔值为假走这;
var result = 5 > 3 ? '婚姻大事全凭父母做主' : '小女子还想侍奉父母两年';
console.log(result); // 婚姻大事全凭父母做主
3.6 特殊的+:连接运算符
1.特殊1:+
var num1 = 3;
var num2 = 'a';
var num3 = 8;
console.log(num1 - num2); // NaN
console.log(num1 * num2); // NaN
console.log(num1 / num2); // NaN
// +两边有非数字'a',取连接运算
console.log(num1 + num2); // 3a
// +两边是纯数字,取加法运算
console.log(num1 + num3); // 11
var num4 = 5;
num4 += 13; // num4的值为18
num4 += 'abc'; // num4的值变为18abc
2. 特殊2:- * /
var num1 = 12;
var num2 = '5';
console.log(num1 - num2); // 7
console.log(num1 * num2); // 60
console.log(num1 / num2); // 2.4
console.log(num1 % num2); // 2
总结:
除+之外,其余的运算符,在进行纯数字运算的时候,正常运算
3.特殊的+
var num1 = '5';
// 将字符串类型的num1变为数字
console.log(+num1); // 5
console.log(+num1+12); // 17
console.log(3+ +num1); // 8
总结:
在纯数字字符串前多写一个+,可以将字符串类型的数字变为数值类型的数字
3.7 运算符优先级
优先级 | 运算符 |
---|---|
12 | 成员访问(obj.username)、数组访问(arr[1])、new(new Person)、函数调用(demo()) |
11 | 后置递增(num++),后置递减(num--) |
10 | 取反(!) 前置递增(++num) 前置递减(—num) typeof void delete |
9 | 乘法(*) 除法(/) 取余(%) |
8 | 加法(+) 减法(-) |
7 | < <= > >= in instanceof |
6 | == != === !== |
5 | 逻辑与(&&) |
4 | 逻辑或(||) |
3 | 三元运算符(? 😃 |
2 | 赋值运算符(= += -= *= /= %=) |
1 | 逗号(,) |
4.流程控制
4.1 顺序分支
代码从上向下执行
4.2 条件分支
1. if条件分支(具体值和范围判断都可)
// 定义变量
var age = 24;
// 只有if判断
if (age < 18) {
console.log('小弟弟,你好小');
}
// if...else...判断
if (age < 18) {
// 当年龄小于18岁的时候,执行此段代码
console.log('年龄小于18岁');
} else {
// 当年龄大于等于18岁的时候,执行此段代码
console.log('年龄大于18岁');
}
// if...else if...else...
if (age < 18) {
console.log('年龄小于18岁');
} else if (age >= 18 && age < 24) {
console.log('年龄在18(包含)到24(不包含)岁之间');
} else if (age >= 24 && age < 30) {
console.log('年龄在24(包含)到30(不包含)岁之间');
} else {
console.log('年龄大于等于30岁');
}
2. switch语句(具体值判断)
// 将数值转换为具体的星期
var week = 3;
switch (week) {
case 1:
console.log('星期一');
break;
case 2:
console.log('星期二');
break;
case 3:
console.log('星期三');
break;
case 4:
console.log('星期四');
break;
case 5:
console.log('星期五');
break;
case 6:
console.log('星期六');
break;
case 7:
console.log('星期日');
break;
default:
console.log('输入的数据有误');
}
利用break进行合理的合并处理
var month = 1;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
console.log('31天');
break;
case 4:
case 6:
case 9:
case 11:
console.log('30天');
break;
case 2:
console.log('28天');
break;
default:
console.log('输入的月份有问题');
}
月份是1 3 5 7 8 10 12的时候,程序输出31天,并break(打断),不再执行下面的代码
月份是4 6 9 11的时候,程序输出30天,并break(打断),不再执行下面的代码
如果都不是,程序输出"输入的月份有问题"
if (month == 1) {
} else if (month == 2) {
} else if (month == 3) {
}
4.3 流程控制-循环语句
1. for循环
for (var i = 0; i < 10; i++) {
console.log(i);
}
2. while循环
var i = 0;
while (i < 10) {
console.log(i);
i++;
}
3. do...while循环
var i = 0;
do {
console.log(i);
i++;
} while (i < 10);
无论条件是否成立,都先执行一次do中的代码
4. break和continue语句
***break 如果在多层循环嵌套中,是终止当前层循环
*continue 是跳出当前循环,继续执行当前层循环的下一次循环
// break:终止循环
for (var i = 0; i < 10; i++) {
if (i == 4) {
break;
}
console.log(i);
}
// 最终的结果是:0 1 2 3
// 跳过当前循环继续执行下一次的循环
for (var i = 0; i < 10; i++) {
if (i == 4) {
continue;
}
console.log(i);
}
// 最终的结果是:0 1 2 3 5 6 7 8 9
5.函数
5.1 功能(为什么用)
- 减少代码重复书写的次数
- 提升开发效率,缩短开发时间
5.2 函数定义
1. 函数申明
// 1.定义普通函数
function demo(){
console.log('第一种定义函数方式');
}
// 调用函数
demo();
2. 匿名函数
// 使用1:函数表达式
var fun = function(){
console.log('第二种定义函数方式');
}
// 匿名函数第一种调用方式
fun();
// 使用2:匿名函数自调用
(function(){
console.log('匿名函数自调用');
})();
// 使用3:作为其他函数的参数
setTimeout(function(){
console.log('1s之后显示在控制栏');
}, 1000)
3. 使用Function构造函数
var fun = new Function('x','y','console.log(x+y)');
fun(3,8)
4. 箭头函数(ES6)
// 下面三个函数是一致的
var fun = function(a,b){return a+b;}
var fun = (a,b)=>a+b;
var fun = (a,b)=>{return a+b};
// 调用函数
fun(3,9);
5.3 特点
-
函数名定义规则
- 由字母数字下划线$组成
- 不能以数字开头
- 不能使用系统关键字和保留字命名
-
定义函数而不调用没有意义
-
调用特点:同一个
奋斗就是每天很难,可是一年一年却越来越容易;
不奋斗就是每天很容易,可是一年一年却越来越难。