【JavaScript】基础知识

JavaScript 基础知识

字符串处理

substring()

用法:提取字符串中介于两个指定下标之间的字符

语法:string.substring(start, stop)

参数:

  • start(必需):一个非负的整数,起始下标(包含)
  • stop(可选):一个非负的整数,结束下标(不包含),默认到字符串末尾

返回值:截取的字符串

示例:

const str = "hello world"
str.substring(0, 5) // 'hello'
str.substring(6) // 'world'

substr()

用法:提取字符串中从开始下标到指定长度的字符

语法:string.substr(start, length)

参数:

  • start(必需):起始下标(包含)
  • length(可选):截取的长度,默认到字符串末尾

返回值:截取的字符串

示例:

const str = "hello world"
str.substr(0, 5) // 'hello'
str.substr(6) // 'world'

注意事项
1. 如果 length 为 0 或负数,将返回一个空字符串
2. 如果 start 或 length 为负数,那么它将被替换为 0

slice()

用法:提取字符串中介于两个指定下标之间的内容

语法:string.slice(start, stop)

参数:

  • start(必需):起始下标(包含),如果是负数,那么它规定从字符串尾部开始算起的位置。也就是说,-1 指最后一个字符,-2 指倒数第二个字符,以此类推
  • stop(可选):结束下标(不包含),默认到字符串末尾,如果这个参数是负数,那么它规定的是从字符串尾部开始算起的字符

返回值:截取的字符串

示例:

const str = "hello world"
str.slice(0, 5) // 'hello'
str.slice(6) // 'world'
str.slice(0, -1) // 'hello worl'
str.slice(-1) // 'd'
str.slice(-5, -2) // 'wor'

split()

用法:将字符串分割成数组

语法:string.split(separator, limit)

参数:

  • separator(可选):分隔符,默认为空格
  • limit(可选):数组返回长度,默认返回全部

返回值:分割后的数组

示例:

const str = "hello world"
str.split(" ") // ['hello', 'world']
str.split("") // ['h', 'e', 'l', 'l', 'o','', 'w', 'o', 'r', 'l', 'd']
str.split("o", 2) // ['hell', 'w']

replace()

用法:替换字符串中指定字符

语法:string.replace(searchValue, replaceValue)

参数:

  • searchValue(必需):需要替换的字符或者 RegExp 对象
  • replaceValue(必需):替换成的字符

返回值:替换后的字符串

示例:

const str = "hello world"
str.replace("world", "world!") // 'hello world!'
str.replace(/world/g, "world!") // 'hello world!'

match()

用法:在字符串中匹配指定字符

语法:string.match(regexp)

参数:

  • regexp:正则表达式对象

返回值:匹配到的字符串数组,如果没有匹配到,返回null

示例:

const str = "hello world"
str.match(/world/g) // ['world']

padStart() / padEnd()

用法:在字符串的开头或结尾填充指定字符

语法:string.padStart(targetLength, padString) / string.padEnd(targetLength, padString)

参数:

  • targetLength(必需):需要填充的长度,如果这个数值小于当前字符串的长度,则返回当前字符串本身
  • padString(可选):填充的字符,默认为空格

示例:

const str = "hello"
str.padStart(10, "*") // '*****hello'
str.padEnd(10, "*") // 'hello*****'

trimStart() / trimEnd()

用法:在字符串的开头或结尾删除空白字符

语法:string.trimStart() / string.trimEnd()

参数:无

返回值:去除空白字符后的结果

示例:

const str = " hello "
str.trimStart() // 'hello '
str.trimEnd() // ' hello'

数组处理

slice()

用法:返回数组中介于两个指定下标之间的内容

语法:array.slice(start, stop)

参数:

  • start(必需):起始下标(包含),如果是负数,那么它规定从字符串尾部开始算起的位置。也就是说,-1 指最后一个字符,-2 指倒数第二个字符,以此类推
  • stop(可选):结束下标(不包含),默认到数组末尾,如果这个参数是负数,那么它规定的是从数组尾部开始算起的字符

返回值:截取后的新数组

示例:

