变量
概念
可以把变量看做存储数据的容器。
变量的独特之处在于它存放的数值是可以改变的。
var定义的变量将成为定义该变量的作用域中的局部变量。
如果只是声明变量而没有赋值,则该变量的值是undefined。
var a; //undefined
function fn(){
var a = b = 3;
}
fn();
console.log(a);//报错,a是局部变量
console.log(b);//3,b是全局变量
//var a = b = 3;
// 可写为
// b = 3;
// var a = b;
全局变量
没有任何作用域的变量
- 在函数外使用var声明变量,这个变量是全局变量。
- 在函数内不用var声明变量,这个变量是全局变量。
全局变量面临的问题
- 局部变量和全局变量名称的冲突
- 很难调试和测试依赖于全局变量的代码
局部变量
在函数里使用var声明变量,这个变量就是局部变量。
标识符
标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名,以建立起名称与使用之间的关系
规则
- 第一个字符必须是一个字母、下划线(_)或一个美元符号($)。
- 其他字符必须是字母、下划线、美元符号或数字。
- 变量名对大小写敏感。
采用驼峰大小写格式
表达式和语句
var a = 1 + 2;//这是一个语句,1 + 2是表达式
返回值
只有函数有返回值
函数表达式的值
是函数本身
console.log(3);//该表达式的值为undefined
函数调用表达式的值
是函数的返回值
function add(x,y){
return x+y;
}
add(1,2);//3
return练习
function fn(){
return 1;
}
fn();//1
function fn1(){
return //js会自动补齐分号
1;
}
fn1();//undefined ,注意换行了。
数据类型
原始数据类型(基本数据类型)
Boolean
Number
String
BigInt
ES6新增
Symbol
特殊值
Null
Undefined
合成数据类型
因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器
Object: //对象又可以分成三个子类型
- Object(狭义的对象)
- Array
- function
null和undefined的区别
- null表示没有对象,是空值,表示一个空指针对象
- 作为函数的参数,表示该函数参数不是对象。
- 对象原型链的最终值。
- undefined表示未定义
- 变量声明但是未赋值
var a; a;//undefined ----------------- var a = 2; a;//2- 调用函数时,未提供参数
function fn(x){ return x; } fn();//undefined ----------------- function fn(x){ return x; } fn(5);//5- 对象没有赋值的属性
var b = new Object(); b.c;//undefined console.log(b);//{} ------------------ var b = new Object(); b.c = 5;//5 console.log(b);//{c:5}- 函数没有返回值
function fn(a){ } fn(2)//undefined
typeof运算符
typeof操作符返回一个字符串,表示未经计算的操作数的类型。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。
typeof null // "object"
typeof NaN // "number"
typeof 123 // "number"
typeof '123' // "string"
typeof false // "boolean"
*function f() {}
typeof f // "function" 函数
typeof undefined // "undefined"
typeof v // "undefined" v是一个未声明的变量
typeof window // "object" 对象
typeof {} // "object" 空对象
typeof [] // "object" 空数组
//typeof对数组(array)和对象(object)的显示结果都是object,instance区分数组
运算符
作用:链接简单的表达式组成复杂的表达式
键关字运算符
typeof
delete 用于删除对象中的某个**属性**,不能删除变量、函数。
instanceof
算术运算符
加法运算符
加法运算符的作用是数值求和,或者字符串拼接。
规则
- 两个操作数有一个字符串就进行字符串拼接,
- 一个操作数转换为数字
- 在两个操作数都是数字的时候,会做加法运算。
- 在两个参数都是字符串或在有一个参数是字符串的情况下会把另外一个参数转换为字符串做字符串拼接。
- 在参数有对象的情况下会调用valueOf或toString。
- 在只有一个字符串参数的时候会尝试将其转换为数字。
- 在只有一个数字参数的时候会返回其正数值。
例子
console.log(2 + 4); // 6
console.log("2" + "4"); // "24"
console.log(2 + "4"); // "24"
console.log(+"4"); // 4
console.log(+"hello"); // NaN
var obj = {
toString: function(){
return 10;
},
valueOf: function(){
return '3';
}
}
obj + 'hello'; // 3hello valueOf优先级比toString高
减法运算符
减法运算符使两个操作数相减,结果是它们的差值。数值求差
- 若一个操作数为字符串,布尔值,null和undefined,则先调用Number()函数将其转换为数值再计算。
- 若操作数时对象则调用对象的valueOf()方法获得数值再计算。
console.log(5 - 2); // 3
console.log('5' - '2'); // 3
console.log('5' - false); // 5
console.log('hello' - 5); // NaN
乘法运算符
乘法运算符的结果是操作数的乘积
- 0乘任何非数值都为NaN
console.log(0 * Infinity); // NaN
console.log(Infinity * Infinty); // Infinity
console.log('hello' * 0); // NaN
console.log(-2 * 2); // -4
除法运算符
除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。
- 任何数值除0都为(+/-)infinite
- 0、非数值与自身相除为NaN
- 非数值与数值相除为NaN
console.log(1 / 2); // 0.5
console.log(1.0 / 2.0); // 0.5
console.log(1 / 0); // Infinity
console.log(-1 / 0); // -Infinity
console.log(0 / 0); // NaN
console.log(Infinity / Infinity); // NaN
console.log('hello' / 'hello'); // NaN
余数运算符
求余运算符返回第一个操作数对第二个操作数的模.
console.log(1 % 2); // 1
console.log(Infinity % 2); // NaN
console.log(-1 % 2); // -1
console.log(-2.5 % 2); // -0.5
递增运算符
x++ // 递增前返回值
++x // 递增后返回值
var a = 10;
var b = a++;
console.log(b);//10
console.log(a);//11
var c = 10;
var d = ++c;
console.log(c);//11
console.log(d);//11
递减运算符
x-- // 递减前返回值
--x // 递减后返回值
求负运算符
一元负号运算符位于操作数前面,并转换操作数的符号.
var x = 3;
var y = -x;
console.log(y); // -3
console.log(-true); // -1
console.log(-flase); // 0
console.log(-'3'); // -3
console.log(-'-3'); // 3
console.log(-null); // -0
数值运算符
一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。
console.log(+true); // 1
console.log(+flase); // 0
console.log(+'3'); // 3
console.log(+'-3'); // -3
console.log(+null); // 0
赋值运算符
x += y
x -= y
x *= y
x /= y
x %= y
x >>= y // x = x >> y 向右移动指定位数的比特位
x <<= y // 向左移动
x >>>= y //无符号右移赋值
x &= y //同一为一
x |= y //有一为一
x ^= y //异或 异才为一
例子
var a = 5; // 0101
a <<= 2; // 010100 即20
console.log(a); //20
var b = 1;
var c = 2;
console.log(b&c); //0
console.log(b|c); //3
console.log(b^c); //3
比较运算符
比较运算符比较两个值,然后返回一个布尔值
== 相等,值相等数据类型可以不相等
=== 严格相等,值和数据类型都必须相等
!= 不相等
!== 严格不相等
<
<=
>
>=
例子
null == undefined //true
1 == '1' //true
1 === '1' //false
true == 1 //true
布尔运算符
! 取反运算符
&& 且运算符
|| 或运算符
condition? true case : false case 三元条件运算符
!"" //true
!" " //false
!"hello" //fasle
!0 //true
!NaN //true
!123 //false
!undefined //true
!null // true
var max = (3 > 5) ? 3 : 5;
console.log(max); //5
短路
| 运算符 | 说明 |
|---|---|
expr1 && expr2 | 若 expr1 可转换为 true,则返回 expr2;否则,返回 expr1 |
| 若 expr1 可转换为 true,则返回 expr1;否则,返回 expr2。 | |
!expr | 若 expr 可转换为 true,则返回 false;否则,返回 true。 |
1 && 3 // 3
1 || 3 // 1
NaN
Not a Number
NaN不与任何值相等,包括其本身
typeof NaN; //number
console.log(NaN == NaN); // false NaN不与任何值相等,包括其本身
console.log(0 / 0) // NaN
console.log({} == {}) // false
typeof 2*3; // NaN number*3
判断一个值是不是NaN——isNaN()
isNaN(undefined)//true
isNaN(true)//false
isNaN(null)//false
位运算符
或运算符:|,有1为1,全1为0,全0为0
与运算符:&,全1为1
否运算符:~
异或运算符:^,有且仅有一个为1得1
左移运算符:<<
右移运算符:>>
带符号位的右移运算:>>>
例子
var a = 2; //10
var b = a << 5; //1000000 左移5位 即64
console.log(b); // 64
var a = 1; // 0001
var b = 2; // 0010
a & b = 0; // 0000
a | b = 3; // 0011
其他
void
void运算符表明一个运算没有返回值,表达式的运算结果返回undefined。
void(x = 3); // undefined
console.log(x); // 3
void(0)- 防止页面刷新,并在调用时传递参数"0"。
<a href = "javascript: void(0);">
<!--这是一个死链接-->
逗号
逗号运算符用于两个表达式求值,并返回后一个表达式的值。
console.log(1 , 2) //2
console.log(2 , 1) //1
运算符优先级
圆括号
new、函数调用
后置递增/减
逻辑非、按位非、一元+-、前置递增/减、typeof、void、delete
幂
乘除取模
加减
按位左/右移
< <= > >= in instanceof
== != === !==
按位与
按位异或
按位或
逻辑与
逻辑或
条件运算符
赋值
逗号
例子
var a = 1;
console(a+++a); //3
//a++ +a 递增的后置优先级高于前置,先算a++
typeof 2 + 4; //'number4',typeof 2优先级更高
var a = typeof typeof 4+4;
console.log(a); // 'string4' 先typeof 4得'number' ,再typeof (typeof 4)得'string',最后拼接+4。
var a = 1, b = 2, c = 3;
var val = typeof a + b || c >0;
console.log(val);//"number2"
//typeof优先级 > +号 > >号 > ||
var d = 5;
var data = d ==5 && console.log('bb');
console.log(data); //bb
//相等 > && > 赋值
var data2 = d = 0 || console.log('haha');
console.log(data2);//haha
// 或 > 赋值,前半部分为0,false输出后半部分
var x = !!"Hello" + (!"world", !!"from here!!");
console.log(x);// 2
// () > !
//先算括号中的,再算逗号,!!"from here!!"值为1,!!"Hello"值为1,和为2
类型转换
显示类型转换
转换为数值类型
Number()、parseInt()、parseFloat()
转换为字符串
toString()、String()
转换为布尔类型
Boolean()
Boolean()转换
| 数据类型 | 转换位false的值 |
|---|---|
| Boolean | false |
| String | ""(空字符串)为false |
| Number | 0和NaN为false |
| Object | 全为true |
| Undefined | false |
| Null | false |
例子
if (" ") {
console.log('blank')
}//true,输出blank,if()内不是空字符串有空格
if ("") {
console.log('empty')
}//false,不输出,if()内空字符串
if ([0]) {
console.log('array')
}//true 输出array,[0]是空数组
隐式类型转换
在使用算数运算操作符时,运算符两边数据类型可以是任意的(js引擎对他们进行隐式类型转换)
==的判断
在转化不同的数据类型时,有以下基本规则
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值
- 如果一个操作数是字符串,另一个数是数值,在比较相等性之前先将字符串转换为数值
- 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较。
一些特殊情况
| 表达式 | 值 |
|---|---|
| null == undefined | true |
| NaN == NaN | false |
| false == 0 | true |
| undefined == 0 | false |
| null == 0 | fasle |
| "1" == 1 | true |
| 0、false、""为假值,undefined、null为空值 |
例子
"" == 0 //true
" " == 0 //true
"" == true //false
"" == false //true
" " == true //false
!" " // false 非空字符串取反为false (这不是在==判断,不要搞混了)
!" " == true //false
!" " == false //true
"hello" == true //false
"hello" == false //true
"0" == true //false
"0" == false //true
"00" == false //true
"0.00" == false //true
undefined == null //true
true == {} //false
[] == true //false
var obj = {
a: 0,
valueOf: function(){return 1}
}
obj == "[object Object]" //false
obj == 1 //true
obj == true //true
//[object Object] 表示这个对象是个包着对象的对象
var obj = {
a: {}
}
obj == "[object Object]" //true
0.1 + 0.2 == 0.3; //false ,浮点数运算值不准确。0.1+0.2 == 0.30000000000000004