JS小字典

424 阅读8分钟

主要内容:

目录如下,右侧导航

  • Javascript字符串
  • 数组对象常用方法
  • 正则表达式
  • typeof
  • 8/16进制
  • Infinity/NaN
  • 其他类型值转为boolean
  • 优先级
  • 预定义函数
  • 变量提升
  • 闭包
  • call和apply
  • 原型链
  • 继承
  • module

字符串对象

说明:下面RegExp/string的方法中,会自动将string传到reg(正则)的构造函数中转换成正则。

属性/方法 描述
length 字符串长度。
charAt(n) 返回在指定位置的字符。
substring(start, end) 截取字符串的某一部分,返回的字符串要头不要尾[start,end)。第二个参数可选,默认[start,length)。
slice(start, end) 与上面👆一样,能为负数更灵活。如果是负数,从尾部开始算起的位置。-1 指字符串的最后一个字符,-2 指倒数第二个字符,以此类推。
indexOf(string, n) 要检索的字符串,第二个字符可选,规定从下标n开始。返回下标。
lastIndexOf(string,n) 从后往前检索,用法与上面👆一致。返回下标。
match(string/reg) 与上面两个👆👆类似。返回匹配结果的数组,数组的内容依赖于 RegExp 是否有全局标志 g。
search(string/reg) 返回第一个与 regexp 相匹配的子串的起始位置。
replace(string/reg,replaceStr) 只替换第一个!!!返回替换后的字符串。
split(string/reg,n) n可选,指定返回数组的最大长度。返回分割后的数组。
toLowerCase() 转小写
toUpperCase() 转大写
valueOf() 返回对象的原始值,和toString方法会在一些情况下会自调用。应用
str.concat(string,…) 必需,一个或多个。没什么鬼用,用+不是更好吗
'haha'.split()
// ['haha']
'haha'.split('')
// ['h', 'a', 'h', 'a']

数组

不改变原数组的方法
  • slice()---选取数组的的一部分,并返回一个新数组。
  • join()---把数组的所有元素放入一个字符串。
  • concat()---连接两个或更多的数组,并返回结果。
  • map()---通过指定函数处理数组的每个元素,并返回处理后的数组。
  • filter()---检测数组元素,并返回符合条件所有元素的数组。
  • every()---检测数组元素的每个元素是否都符合条件。
  • some()---检测数组元素中是否有元素符合指定条件。
  • includes()---返回true或false。
  • indexOf()---搜索数组中的元素,并返回它所在的位置。
  • lastIndexOf()---返回一个指定的字符串值最后出现的位置,在一个字符串中的指定位置从后向前搜索。
  • valueOf()---返回数组对象的原始值。
  • toString()---把数组转换为字符串,并返回结果
  • find()---返回复合条件的第一个元素,后面的不再执行。没有符合条件的返回undefined
    • find(function(currentValue, index, arr),thisValue)
改变原数组的方法
  • pop()---删除数组的最后一个元素并返回删除的元素。
  • push()---向数组的末尾添加一个或更多元素,并返回新的长度。
  • shift()---删除并返回数组的第一个元素。
  • unshift()---向数组的开头添加一个或更多元素,并返回新的长度。
  • reverse()---反转数组的元素顺序。
  • sort(func)---对数组的元素进行排序。按数字大小排序一定要写function
  • splice()---用于插入、删除或替换数组的元素。
示例
var a = ['', 2, '2']
var res = a.every((value, index, arr) => {
  if(!value)
    console.log(index) // 0
  console.log(a) // ['', 2, '2']
  return !!value
})
res // false
var arr = [ "George", "John", "Thomas", "James", "Adrew", "Martin" ]
arr.splice(2,0,"William")
// George,John,William,Thomas,James,Adrew,Martin

正则表达式

符号 说明 例子 匹配的字符
^n 开始 /^1/ 12\1\122
n$ 结束 /1$/ 21\1\311
. 一个任意字符 /^a.a$/ aqa\asa
[^nnnn] 集合外的字符(单个) /^[^123]$/ 4\5\7
(reg|reg|reg) 任意一个匹配 /^(.|.a|1{2})$/ w\4a\11
i 对大小写不敏感 /^sad$/i Sad\sad\SAD
g 不是找到第一个就停

支持正则的string对象方法

  • search
  • replace
  • split
  • match
//search
'asddcada'.search(/.d/g)  //1
'asddcada'.search(/.d/i)  //1