const arr = [1, 2, 3, 4, 5]
arr.slice(0, 2) // [1, 2]
arr.slice(2) // [3, 4, 5]
arr.slice(0, -1) // [1, 2, 3, 4]
arr.slice(-1) // [5]

splice()

用法:在数组中删除元素或删除后追加新的元素

注意事项
会改变原数组

语法:array.splice(start, count,...items)

参数:

  • start(必需):起始下标(包含),可以为负数,负数从末尾开始倒计数
  • count(可选):删除的个数,默认删除到数组末尾,如果为 0 或者负数,则不会执行删除操作
  • items(可选):追加的新元素

返回值:被删除的元素数组

示例:

const arr = ['1', '2', '3', '4', '5']
arr.splice(0, 2) // ['1', '2']
console.log(arr) // ['3', '4', '5']
arr.splice(0, 1, '33', '44') // ['3'] 
console.log(arr) // ['33', '44', '4', '5']

join()

用法:将数组中的元素连接成一个字符串

语法:array.join(separator)

参数:

  • separator(可选):连接符,默认以逗号分割

返回值:连接后的字符串

示例:

const arr = ['1', '2', '3', '4', '5']
arr.join() // '1,2,3,4,5'
arr.join('-') // '1-2-3-4-5'

push()

用法:在数组中添加元素

注意事项
会改变原数组

语法:array.push(item1, item2, ...)

参数:

  • item1:要添加的元素

返回值:无

示例:

const arr = ['1', '2', '3', '4', '5']
arr.push('6')
arr.push('7','8')
console.log(arr) // ['1', '2', '3', '4', '5', '6', '7', '8'])

pop()

用法:删除数组中最后一个元素并返回删除的元素

注意事项
会改变原数组

语法:array.pop()

参数:无

返回值:删除的元素

示例:

const arr = ['1', '2', '3', '4', '5']
arr.pop() // '5'
console.log(arr) // ['1', '2', '3', '4']

shift()

用法:删除数组中第一个元素并返回删除的元素

注意事项
会改变原数组

语法:array.shift()

参数:无

返回值:删除的元素

示例:

const arr = ['1', '2', '3', '4', '5']
arr.shift() // '1'
console.log(arr) // ['2', '3', '4', '5']

unshift()

用法:在数组的开头添加一个或多个元素,并返回数组新的长度

注意事项
会改变原数组

语法:array.unshift(item1, item2,...)

参数:

  • item1:要添加的元素

返回值:新数组的长度

示例:

const arr = ['1', '2', '3', '4', '5']
arr.unshift('6', '7') // 7
console.log(arr) // ['6', '7', '1', '2', '3', '4', '5']

sort()

用法:对数组进行排序

注意事项
会改变原数组,原理可 参考这里

语法:array.sort(compareFunction)

参数:

  • compareFunction(可选):比较函数,默认按照字符编码升序

返回值:数组本身

示例:

const arr = [1, 3, 5, 2, 4]
arr.sort((a,b)=>a-b) // [1, 2, 3, 4, 5] 升序
arr.sort((a,b)=>b-a) // [5, 4, 3, 2, 1] 降序

reverse()

用法:颠倒数组中的元素顺序

注意事项
会改变原数组

语法:array.reverse()

参数:无

返回值:数组本身

示例:

const arr = [1, 3, 5, 2, 4]
arr.reverse() // [4, 2, 5, 3, 1] 升序

concat()

用法:将多个数组合并成一个数组

语法:array.concat(array1, array2,...)

参数:

  • array1(必需):要合并的数组

返回值:数组本身

示例:

const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]
arr1.concat(arr2, [7, 8], 9) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(arr1) // [1, 2, 3]

indexOf()

用法:在数组中查找指定元素的下标(从数组的开头开始查找,找到第一个就返回)

语法:array.indexOf(item)

参数:

  • item:要查找的元素

返回值: 元素下标,如果没有找到,返回-1

示例:

const arr = ['1', '2', '3', '4', '5', '3']
arr.indexOf('3') // 2

注意
在比较过程中,使用全等操作符

