目录
1.数据类型
(1)原始数据类型
(2)隐式转换
(3)逻辑语句中的类型转换
(4)数据类型检测
2.表达式
3.运算符
(1)分类
(2)其他
4.作用域
5.语句
6.严格模式
1.数据类型
(1)原始数据类型
number, string, boolean, null, undefined, object
object对象包含: Array, Function, Date...
function fun() {}
console.log(typeof fun) //function
console.log(typeof []) //object
console.log(typeof new Date()) //object
console.log(typeof null) //object
console.log(typeof undefined) //undefined
(2)隐式转换
-,*,/
非number类型运算时, 先将非number转换为number类型
e.g: null->0 undefined -> NaN ['5']->'5'->5 字母->NaN
+ 运算规则 (规则1-3,优先级从高到低)
规则1: 当一侧为String,字符串拼接
规则2: 当一侧为Number类型, 一侧为原始类型, 将原始转为Number类型
规则3: 当一侧为Number类型, 一侧为引用类型, 均转为字符串后拼接
console.log('qw' + ['2']) // qw2 (规则1)
console.log(7-'a'); // NaN
console.log(10 + '23') // 1023 (规则2)
console.log(10 + null) // 10 (规则3)
console.log(10 / 0) // Infinity 相当于报错, 0不能作为除数
(3)逻辑语句中的类型转换
只有单个变量, 转换为boolean值
null,undefined,'',NaN,0,false的值为false, 其他都是true,e.g:{},[]
使用==比较规则
规则1: NaN 和其他类型始终返回false, 包括自己
规则2: Boolean 和其他类型比较, Boolean先转换为Number类型 true->1 false->0
规则3: String和Number比较, 先将String转换为Number类型 ''->0
规则4: null==undefined为true, null和undefined与其他任何比较均为false
规则5: 原始类型和引用类型作比较时, 引用类型按照ToPrimitive规则转换为原始类型
console.log(NaN == NaN) //false (规则1)
console.log(true == 1) // true (规则2)
console.log('3' == 3) // true (规则3)
console.log(null == undefined) //true (规则4)
console.log('1,2' == ['1,2']) // true ['1,2']->'1,2' (规则5)
console.log('a'-'b' == 'b' - 'a'); //false
console.log('a'-'b'); //NaN
console.log('b'-'a'); //NaN
console.log(1111111111111);
// 引用类型与引用类型作比较 地址不同 new创建对象
console.log(new Object() == new Object()); //false
console.log({} == {}); //false
console.log([1,2] == [1,2]); //false
// 对象类型 {}
// 字符串无length属性, length是原型上的属性 Object的属性, 字符串不是对象,故无法通过该方式追加
var str = 'aaa'
console.log(str.length); //3
// str.t = 'b' //字符串不是对象,故无法通过该方式追加
// console.log(str.t);
===严格等于
// === 严格等于 值和数据类型均相等返回true 先比较数据类型, 再比较值
console.log(null === null); //true
console.log(null === undefined) //false
console.log(4 == '4.00'); //true
console.log(4 === '4.00') //false
(4)数据类型检测
typeof 适用于基本数据类型的检测(Number,Boolean,String,...),引用类型全返回object
instanceof 适用于引用类型的检测
Object.prototype.toString() 两种类型检测均可 每个对象都有prototype属性
console.log([1,2,3] instanceof Array); //true
console.log(new Date() instanceof Date); //true
console.log(Object.prototype.toString.call([1,2])); //[Object Array]
console.log(Object.prototype.toString.call([1,2]).substring(8,13)); //Array 可通过字符串截取
console.log(Object.prototype.toString.apply(null)); //[object Null]
console.log(Object.prototype.toString.apply(undefined)); //[object Undefined]
console.log(Object.prototype.toString.apply(NaN)); //[object Number]
console.log(Object.prototype.toString.apply(4.00)); //[object Number]
console.log(Object.prototype.toString.apply(4)); //[object Number]2
2.表达式
表达式指一中js短语, 可使js解释器用来产生一个值
(1)分类
原始表达式: 常量,直接量(e.g:字符串), 关键字, 变量
初始化表达式: 通过自变量形式创建数组,对象的表达式
属性访问表达式
函数表达式
调用表达式
对象创建表达式: 通过new的形式创建对象
// 1. 原始表达式 e.g: 10 算式组成复合表达式e.g: 10 * 2
// 2. 初始化表达式
// (1) 创建对象
var obj1 = { x: 1, y: 2 } //自变量的方式创建
var obj2 = new Object()
obj2.a = 3
console.log(obj1) //{x: 1, y: 2}
console.log(obj2) //{a: 3}
// (2) 创建数组
var arr1 = [1, 2]
var arr2 = [1, , , , 3] // 稀疏数组 length:5 最后的逗号表分隔 for-in遍历时, 稀疏数组只返回有值的元素 for循环打印所有
var arr3 = new Array(2, 3)
var arr4 = new Array(3) // 创建长度为3的数组
console.log(arr1) // [1,2]
console.log(arr2) // [1, empty × 3, 3]
console.log(arr3) // [2, 3]
console.log(arr4) // [empty × 3]
// 3.属性访问表达式
console.log(obj2.a) //3
console.log(obj2['a']) //3
// 4. 函数表达式 必须后调用 先调用会报错, var声明的变量会变量提升至最前边
// var fun2 = undefined
// console.log(fun2); //undefined
var fun2 = function () {
console.log('222222')
}
// 5. 调用表达式(调用函数)
fun2()
// 立即执行函数 !区分作用域(可写可不写) (function({匿名函数})() 最后的()相当于调用函数
!(function () {
console.log('立即执行函数')
})()
3.运算符
(1)分类
按照操作数的个数
一元运算符: !
二元运算符:
三元运算符: 表达式1 ? 表达式2 : 表达式3 表达式1的结果为Boolean值,true则取表达式2的值,否则取表达式3的值
(2)其他
delete, in, void, ||
// delete 运算符 删除属性
var obj3 = new Object()
// (1) 对象名.属性 = 属性值 使用该种方式定义的属性, delete可删
obj3.x = 100
console.log(obj3) // {x: 100}
delete obj3.x
console.log(obj3) // {}
// (2) 定义属性 通过defineProperty()定义对象属性添加属性和值, 可控制属性操作权限 每个对象自身包含value,configurable,writable,enumerable属性
Object.defineProperty(obj3, 'y', {
value: 200,
configurable: false, //是否可配置,是否可删除 默认true
writable: true, //是否可修改 默认true
enumerable: false, //是否可枚举(遍历) 默认true
})
console.log(obj3) //{y: 200}
delete obj3.y
console.log(obj3) //{y: 200}
// in 运算符 判断某属性是否为obj上的属性
console.log('y' in obj3) //true
// void 运算符 阻止页面跳转 <a href="javascript: void(0)"></a>
// ||运算符 |位或(转换为二进制,每位相或,有1则1,全0则0,得值, e.g: 3 | 5 = 7 )
function fun3(a,b,c){
// c 默认为10, 传参使用实参的值, 否则使用默认值
// 方式1: if判断
// 方式2: 短路或, 左侧为true则不继续运算
c = c || 10
return a + b + c
}
console.log(fun3(1,2,20)); // 23
// new 和 this 面向对象
4.作用域
// 作用域
var a = 10 // 全局变量 a 属于window
function fun1() {
var b = 20
console.log(a) // 10 可访问全局变量a
console.log(b) // 0
}
fun1() //先声明再调用
console.log(a) //10
// console.log(b); //无法访问函数内的变量 Uncaught ReferenceError: b is not defined
h = 5
function fun2() {
// var a = 1
var d = (e = 5)
var f = 5,
g = 5
i = 5
// var a=1,b=1
console.log(typeof d) // number 5
console.log(typeof e) // number 5
console.log(typeof f) // number 5
console.log(typeof g) //number 5
console.log(typeof h) //number 5
console.log(typeof i) //number 5
}
fun2()
console.log(typeof d) // undefined
console.log(typeof e) // number 5
console.log(typeof f) // undefined
console.log(typeof g) // undefined
console.log(typeof h) //number 5
console.log(typeof i) //number 5
5.语句
// 语句
// 1. 块 block { }包裹 没有块级作用域
{
// 语句1;
// 语句2; ...
var c = 30 //没有作用域, var可进行变量提升
console.log(c) //30
}
// { a: 1, b: 2 } // SyntaxError
console.log(c) //30 没有块级作用域
// 2. try-catch / try-catch-finally/ try-finally 也可嵌套 try{}中发生异常,则在catch{}中捕获异常, finally{}中无论是否异常都执行
try {
var str = undefined
var res = str.trim()
} catch (e) {
console.log(e)
} finally {
console.log('aaa')
}
console.log('qqq')
// 3. for-in 顺序不确定, enumerable为false时无法遍历, for in对象属性受原型链影响
var obj = { x: 1, y: 2 }
for (var key in obj) {
console.log(obj[key]) // 1 2
}
6.严格模式
使用 'use strict'写在函数内部或js代码的最前边 增强安全性,添加限制
限制:
不允许使用 with
不允许声明的变量未赋值
arguments变为参数的静态副本
delete参数,函数名报错
delete不可配置的属性报错(使用defineProperty属性可删,但使用delete会报错)
eval, argument变为关键字, 不能作为变量,函数名
function fun2(a, b) {
'use strict'
console.log(arguments)
var obj4 = {x:1, x: 2}
console.log(obj4); // { x:2} 覆盖掉
}
fun2() //Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
fun2(10,20) //Arguments(2) [10, 20, callee: ƒ, Symbol(Symbol.iterator): ƒ]