1.typeof/instanceof/Object.prototype.toString()

它们都可以判断值的类型
instanceof 可以区分ArrayObject

typeof null // Object
let arr = []
arr instanceof Array // true
let obj = {} 
obj instanceof Array //false

2.null / undefined /NaN/Infinity

null表示该值为空 占用内存空间 不是数值类型
undefined表示该值未定义 没有分配内存空间 不是数值类型
NaN是非数字的数值
Infinity表示值的无穷
除了Infinity它们在条件表达式里面都判断为false

// Number()转化结果如下
Number(null) //0
Number(undefined) //NaN
Number(NaN) //NaN
Number(Infinity) //Infinity

null === null // true
undefined === undefined // true
NaN === NaN // false
Infinity === Infinity // true

3.Object 基础

Object元属性(属性描述)

{
    value:123, //该属性的属性值
    writable:false, //表示value属性的值能否被修改
    enumerable:false, //表示value属性能否被遍历(是否为可枚举属性)
    configurable:false //表示value属性能否被修改(控制value属性能否被删除、修改、其他元属性能否被修改)
    get:() =>{}, // value属性的取值函数
    set:() =>{}  // value属性的存值函数
}

对象属性模型的相关方法
Object.getOwnPropertyDescriptor()
获取某个属性的描述对象
(只能获取自身属性)

let obj = {p:1}
Object.getOwnPropertyDescriptor(obj, 'p')
// {
//    value:1,
//    writable:true,
//    configurable:true,
//    enumerable:true
// }

Object.defineProperty():修改单个属性的描述对象

let obj = {a:1}
Object.defineProperty(obj, 'a', {
    value:1,
    configurable:true,
    writable:false,  //修改为false,表示obj.a的值不能被修改
    enumerable:true
})
obj.a = 2  
obj.a // 1

Object.defineProperties():修改多个属性的描述对象

let obj = Object.defineProperties({}, {
  p1: { value: 123, enumerable: true },
  p2: { value: 'abc', enumerable: true },
  p3: { get: function () { return this.p1 + this.p2 },
    enumerable:true,
    configurable:true
  }
});
obj.p1 // 123
obj.p2 // "abc"
obj.p3 // "123abc"

控制对象状态的方法
Object.preventExtensions():防止对象扩展。
Object.isExtensible():判断对象是否可扩展。
Object.seal():禁止对象配置。
Object.isSealed():判断一个对象是否可配置。
Object.freeze():冻结一个对象。
Object.isFrozen():判断一个对象是否被冻结。

原型链相关方法
Object.create():该方法可以指定原型对象和属性,返回一个新的对象。
Object.getPrototypeOf():获取对象的Prototype对象

Object实例方法
Object.prototype.valueOf():返回当前对象对应的值。
Object.prototype.toString():返回当前对象对应的字符串形式。
Object.prototype.toLocaleString():返回当前对象对应的本地字符串形式。
Object.prototype.hasOwnProperty():判断某个属性是否为当前对象自身的属性,还是继承自原型对象的属性。
Object.prototype.isPrototypeOf():判断当前对象是否为另一个对象的原型。
Object.prototype.propertyIsEnumerable():判断某个属性是否可枚举(只返回自身属性)

Object.keys()Object.getOwnPropertyNames()
都只返回自身属性
getOwnPropertyNames()可以返回不可枚举的属性

delete指令
删除Object指定属性(不能删除继承的属性)

in指令
判断对象里面是否包含该属性
(可以查询到继承属性)
(但不能区分属性是否是继承而来)
Object.hasOwnProperty()可以查询是否为继承属性

for in
遍历对象属性
(遍历自身及继承可遍历属性)

let obj = {j:'123'}
for(let key in obj){
    key // j
    obj[key] // '123'
}
若只想遍历自身属性时
for (let key in obj){
    if(obj.hasOwnProperty(key)){
        // do someting
    }
}

with
批量处理对象属性
(必须是当前已存在属性,否则会生成当前作用域下的全局变量)
with不改变当前作用域,使用时需要注意作用域)

let obj = {a:1,b:2}
with(obj){
a:3;
b:4;
}

4.函数基础

length
函数形参数量

function test(a,b) {
    return a+b
}
test(1,2,3,4,5)
test.length // 2

arguments
函数形参列表
(只能在函数内部使用)
(正常模式可以在内部修改)
(是一个对象而不是数组)

function test(a,b){
    arguments[0]=2
    arguments[1]=3
    return a+b
}
test(1,1) //5


function test(a,b){
    'use strict'
    arguments[0]=2
    arguments[1]=3
    return a+b
}
test(1,1) //2 严格模式下不改变实际效果

闭包
函数内部的函数
(读取函数内部的变量 且让其一直存在不被回收)
(封装私有变量和方法)
注意:由于闭包不被回收的特性 需要谨慎使用