//replace
'asddcada'.replace(/.d/i,' ')  // 'a dcada'
'asddcada'.replace(/.d/g,' ')  // 'a dc a'

//aplit
'asddcsda'.split(/.d/i)  //['a', 'dc', 'a']
'asddcsda'.split(/.d/g)  //['a', 'dc', 'a']

//match
'asddcsda'.match(/.d/i)  //['sd', index: 1, input: 'asddcsda', groups: undefined]
'asddcsda'.match(/.d/g)  //['sd', 'sd']

时间对象

方法 描述
getFullYear() / setFullYear() 获取年份  /  设置年月日
getMonth() / setMonth() 获取月份(0-11) /  设置月日
getDate() / setDate() 获取日数 / 可以设置日数
getHours() getMinutes() getSeconds()
setHours() setMinutes() setSecond()
getDay() 获取今天星期几,返回数字0-6    0代表星期天

其他后续补充


typeof

可能返回的值:

  • 'number'
  • 'string'
  • 'boolean'
  • 'undefined'
  • 'object'
  • 'function'
typeof null // 'object'

// 如果a没有声明
typeof a // 'undefined'

但当你判断一个变量的类型时会遇到一些问题,如下例

var str1 = new String('js');
var str2 = 'js';
typeof str1; //object
typeof str2; //string
str1 instanceof String; //true
str2 instanceof String; //false
// typeof 用在一些通过new表达式生成的变量,输出为object
// instanceof 只能判断是否为Object、String、Array、Date等等或是用户通过构造函数自定义的类,而不能判断基本数据类型,基本数据类型不属于任何类

// 一个相对周全的办法
function isString(str){
    return (typeof str == 'string')||(str instanceof String)
}

预定义函数

js引擎的一组可供随时调用的内建函数

  • parseInt()
  • parseFloat()
  • isNaN()
  • isFinite()
  • encodeURI()
  • decodeURI()
  • encodeURIComponent()
  • dncodeURIComponent()
  • eval()
parseInt
parseInt('123') // 123
parseInt('a123') // NaN

parseInt('987', 8)
// NaN
parseInt('212', 8)
// 138
parseInt('212', 9)
// 173

// 0x开头会默认以16进制
parseInt('098')
// 98
parseInt('0377')
// 377
parseInt('0x377')
// 887
isNaN
isNaN('abv')
// true
isNaN(NaN)
// true
isNaN('1233m')
// true
isNaN('123')
isFinite
// 检查输入是否是一个既非Infinity也非NaN的数字
// 参数数字、数字字符串、null、true、false的时候 
isFinite()
eval
// eval会将输入的字符串当做js代码来执行
eval('var li = 2;');
li
2
// eval可以用来深拷贝吗?
// 要考虑安全性和性能方面的问题

call & apply

这俩兄弟没啥区别,就是在传参数时,前者是平铺,后者是数组。 如果只传一个参数的话,就是代表指向的是这个参数,如果不想传第一个的话需要传一个null代表指向的是全局对象。

// 首先一个常用的用法是:用他们来触发函数
myfunc.call(this, ...args)
myfunc.apply(this, args)

// 第二个用法:利用他们来调用另一个对象的方法,据为己用
var obj = {
    name: 'Judy',
    say: function(who) {
        return "Hello, "+ who + ", I'm " + this.name
    }
}
obj.say('Tony')
// Hello, Tony, I'm Judy

var myObj = {name: 'Sam'}
obj.say.apply(myObj, ['Tony'])
obj.say.apply(myObj, 'Tony')
// Hello, Tony, I'm Sam

arguments 的特征只有数组的length属性

function func() {
    var args = [].slice.call(arguments)
    return args.reverse()
}

小数的处理

javascript进行科学计数法转换,保留有效位小数点(四舍五入/五舍六入/向下或向上取整)

四舍五入

Math.round('4.212'*100)/100  //4.21
Math.round('4.218'*100)/100  //4.22

五舍六入

toFixed()
2..toFixed(2) //2.00
2.3.toFixed(2) //2.30

2.31.toFixed(2) //2.31
2.31213.toFixed(2) //2.31
2.31567.toFixed(2) //2.31
2.3165.toFixed(2) //2.32

2.toFixed(2)
// Uncaught SyntaxError: Invalid or unexpected token
'2.21'.toFixed(2)
// Uncaught TypeError: "200.825".toFixed is not a function


