《前端》JavaScript 中 10 个需要掌握基础的问题

本文介绍了JavaScript中如何从数组中移除特定项,包括删除单个匹配项和所有匹配项的方法。同时,讲解了使用jQuery或纯JS进行页面重定向,以及理解JavaScript闭包的工作原理,包括闭包在函数式编程、事件处理、模块化等场景的应用。此外,还展示了闭包如何保持对变量的引用,以及在不同示例中的行为。
摘要由CSDN通过智能技术生成

https://github.com/qq449245884/xiaozhi JavaScript 是一种客户端编程语言。
1.如何从数组中移除一个特定的项
思路:首先,使用indexOf查找要删除的数组元素的索引(index),然后使用splice方法删除该索引所对应的项。
splice()是一个非纯函数,通过删除现有元素和/或添加新元素来更改数组的内容。
const array = [2, 5, 9]
const index = array.indexOf(5)
if (index > -1) {
array.splice(index, 1)
}
console.log(array)// [ 2, 9 ]
splice的第二个参数是要删除的元素数量。
注意,splice会在适当的位置修改数组,并返回一个包含已删除元素的新数组。
接着,我们可以来完善一下。
下面有两个函数,第一个函数仅删除一个匹配项(即从[2,5,9,1,5,8,5]中删除第一个匹配项5),而第二个函数则删除所有匹配项:
// 仅删除第一个匹配项
function removeItemOnce (arr, value) { let index = arr.indexOf(value)
if (index > -1) { arr.splice(index, 1) } return arr}// 删除所有匹配项
function removeItemAll (arr, value) { let i = 0
while(i < arr.length) {
if (arr[i] === value) {
arr.splice(i, 1) } else { ++i } }}删除数组中索引i处的元素:删除数组中索引i处的元素:
array.splice(i, 1)如果你想从数组中删除值为number的每个元素,可以这样做:for (let i = array.length - 1; i>=0; i–) {
if (array[i] === number) { array.splice(i, 1) }}如果你只想使索引i处的元素不再存在,但又不想更改其他元素的索引:delete array[i]2. 如何使用 jQuery 或纯 JS 将用户从一个页面重定向到另一个页面jQuery 不是必需的,window.location.replace(…)最适合模拟 HTTP 重定向。window.location.replace(…)优于使用window.location.href,因为replace()不会将原始页面保留在会话历史记录中,这意味着用户将不会陷入永无休止回退按钮。如果要模拟单击链接,可以使用location.href,如果要模拟HTTP重定向,请使用location.replace。事例:

//模拟HTTP重定向
window.location.replace(“http://stackoverflow.com”)
// 模拟单击链接
window.location.href = “http://stackoverflow.com”
你还可以这样做:
$(location).attr(‘href’, ‘http://stackoverflow.com’)

3.JavaScript 闭包是如何工作的闭包是一个函数和对该函数外部作用域的引用(词法环境),词法环境是每个执行上下文(堆栈)的一部分,并且是标识符(即局部变量名称)和值之间的映射。JavaScript 中的每个函数都维护对其外部词法环境的引用。此引用用于配置调用函数时创建的执行上下文。不管何时调用函数,该引用使函数内的代码能够查看在函数外声明的变量。在下面的代码中,inner与调用foo时创建的执行上下文的词法环境一起形成一个闭包,并对外部隐藏了变量secret:function foo() { const secret = Math.trunc(Math.random()*100) return function inner() { console.log(The secret number is ${secret}.) }}const f = foo() // secret 不能从foo 外部直接访问f() // 访问 secret 的唯一办法就是调用 f换句话说,在JavaScript中,函数带有对私有状态的引用,只有它们(以及在相同的词法环境中声明的任何其他函数)可以访问该私有状态。这个状态对函数的调用者是不可见的,这为数据隐藏和封装提供了一种优秀的机制。请记住,JavaScript中的函数可以像变量一样传递,这意味着这些功能和状态的对可以在程序中传递:类似于在c++中传递类的实例。如果JavaScript没有闭包,则必须在函数之间显式传递更多状态,从而使参数列表更长,代码更冗余。所以,如果你想让一个函数总是能够访问私有状态,你可以使用一个闭包,我们经常想把状态和函数联系起来。例如,在Java或c++中,当你向类添加私有实例变量和方法时,这是将状态与功能关联起来。在 C 语言和大多数其他编程语言中,函数返回后,由于堆栈被销毁,所有的局部变量都不再可访问。在JavaScript中,如果在另一个函数中声明一个函数,那么外部函数的本地变量在返回后仍然可以访问。这样,在上面的代码中,secret在从foo返回后仍然对函数对象内部可用。闭包在需要与函数关联的私有状态时非常有用。这是一个非常常见的场景,JavaScript直到2015年才有类语法,它仍然没有私有字段语法,闭包满足了这一需求。私有实例变量在下面的事例中,函数 toString 隐藏了 Car 类的一些细节。
function Car(manufacturer, model, year, color) { return { toString() { return ${manufacturer} ${model} (${year}, ${color}) } }}const car = new Car(‘Aston Martin’,‘V8 Vantage’,‘2012’,‘Quantum Silver’)console.log(car.toString())函数式编程在下面的代码中,函数inner隐藏了fn和args。function curry(fn) { const args = [] return function inner(arg) { if(args.length === fn.length) return fn(…args) args.push(arg) return inner }}function add(a, b) { return a + b}const curriedAdd = curry(add)console.log(curriedAdd(2)(3)()) // 5面向事件的编程在以下代码中,函数onClick隐藏了变量BACKGROUND_COLOR。const $ = document.querySelector.bind(document)const BACKGROUND_COLOR = 'rgba(200,200,242,1)'function onClick() { KaTeX parse error: Expected 'EOF', got '}' at position 45: …ACKGROUND_COLOR}̲(‘button’).addEventListener(‘click’, onClick)Set background color模块化在下面的示例中,所有实现细节都隐藏在一个立即执行的函数表达式中。函数tick和toString隐藏了私有状态和函数,它们需要完成自己的工作。闭包使我们能够模块化和封装我们的代码。let namespace = {};(function foo(n) { let numbers = [] function format(n) { return Math.trunc(n) } function tick() { numbers.push(Math.random() * 100) } function toString() { return numbers.map(format) } n.counter = { tick, toString }}(namespace))const counter = namespace.countercounter.tick()counter.tick()console.log(counter.toString())事例 1:此示例演示局部变量未在闭包中复制。 闭包保留对原始变量本身的引用。 似乎即使外部函数退出后,堆栈仍在内存中保留。function foo () { let x = 42 let inner = function () { console.log(x) } x = x + 1 return inner}let f = foo()f()事例 2:在下面的代码中,三种方法log ,increment 和update 都在同一词法环境闭包中。function createObject() { let x = 42; return { log() { console.log(x) }, increment() { x++ }, update(value) { x = value } }}const o = createObject()o.increment()o.log() // 43o.update(5)o.log() // 5const p = createObject()p.log() // 42事例 3:如果使用的变量是使用var声明的,需要注意的一点是,使用var声明的变量被提升。 由于引入了let和const,这在现代JavaScript 中几乎没有问题。在下面的代码中,每次循环中,都会创建一个新的inner函数,变量i被覆盖,但是因var会让 i 提升到函数的顶部,所以所有这些inner函数覆盖的都是同一个变量,这意味着i(3)的最终值被打印了三次。function foo () { var result = [] for (var i = 0; i < 3; i++) { result.push(function inner () { console.log(i) }) } return result}const result = foo()for(var i = 0; i < 3; i

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值