function f1() {
    let a=9;
    function f2() {
        return a++
    }
    return f2
}
let result = f1()
result() //9
result() //10
result() //11

立即调用的函数表达式(IIFE)
避免污染全局变量
封装私有变量和方法

(function() {}()); //该写法行尾必须加分号

5.数组基础

数组的本质是Object
length
数组成员的个数
(该值可被修改)

let arr = [1,2,3,4]
arr.length = 2
arr // [1,2]
arr.length = 5
arr // [1,2,3,4,undefined]

空位
空位值为undefined时可以被for循环遍历到
[,,]则不会遍历
delete指令删除数组成员后 会留下undefined空位
以上几种情况Array.length都不会改变

let arr = [1,,3]
for(let item in arr){
    console.log(item) // 1,3
}

let arr = [1,undefined,3]
for(let item in arr){
    console.log(item) // 1,undefined,3
}
delete arr[0]
arr //[undefined,undefined,3]

Array的实例方法
push()/unshift()
push() 末尾加 可以操作多个
unshift() 开头加 只能操作一个
(改变当前数组)

pop()/shift()
pop() 删末尾
shift() 删开头
(一次操作一个)
(改变当前数组)

join()
将数组以指定方式拼接为字符串
(不改变当前数组)

let arr = [1,2,3]
arr.join(',')
arr // [1,2,3]
arr = arr.join(',')
arr // '1,2,3'

let arr = [1,undefined,,3]
arr = arr.join(',')
arr // '1,,,3'

concat()
合并数组
(浅拷贝)
(不改变当前数组)

let arr = [1,2,3]
[4].concat(arr) //[4,1,2,3]

reverse()
倒置数组
(改变原数组)

let arr = [1,2,3]
arr.reverse() // [3,2,1]

slice()
提取数组成员返回新数组
(不传参时可对数组浅拷贝)
(不改变当前数组)

let arr = [1,2,3,4,5]
let arr1 = []
arr1 = arr.slice(1,3)
arr // [1,2,3,4,5]
arr1 // [2,3]

splice()
操作数组成员,返回被操作的部分
(单纯添加时返回空数组)
(改变当前数组)

let arr = [1,2,3]
arr.splice(1,1,9) // arr:[1,9,3]
arr.splice(-1,1,9)  // arr:[1,2,9]
arr.splice(1,0,9) // arr:[1,9,2,3]
arr.splice(2) // arr:[1,2] result:[3]

sort()
数组排序
(默认按字典顺序排列)
(改变原数组)

[4,2,3].sort((a,b)=>{
    return a-b // [2,3,4]
})

map()/forEach()
操作数组里的每一个成员
map()返回一个新数组,forEach()没有返回值)
(跳过空位,不跳过undefinednull
map()不改变当前数组,forEach()改变当前数组)

let arr = [1,2,3]
arr.map((item,index,arr)=>{
    return item*index // [0,2,6]
})
arr //[1,2,3]
arr.map((e)=>{
    return this[e] // [1,2,3]
},arr)

filter()
筛选符合条件的成员,返回一个新数组
(不改变当前数组)

let arr = [1,2,3]
let obj - {MAX:2}
arr.filter((item,index,arr)=>{
    return item>1 // [2,3]
})
arr // [1,2,3]

arr.filter(function(item,index,arr){
    return item>=this.MAX // [2,3]
    // 上面这种做法不能使用箭头函数,因为箭头函数this指向不能变化
},obj)

some()/every()
短路方法
(不改变当前数组)
some()有一个true即为true
every()有一个false即为false

reduce()/reduceRight()
处理数组成员,返回一个累积值
前者左到右,后者反之
(不改变当前数组)

let arr = [1,2,3,4]
arr.reduce((a,b)=>{
    return a+b // 10
})

indexOf()/lastIndexOf
indexOf()返回第一次出现的位置
lastIndexOf()返回最后一次出现的位置
(不改变当前数组)
(没有找到返回-1)

6.错误处理机制

几种常见的错误对象
SyntaxError 解析代码时发生的语法错误
ReferenceError 引用不存在的变量的语法错误
RangeError 超出有效范围的错误
TypeError参数或者变量不是预期类型的错误
URIErrorURI相关函数的参数不正确时抛出的错误,主要涉及encodeURI()decodeURI()encodeURIComponent()decodeURIComponent()escape()unescape()这六个函数
EvalError Eval函数未被正确执行的错误
throw
手动中断程序执行,抛出错误

if(true){
    throw new Error('我想抛出错误!') 
    //Uncaught ReferenceError: 我想抛出错误!
}

try...catch...finally
try捕捉异常然后交给catch处理
finally语句存在,不管是否捕捉到异常最后都会执行

try{
    throw '我又想抛出异常了'
}catch(e){
    console.log('知道了,剩下的我来')
}
// 我又想抛出异常了
// 知道了,剩下的我来

FromXTLeo
3 声望0 粉丝