lastIndexOf()

用法:在数组中查找指定元素的下标(从数组的末尾开始查找,找到第一个就返回)

语法:array.lastIndexOf(item)

参数:

  • item(必须):要查找的元素

返回值: 元素下标,如果没有找到,返回-1

示例:

const arr = ['1', '2', '3', '4', '5', '3']
arr.lastIndexOf('3') // 5

注意
在比较过程中,使用全等操作符

forEach()

用法:遍历数组中的每一个元素(可以跳出当前的循环,想要终止循环必须要 throw 一个错误)

语法:array.forEach(callback)

参数:

  • callback(必须):回调函数,接收三个参数,第一个是当前元素,第二个是当前元素的下标,第三个是数组本身

返回值: 无

示例:

const arr = ['1', '2', '3', '4', '5']
arr.forEach((item, index, a)=>{
  console.log(item, index, a)
})

map()

用法:遍历数组中的每一个元素,并返回一个新数组(无法跳出循环)

注意:和 forEach 的区别
map 可以再每次循环中使用 return 返回新数组,更适合需要创建新数组的时候使用

语法:array.map(callback)

参数:

  • callback(必需):回调函数,接收三个参数,第一个是当前元素,第二个是当前元素的下标

返回值: 新数组

示例:

const arr = ['1', '2', '3', '4', '5']
const arr2 = arr.map((item, index)=>{
  return item + index
})
console.log(arr2) // ['10', '21', '32', '43', '54']

filter()

用法:过滤数组中的元素,并返回一个新数组

语法:array.filter(callback)

参数:

  • callback(必需):回调函数,接收三个参数,第一个是当前元素,第二个是当前元素的下标

返回值: 数组本身

示例:

const arr = ['1', '2', '3', '4', '5']
const arr2 = arr.filter((item, index)=>{
  return item > 2
}) 
console.log(arr2) // ['3', '4', '5']

fill()

用法:填充数组中指定位置的元素

注意事项
会改变原数组

语法:array.fill(value, start, end)

参数:

  • value(必需):填充的值
  • start(可选):开始下标,默认 0
  • end(可选):结束下标(不包含),默认到数组最后一个元素

返回值: 数组本身

示例:

const arr = ['1', '2', '3', '4', '5']
arr.fill('a', 2, 4) // ['1', '2', 'a', 'a', '5']

every()

用法:判断数组中所有元素是否都满足指定条件

语法:array.every(callback)

参数:

  • callback(必需):回调函数,接收两个参数,第一个是当前元素,第二个是当前元素的下标

返回值:

  • true:所有元素都满足条件
  • false:至少有一个元素不满足条件

示例:

const arr = [1, 2, 3, 4, 5]
arr.every((item, index)=>{
  return item > 0
}) // true

some()

用法:判断数组中是否至少有一个元素满足指定条件

语法:array.some(callback)

参数:

  • callback(必需):回调函数,接收两个参数,第一个是当前元素,第二个是当前元素的下标

返回值:

  • true:至少有一个元素满足条件
  • false:所有元素都不满足条件

示例:

const arr = [1, 2, 3, 4, 5]
arr.some((item, index)=>{
  return item > 2
}) // true

includes()

用法:判断数组中是否包含指定元素

语法:array.includes(item, index)

参数:

  • item(必需):要查找的元素
  • index(可选):开始下标,默认 0

返回值:

  • true:数组中包含指定元素
  • false:数组中不包含指定元素

示例:

const arr = [1, 2, 3, 4, 5]
arr.includes(3) // true
arr.includes(3, 4) // false

reduce()

用法:将数组中的元素进行累加计算,返回计算结果,从数组的第一项开始累加

语法:array.reduce(callback, initialValue)

参数:

  • callback(必需):回调函数,接收四个参数,第一个是累加结果,第二个是当前元素,第三个是当前元素的下标,第四个是数组本身
  • initialValue(可选):初始值,默认第一个元素

返回值: 计算结果

示例:

const arr = [1, 2, 3, 4, 5]
arr.reduce((pre, cur, index, a)=>{
  return pre + cur
}) // 15
arr.reduce((pre, cur, index, a)=>{
  return pre + cur
}, 10) // 25

reduceRight()

用法:将数组中的元素进行累加计算,返回计算结果,从数组的末尾开始累加

语法同 reduce()

find()

用法:查找数组中第一个满足指定条件的元素

语法:array.find(callback)

参数:

  • callback(必需):回调函数,接收两个参数,第一个是当前元素,第二个是当前元素的下标,第三个元素是数组本身

返回值:

  • 找到的元素:返回该元素
  • 未找到的元素:返回 undefined

示例:

const arr = [1, 2, 3, 4, 5]
arr.find((item, index, a)=>{
  return item > 2
}) // 3

findIndex()

用法:查找数组中第一个满足指定条件的元素的下标

语法:array.findIndex(callback)

参数:

  • callback(必需):回调函数,接收两个参数,第一个是当前元素,第二个是当前元素的下标,第三个元素是数组本身

返回值:

  • 找到的元素的下标:返回该元素的下标
  • 未找到的元素的下标:返回-1

示例:

const arr = [1, 2, 3, 4, 5]
arr.findIndex((item, index, a)=>{
  return item > 2
}) // 2

copyWithin()

用法:浅复制数组的一部分到同一数组中的另一个位置,并返回

注意事项
会改变原数组的内容,但原数组长度不变

语法:array.copyWithin(target, start, end)

参数:

  • target(必需):目标位置
  • start(可选):开始下标,默认 0
  • end(可选):结束下标(不包含),默认到数组最后一个元素

返回值: 数组本身

示例:

const arr = [1, 2, 3, 4, 5]
arr.copyWithin(2, 0, 3) // [1, 2, 1, 2, 3]

flat()

用法:将多维数组扁平化

语法:array.flat(depth)

参数:

  • depth(可选):表示要展开的层数,默认1

返回值: 扁平化后的数组

示例:

const arr = [1, 2, [3, 4, [5, 6]]]
arr.flat() // [1, 2, 3, 4, [5, 6]]
arr.flat(2) // [1, 2, 3, 4, 5, 6]

// 使用 Infinity 作为深度,展开任意深度的嵌套数组
arr.flat(Infinity) // [1, 2, 3, 4, 5, 6]

// 利用 flat 去除数组中的空项
const arr2 = [1, 2 , , 4 , 5]
arr2.flat() // [1, 2, 4, 5]

flatMap()

用法:使用映射函数映射每个元素,然后将结果压缩成一个新数组(只会处理一层)

语法:array.flatMap(callback)

参数:

  • callback:回调函数,接收两个参数,第一个是当前元素,第二个是当前元素的下标,第三个元素是数组本身

返回值: 处理后的数组

示例:

  const arr = [1, 2, 3, 4, 5]
  arr.flatMap((item)=>{
    return [item, item * 2]
  }) // [1, 2, 2, 4, 3, 6, 4, 8, 5, 10]

entries()、keys()、values()

用法:遍历数组,返回一个迭代器对象

语法:array.entries()array.keys()array.values()

返回值:迭代器对象

示例:

const arr = ['a', 'b']
console.log(arr.entries()) // [[0, 'a'], [1, 'b']]
for(let [index, item] of arr.entries()){
  console.log(index, item)
}
// 0 a
// 1 b

for(let item of arr.keys()){
  console.log(item)
}
// 0
// 1

for(let item of arr.values()){
  console.log(item)
}
// a
// b

for…in 和 for…of

两者均可以用来遍历数组或对象

  • for…in:遍历的是数组的索引或者对象的 key
  • for…of:遍历的是值

Map处理

是 es6 提供的一种新的数据结构,它类似于对象,也是键值对的集合,但是键的范围不仅限于字符串,各种类型的值都可以
当做键键值对结构,键值对的插入顺序与添加顺序一致,如果后续添加的key重复,则会覆盖原有的值

创建

  1. 带值的初始化:
const map = new Map([['name', 'Bob'], ['age', 12]])
  1. 初始化:
const map = new Map()
map.set('name', 'Bob')
map.set('age', 12)

属性

size: 成员数量

const map = new Map()
map.size // 0
map.set('name', 'Bob')
map.size // 1

实例方法

  1. get():获取指定 key 对应的 value
const map = new Map()
map.set('name', 'Bob')
map.set('age', 12)
map.get('name') // Bob
  1. has():判断是否存在指定 key
const map = new Map()
map.has('name') // false
map.set('name', 'Bob')
map.has('name') // true
  1. clear():清空所有元素
const map = new Map()
map.set('name', 'Bob')
map.set('age', 12)
map.clear()
map.size // 0
  1. delete():删除指定 key 对应的 value
const map = new Map()
map.set('name', 'Bob')
map.set('age', 12)
map.delete('name')
map.size // 1

遍历

for…of循环
keys()、values()、entries()

与 Object 的区别

  • 使用 Map:

    1. 储存的键不是字符串/数字/或者 Symbol 时,选择 Map,因为 Object 并不支持
    2. 储存大量的数据时,选择 Map,因为它占用的内存更小
    3. 需要进行许多新增/删除元素的操作时,选择 Map,因为速度更快
    4. 需要保持插入时的顺序的话,选择 Map,因为 Object 会改变排序
    5. 需要迭代/遍历的话,选择 Map,因为它默认是可迭代对象,迭代更为便捷
  • 使用 Object:

    1. 只是简单的数据结构时,选择 Object,因为它在数据少的时候占用内存更少,且新建时更为高效
    2. 需要用到 JSON 进行文件传输时,选择 Object,因为 JSON 不默认支持 Map
    3. 需要对多个键值进行运算时,选择 Object,因为句法更为简洁
    4. 需要覆盖原型上的键时,选择 Object

Set 处理

类似数组,但是没有重复的值,并且无序

创建

  1. 带值的初始化:
const set = new Set([1, 2, 3])
  1. 初始化:
const set = new Set()
set.add(1)
set.add(2)
set.add(3)

属性

size: 成员数量

const set = new Set()
set.size // 0
set.add(1)
set.size // 1

实例方法

  1. add():添加元素
const set = new Set()
set.add(1)
set.add(2).add(3)
  1. delete():删除元素
const set = new Set()
set.add(1)
set.delete(1) // true
  1. has():判断是否存在指定元素
const set = new Set()
set.add(1)
set.has(1) // true
  1. clear():清空所有元素
const set = new Set()
set.add(1)
set.clear()
set.size // 0

call()、apply()、bind()

都是用于改变函数的this指向,不同点在于传参方式以及返回值不同

注意事项
若不向方法的第一个参数传值或者传递 undefined、null,则在 JavaScript 正常模式下,目标函数内部的 this 指向 window 对象,严格模式下,分别指向 undefined、null

call()

语法:函数名.call(param1, param2, ...paramN)

参数:

  • param1:this 要指向的对象
  • param2~paramN:函数所需要的参数

返回值:返回调用函数的返回结果,属于立即执行函数

//此处声明若用 let,则第一个调用函数输出 undefined,
//因为此处 let 声明的变量虽然也是全局变量但其不会成为全局对象 window 的属性,故 say() 直接调用时为undefined
var word = "我是window";
function say(params1,params2){
	console.log(params1+" "+params2+","+this.word)
}
let obj = {
	word: "我是obj"	
}
let newObj= {
	word: "我是newObj"	
}
say("Hi","friend"); // Hi friend,我是我是window // let声明 则输出:Hi friend,undefined
say.call(obj,"Hi","friend")  // Hi friend,我是obj
say.apply(newObj,["Hi","friend"])  // Hi friend,我是newObj

apply()

语法:函数名.apply(param1, param2)

参数:

  • param1:this 要指向的对象
  • param2:函数所需要的参数组成的数组

返回值:返回调用函数的返回结果,属于立即执行函数

