变量声明及赋值
var a = 10;
var b = c = 10;
原始值与引用值
原始值 > 基本类型 > 栈内存 (Null, Undefined, String, Number, Boolean)
引用值 > 引用类型 > 堆内存 (Function、 Object、 Array)
var a = 3;
var b = a;
a = 1;
let arr1 = [1, 2];
let arr2 = arr1;
arr.push(3);
arr = [1];
字符串、数字和布尔类型等基本数据类型的值并不是引用类型,因此当你向这些值中添加属性时`JavaScript`并不会报错,但实际上你并没有将这些属性添加进去。这些值是不可变的,不能改变。有人会问,为什么有时候字符串可以像对象一样使用一些方法?那就是基本类型的装箱与拆箱的过程。
任何数据类型的值 + 字符串都是字符串 // 因为太重要,所以独立一个标题
NaN
0 / 0
'a' / 'b'
NaN / NaN
typeof Infinity
运算
4 % 6
5 % 3
a = a + b
b = a - b
a = a - b
let a = 5, b;
b = --a + --a;
b = --a + a--;
b = --a + a++;
NaN == NaN;
在`JavaScript`中,只有一个值不等于自身,那就是`NaN`。而且几乎所有的值都有属性,而`null`和`undefined`没有。
falsty的值有: null, undefined, 0, false, '', ' ', NaN
JavaScript中出现小数精度问题原因我们要站在计算机的角度思考 0.1 + 0.2 这个看似小儿科的问题。我们知道,能被计算机读懂的是二进制,而不是十进制,所以我们先把 0.1 和 0.2 转换成二进制看看
switch和if应用场景
switch :当值已经固定了
if :当数据是有一个范围的时候
for循环
for(let i =0; i;i++) {
# 内部可以通过break跳出循环
# 可以通过 i = 0 跳出循环
# 如果for循环在函数里面,可通过return跳出循环
}
let i = 100;
for(;i--;) {
console.log(i);
}
typeof
typeof(x);
typeof(null);
typeof('1' - '1');
console.log(a);
console.log(typeof(a));
console.log(typeof(typeof(a)));
严格模式
# 如果浏览器不支持严格模式,那么就不会报错
如果是函数的话可能会报错,所以只能从数字和字符串中选择,而字符串最合理
'use strict';
严格模式禁用:caller、callee、with、必须声明变量、var a = b = 1, 函数内的this指向undefined,在严格模式下调用函数要通过call来改变this的指向,函数参数不能重复、对象的属性名拒绝重复(但不报错),eval在严格模式下是有作用域的不能在全局访问,不能使用八进制,而且在严格模式下给封印的属性赋值扩展、赋值会报错
在非严格模式下,call会将第一个参数装箱。
new 、点、括号、原型、this
function Foo() {
getName = function () { alert(1); }
return this;
}
Foo.getName = function () { alert(2); }
Foo.prototype.getName = function () { alert(3); }
var getName = function () { alert(4); }
function getName () { alert(5); }
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
summary:如果new fn.xxx后面没有带括号,那么fn.xxx先执行,
如果new fn().xxx后面带了括号,那么new fn()限制性
如果返回值是一个基本类型,那么new 基本类型 > 基本类型。eg:new 3 > 3
return的值是一个赋值表达式时,返回的是右边的值
function fbb() {
var a={};
return a.b=0;
}
fbb();
# 同样道理
function Car(name) {
return this.name = name;
}
console.log(typeof new Car({}).name);
这里面涉及到对象的key是基本类型的问题,如果是基本类型的话,都可以作为对象的key值,当然也包括 null 、 undefined 、 ''、 ' ' 、 NaN,如果是引用类型的话,key值是堆地址
算术运算符和逻辑运算符优先级
1.()圆括号的优先级最大
2. 一元运算符 ++ 、 --( ++a 优先级小于 a++ )、 ! 、+... 、-...
3. 算术运算符 **(幂) 、* 、 / 、 %(取余) 、 + 、 -
4. 移位运算符 <<(按位左移)、>>(按位右移)、>>>(无符号右移)
5. 比较运算符 < 、 <= 、 > 、 >= 、 == 、 != 、=== 、!==
6. 位运算符 & (按位与) 、^ (按位异或) 、| (按位或)
7. 逻辑运算符 &&(逻辑与)、|| (逻辑或)
8. 三元运算符
9. 赋值运算符 =、 += 、-= 、*= 、/= 、%=
10. 展开运算符 ...
11. 逗号运算符 ,
所以:当 console.log(true && 1 + 0 || 1),输出的是3,而且逻辑运算符只对真假做校验,不会特意去转化成 true 与 false 作为返回值
Object
和String
、Number
之间的转换
let x = {
toString () {
return x;
},
valueOf () {
return y;
}
}
console.log(x == 1);
console.log(x == '2');
# 分析 以上两个比较都会进行类型的转换,而且都会先经过valueOf。如果valueOf返回的是基本类型,那么就不会经过toString的方法。如果只有toString方法,那么直接走toString方法,并且若返回的不是基本的数据类型则报错。
undefined
、null
、0
undefined == null
undefined == 0
null == 0
Number(null)
Number(undefined)
Number([])
[] == 0
[''] == 0
[' '] == 0
[undefined] == 0
[null] == 0