语法
var关键字和变量提升
javascript 的变量是松散类型的,意思是可用于保存任何数据类型,每个变量只不过是一个用于保存任意值的命名占位符。
var关键字声明的是函数作用域
var声明提升:
function fn() {
console.log(name);
var name = 12;
}
fn();//undefined
相当于:
function fn() {
var name;
console.log(name);
name = 12;
}
fn();//undefined
因此不会报错,而是输出undefined
let声明
let声明的是块级作用域,块级作用域是函数作用域的子集,因此适用于var的作用域限制同样也适用于let.
let不允许同一个块级作用域中出现冗余声明,对声明冗余不会因为let和var混用而受影响。
if (true) {
let age;
let age;
console.log(age);
}
console.log(age);
报错:Uncaught SyntaxError: Identifier 'age' has already been declared(age已经声明过了)
let出现的暂时性死区
let声明不会变量提升,在let变量声明之前不能以任何方式来引用为声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”,都会抛出ReferenceError。
let在全局作用域中声明的变量不会成为windows的属性,而var声明则会成为window的属性。
for循环声明
var 声明的变量会渗透到for循环外部
for (var index = 0; index < 5; index++) {
}
console.log(index);//5
let声明的变量不会渗透到for循环外部
for (let index = 0; index < 5; index++) {
}
console.log(index);//index is not defined
在适用var声明变量时,对迭代变量的奇特声明和修改:
for (var index = 0; index < 5; index++) {
setTimeout(function() {
console.log(index);//输出5个5
}, 1);
}
原因:是因为在退出循环时保存的是导致循环退出的值。改用let就不会有问题了。
const声明
1.const声明也是块级作用域
2.声明是必须赋值,后面不能再修改,相当于创建常量。
3.同let一样,不能重复声明。
数据类型
6种简单数据类型:
1.Undefined
2.Null
3,Bollean
4.Number
5.String
6.Symbol(es6新增,字符)
一种复杂数据类型:
- Object(对象)
null
undefined是由null派生过来的,因此他们表面上相等。由于他们的类型不同,所以不全等于。
console.log(null == undefined);//true
console.log(null === undefined);//false
Boolean
Boolean(变量)转型函数;
数据类型 | true | false |
---|---|---|
Boolean | true | false |
String | 非空字符串 | “”(空字符串) |
Number | 非零数值(包括无穷值) | 0,NaN |
Object | 任意对象 | null |
Undefined | 无 | undefined |
Number
浮点型只会保存近似值,因为对于有些小数,二进制是无法精确表示的。
Number.MIN_VALUE,最小值
Number.MAX_VALUE 最大值
infinity 无穷大
isFinite(变量)函数,判断是否在能表示范围内
isNaN(变量) 判断是否为NAN,如果是返回false,否则返回true,可以转换为数值的也为false
console.log(isNaN(NaN)); //true
console.log(isNaN(false)); //false
console.log(isNaN('19')); //false
console.log(isNaN("blrfea")); //true
console.log(isNaN(12));//false
number(变量 ): 转型函数,可用于任何数据类型,
转换规则:
布尔值,true转为1,false转为0
数值,直接返回
null,返回0
undefined 返回NaN
字符串:空字符串返回0,纯数字字符放回相应的数值,其他的都返回NaN
parseInt(变量,进制数)
将开头有整数的部分转为转为整数。
parseFloat(变量):将开头有小数的部分转为小数。
只能解析十进制
String
字符串的特点:
ECMAscript中的字符串是不可变得,一旦创建,值就不能改变了。要想修改,必须先销毁原始的字符串。然后将新的字符串保存到该变量。
tostring(); 转换为字符串函数。(null,undefined没有tostring()方法。)
变量加上一个空字符也可以转换为字符串:
let a = 321321;
a = a + '';
模板字面量:保留换行符,可以换行定义字符串。
let b = `feaf
feaf`;
模板字面量使用变量,插入值函数:${}
let c = `${a}+${b}=${a+b}`
Symbol类型
符号是原始值,且符号实例是唯一的,不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险。
//a和b是不相等的
let a = Symbol();
let b = Symbol();
let c = Symbol('ab');//可以传入字符串参数,作为对符号的描述
全局注册表
创建时会在全局中检索是否存在对应的符号,如果存在就使用现有的,没有就创建新的。
所有的参数必须使用字符串,因此传给Symbol.for()的所有参数都会转换为字符串。
let a = Symbol.for('symbol类型');
let b = Symbol.for();
console.log(b) //Symbol(undefined)
Symbol.keyFor();查询==全局==注册表,返回对应的字符串键。
let a = Symbol.for('abc');
console.log(Symbol.keyFor(a));//abc
使用符号作为属性的常用方法
Object.defineProperties()
方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
let obj = {};
let b = Symbol("b");
let c = Symbol("c");
Object.defineProperties(obj, {
[b]: {
value: "cde val",
},
[c]: {
value: "fff val",
},
});
**Object.defineProperty()**
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
let a = Symbol('abc');
let b = Symbol('cde');
let c = Symbol('fff');
let o = {
one: 'hello',
two: 'wird',
[a]: 'abc val'
};
Object.defineProperty(o, b, {
value: 'aaa'
});
**Object.getOwnPropertyNames()
**方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
let a = Symbol('abc');
let b = Symbol('cde');
let c = Symbol('fff');
let o = {
one: 'hello',
two: 'wird',
[a]: 'abc val'
};
console.log(Object.getOwnPropertyNames(o));
//(2) ["one", "two"]
**Object.getOwnPropertySymbols()**
方法返回一个给定对象自身的所有 Symbol 属性的数组。
let obj = {
name: "wanmg",
age: 12,
};
let b = Symbol("b");
let c = Symbol("c");
Object.defineProperties(obj, {
[b]: {
value: "cde val",
},
[c]: {
value: "fff val",
},
});
console.log(Object.getOwnPropertySymbols(obj));//[ Symbol(b), Symbol(c) ]
Object.getOwnPropertyDescriptors()
方法用来获取一个对象的所有自身属性的描述符。
let obj = {
name: "wanmg",
age: 12,
};
let b = Symbol("b");
let c = Symbol("c");
Object.defineProperties(obj, {
[b]: {
value: "cde val",
},
[c]: {
value: "fff val",
},
});
console.log(Object.getOwnPropertyDescriptors(obj));
/*{
name: {
value: 'wanmg',
writable: true,
enumerable: true,
configurable: true
},
age: { value: 12, writable: true, enumerable: true, configurable: true },
[Symbol(b)]: {
value: 'cde val',
writable: false,
enumerable: false,
configurable: false
},
[Symbol(c)]: {
value: 'fff val',
writable: false,
enumerable: false,
configurable: false
}
}*/
Reflect.ownKeys()
:返回两种类型的键
let obj = {
name: "wanmg",
age: 12,
};
let b = Symbol("b");
let c = Symbol("c");
Object.defineProperties(obj, {
[b]: {
value: "cde val",
},
[c]: {
value: "fff val",
},
});
console.log(Reflect.ownKeys(obj));//[ 'name', 'age', Symbol(b), Symbol(c) ]
运算符
指数运算符 (**)
ECMAScript 7 中新增的
Math.pow(3,2)==3**2
加性运算符
加法:
1、加法运算符需要注意数据类型,可以进行字符串的加法运算。
2、两个字符串相加相当于两个字符串拼接到一起。其中有一个是字符串,相加后仍然是字符串。
3、如果一个是字符串,另一个是数值,对象或字符串,内部调用toString()方法将其转换为字符 串,在进行拼接。如果为null或undefined,则内部再调用String()方法,变为字符串‘null’和’undefined‘,然后再拼接。
相等操作符
等于和不等于在比较前会执行类型转换,全等和不全等不会进行类型转换,因此只有数值和类型都相等是才会返回true。
等于和不等于
规则:
- 任意一个为布尔值,则将其转换为数值再进行比较,false为0,true为1
- 一个为字符串,一个为数值,将字符串转换为数值后再进行比较。
- 有一个为对象,则调用对象的valueOf()方法取得原始值,再进行比较。
- null和undefined相等。
- null和undefined不能转换为其他类型的值再进行比较。
- 有一个为NaN,则返回false.
- 如果两个都是对象,只有当指向同一个对象是才返回true.
结果 | 表达式 |
---|---|
true | null == undefined |
false | 'NaN' == NaN |
false | 5 == NaN |
true | NaN != NaN |
true | false==0 |
true | true == 1 |
false | true == 2 |
false | unndefined == 0 |
false | null == 0 |
true | "5" == 5 |
全等和不全等
只有当类型和数值都相等是才为true
undefined === null // false 类型不同所以为false
标签语句
label : statement
标签语句最常用的是搭配break和continue语句使用
let num = 0;
out:
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
continue out;
}
num++;
}
}
//当i==5和j==5时,跳到out,然后继续执行,所以只有55到60之间没有执行
console.log(num); // 95
let num = 0;
out:
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (i == 5 && j == 5) {
break out;
}
num++;
}
}
//当i==5和j==5时,调到out,内外循环都停止了,所以就只执行到55
console.log(num); // 55
函数
函数的特点:
- 不需要指定函数的返回值,因为任何函数可以在任何时候返回任何值。
- 不指定返回值得函数实际上返回undefined.