//此处声明若用 let,则第一个调用函数输出 undefined,
//因为此处 let 声明的变量虽然也是全局变量但其不会成为全局对象 window 的属性,故 say() 直接调用时为undefined
var word = "我是window";
function say(params1,params2){
	console.log(params1+" "+params2+","+this.word)
}
let obj = {
	word: "我是obj"	
}
let newObj= {
	word: "我是newObj"	
}
say("Hi","friend"); // Hi friend,我是我是window // let声明 则输出:Hi friend,undefined
say.call(obj,"Hi","friend")  // Hi friend,我是obj
say.apply(newObj,["Hi","friend"])  // Hi friend,我是newObj

bind()

语法:函数名.bind(param1, param2, ...paramN)

参数:

  • param1:this 要指向的对象
  • param2~paramN:函数所需要的参数

返回值:返回新的函数

var word = "我是window";
function say(params1,params2){
	console.log(params1+" "+params2+","+this.word)
}
let Obj1= {
	word: "我是newObj1"	
}
let Obj2= {
	word: "我是newObj2"	
}
//返回一个新的函数
let newFunc = say.bind(Obj1,"hello","friend"); 
newFunc()   // hello friend,我是 newObj1

// 可将其改为立即执行函数,此时返回和call(),apply()相同
say.bind(Obj2,"hello","friend")();   // hello friend,我是 newObj2

let、var

相同点

两者都是声明变量的,其中let是es6中出现的

不同点

  1. 作用域不同

    • var:函数作用域+全局作用域
    • let: 块级作用域(es6 新增)
  2. let 不能在定义之前访问,但 var 可以(因为var有变量提升,也就是预解析)

    console.log(a) // 预解析只声明不复制 undefined
    var a = 10 // var 后面的变量,变量提升了(也就是预解析了)
    console.log(a) // 10
    console.log(b) // 报错(Uncaught ReferenceError: Cannot access 'b' before initialization),let声明的变量不能在定义(初始化)之前访问
    let b = 20
    
  3. let不能被重新定义,但var可以

    let a = 10
    let a = "你好" // 报错(Uncaught SyntaxError: Identifier 'a' has already been declared)let后面的变量不能重新定义,var可以
    console.log(a)
    var b = 10
    var b = "你好"
    console.log(b)
    

js中的原型和原型链

// 定义函数对象(也就是构造函数)
function Person(name, age){
  this.name = name;
  this.age = age;
  this.eat = function(food){
    console.log(`${this.name}在吃${food}`);
  }
}

// 通过原型对象 prototype 给 Person 类添加属性和方法
Person.prototype.city = '中国'
Person.prototype.sleep = function(){
  console.log(`${this.name}正在睡觉`)
}

// 定义实例对象(一个普通对象)
let person = new Person('张三', 18);
person.sleep(); // 张三正在睡觉
person.eat('苹果'); // 张三在吃苹果
person.city; // 中国

  • prototype
    定义:每个函数都有一个 prototype 属性,被称作原型,prototype 原型指向一个对象,所以也被称为原型对象

    只有函数对象才会拥有该属性,原型对象(Person.prototype)是构造函数(Person)的一个实例

  • __proto__

    JS 在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的构
    造函数的原型对象

Person.prototype.constructor === Person // true
person.constructor === Person // true
person.__proto__ === Person.prototype // true  
person.__proto__.__proto__ === Object.prototype // true


// 以下三个成立,是因为 Person、Object、Function 都是函数对象,是通过 new Function() 创建的
// 其中 Function 比较特殊,自己创建自己
Person.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true  
Function.__proto__ === Function.prototype // true

Person.prototype.__proto__ === Object.prototype // true
Function.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null // true  原型链的尽头是 null

原型链原理:

  1. 当我查找 person 实例的 city 属性时,会先再这个person对象本身属性上查找,如果没有找到,就去person.__proto__上找(也就是Person.prototype原型对象),直到最顶层Object.prototype.__proto__null时停止
  2. 如果对象自身和它的原型都定义了同一个属性名,那么优先读取对象自身的属性,这叫做“覆盖”

总结:

  • 原型和原型链是 JS 实现继承的一种模型
  • 原型链的形成是真正是靠__proto__而非prototype
  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值