-2..toFixed(2) //-2.00
-2.3.toFixed(2) //-2.30
...
// 下面一样

截取

巧用向下取整
Math.floor('4321'*100)/100 //4321
Math.floor('4.212'*100)/100 //4.21
Math.floor('4.218'*100)/100 //4.21
Math.floor(4321*100)/100 //4321
Math.floor(4.212*100)/100 //4.21
Math.floor(4.218*100)/100 //4.21

Math.floor('-4.218'*100)/100 //-4.22
Math.floor('-4.212'*100)/100 //-4.22
向上取整
Math.cell('-4.212'*100)/100 //-4.22
正则表达式(负数不行)
Number(15.7784514000.toString().match(/^\d+(?:\.\d{0,2})?/)) // 15.77
Number('15.7784514000'.toString().match(/^\d+(?:\.\d{0,2})?/)) //  15.77

Number('15.7'.toString().match(/^\d+(?:\.\d{0,2})?/)) // 15.7
Number('15'.toString().match(/^\d+(?:\.\d{0,2})?/)) // 15
丢掉小数部分
parseInt('-98.312'*2/2) // -98
parseInt('-98.912'*2/2) // -98

parseInt('-98.7766'*100)/100 // -98.77

8/16进制

// 0开头 就会把后面的当成8进制
let n = 0377
n // 255

n = -0377
n // -255

n = 097
n // 97

// 0x开头 就会吧后面的当成16进制
n = 0xff
n //255

进制转换见parseInt


其他类型值转为布尔为falsy的情况

// 为false的情况以下五种
!!''
!!null
!!undefined
!!0
!!NaN

// 注意这些'奇怪'的情况
NaN == NaN //false
!!Infinity //true

变量提升

先看以下代码,可能想当然的以为先alert(123),但其实并不是的。这里会有变量提升,虽然在第一个alert调用时,a没有在函数内被定义,但是变量本身已经存在于本地空间了,值为undefined并且覆盖了同名的全局变量。

var a = 123
function f() {
    alert(a)
    var a = 1
    alert(a)
}
f()

闭包

利用闭包实现迭代器

function setup(x) {
    var i = 0
    return function() {
        return x[i++]
    }
}

var next = setup(['a', 'b', 'c'])

原型

__proto__prototype的区别:

function Foo(){}
// Foo.prototype Foo的对象属性
// 当使用new Foo()来构造Foo的实例的时候,构造器的prototype属性会用做实例的原型 __proto__
[].__proto__ === Array.prototype
// true  即:实例的__proto__指向构造函数.prototype

Object.prototype.__proto__ === null
// true

// 注意:这里子对象.prototype.__proto__指向父对象.prototype
// 实例的__proto__指向构造函数.prototype
// 最内一层最终会指向Object.prototype,
// Object.prototype.__proto__指向null,结束链

慕课视频截图
可能表达得不清楚,送你去看大佬视频


继承

参考上面原型链的图学习下面代码

function Animal(){
    this.animal = 'animal'
}
function Fish(){
    this.fish = 'fish'
}
function SaltedFish(){
    this.name = 'saltedFish'
}

SaltedFish.prototype = new Fish()
Fish.prototype = new Animal()
// 这里的SaltedFish并不能继承Animal因为,他是继承的Fish的实时实例

// 另外当我们对prototype完全替换时可能会对constructor属性产生副作用,我们需要对constructor进行重置
Fish.prototype.constructor = Fish
SaltedFish.prototype.constructor = SaltedFish

let sf = new SaltedFish()

sf.constructor === SaltedFish
SaltedFish.constructor === Function

// test
sf.__proto__ === SaltedFish.prototype
sf.__proto__.__proto__ === Fish.prototype
sf.__proto__.__proto__.__proto__ === Object.prototype
sf.__proto__.__proto__.__proto__.__proto__ === null

module

export

util.js

let a = 1
// 错误写法,相当于 export 1
export a    
// 正确
export { a } 
expert let b = 2

func.js

// 报错
import a from './util'

// 正确
import {a} from './util'
a  // 1

import {a as aFunc} from './util'
aFunc  // 1
a  // undefined

import * as utils from './util'
utils.a  // 1

import './util'  // 会将util文件从头到尾执行一遍

export default

utils.js

export default function getUserName() {}  // 输出
import getUserName from 'getUserName'  // 输入

export function getUserName() {}  // 输出
import {getUserName} from 'getUserName'  // 输入