切换主题
字数
2692 字
阅读时间
11 分钟
复习与学习,就是思考这些概念是什么, 有什么联系,用到实际中是怎么样的,然后去实践验证
要分清 前端和后端、客户端和服务端
前端服务器不属于前端, 前端服务器 是后端. 所以nextjs是前端+前端服务器的全栈框架 而react web 是纯前端框架
学习计算机的目的是认识已有计算机系统, 理解的核心是图灵完备,'调用'和'运算'的实现就是满足图灵完备, 一副 跳转给不同算术单元传输信号的 逻辑电路图
学习编程(语言)是为了读懂计算命令,描述计算命令,理解的核心就是语法(结构体和指针,对象和引用,回调和上下文)
学习程序设计是想如何实现有想要的功能的程序,理解的核心是如何组织拆分资源和功能,前端的话资源主要是ui, 后端的话资源主要是数据
三种目的不同,实现行为方式不同,读别人的代码就是自顶向下理解,什么功能,怎么传数据,电路怎么跑 学习就是认知,将原本没有概念的抽象概念在自己的脑子里映射成直观的图
1、文件对于代码运行的影响
在计算机中,文件只是为了人区分用途分割出来的代码片段,对于计算机来说将代码分割成文件还是不分割都是一样的,所以同一后缀名的文件,分割出来对于计算机执行代码没有任何(语法)意义,例如在 React 中声明组件,单独创建出一个 tsx 文件,将其用帕斯卡命名法( PascalCase 也称为大驼峰命名法)命名后,还需要在文件内声明其(文件名)是一个组件,文件名在这里只起到一个为计算机标明位置,为人表面结构的功能 React.FC的功能
2、回调函数的判断依据
函数是否被称为回调函数取决于它被使用的方式。*
回调函数是指在编程中,将一个函数作为参数传递给另一个函数,并在后者执行完特定任务后,调用传入的函数,以完成某些操作或通知。回调函数通常用于异步编程中,用于处理异步操作的结果或事件。
function funcA(param) {
console.log(param);
}
function funcB() {
return "Hello";
} // 在funcA的参数中调用funcB,并将其返回值作为参数传递给funcA
funcA(funcB());
在这段代码中,并没有使用回调函数。回调函数通常是作为参数传递给其他函数,并在特定的事件发生或条件满足时由其他函数调用。在这段代码中,虽然 funcB
返回的值被作为参数传递给了 funcA
,但 funcB
并不是一个回调函数。
实际上,在这段代码中,funcB
只是一个简单的函数,它没有被传递给其他函数作为参数,并且没有在某个事件发生时被调用。因此,它不是一个回调函数。
function a(a: number): number {
console.log(a); return 64;
}
function b(i: number): void {
console.log(i);
} // 先声明函数a和函数b,然后再调用
b(a);
在这段代码中,没有使用回调函数。回调函数是指在异步操作完成后执行的函数,通常作为参数传递给其他函数,在异步操作完成时被调用。
在这个代码片段中,函数 b
被调用并传递了函数 a
作为参数,但是 b
函数本身没有在异步操作完成后调用传入的函数 a
。相反,它将传入的参数直接打印出来。
以下是将函数 a
作为回调函数的一个示例:
typescript
function a(a: number): number {
console.log(a);
return 64;
}
function b(callback: (i: number) => void): void {
const result = callback(42); // 调用传入的回调函数
console.log("Result:", result);
}
// 将函数a作为回调函数传递给函数b
b(a);
在这个示例中:
- 函数
b
接受一个回调函数作为参数,这个回调函数的类型为(i: number) => void
,即接受一个number
类型参数并且没有返回值。 - 在函数
b
中,调用传入的回调函数,并将参数42
传递给它。 - 在函数调用的结果中,将函数
a
作为回调函数传递给了函数b
,这样在函数b
内部就可以调用函数a
。 在 JavaScript 中,通常将一个函数称为回调函数,当它满足以下条件之一时:
- 作为参数传递给其他函数,并在其他函数内部被调用。
- 在某个事件发生时被作为事件处理函数调用。
因此,要判断一个函数是否是回调函数,可以根据上述条件进行检查。例如,可以检查函数是否作为参数传递给其他函数,或者是否被用作事件处理函数。
以下是一个示例,演示如何判断一个函数是否是回调函数:
javascript
function callbackFunction(param) {
console.log(param);
}
function higherOrderFunction(callback) {
// 在这个高阶函数中调用回调函数
callback("This is a callback");
}
// 将函数callbackFunction作为回调函数传递给higherOrderFunction
higherOrderFunction(callbackFunction);
// 另一个示例,判断函数是否用作事件处理函数
document.addEventListener('click', callbackFunction);
函数是否被称为回调函数取决于它被使用的方式。
回调函数是一个术语,用于描述在某些情况下被传递给其他函数的函数。这种情况包括被用作事件处理函数、异步操作的回调函数、或者作为高阶函数的参数。但是,只要一个函数被高阶函数作为参数传递,并不意味着它就是一个回调函数。它还需要在高阶函数内部被调用,才能满足回调函数的定义。
实际上,判断一个函数是否是回调函数,需要综合考虑两个方面:
- 这个函数是否被传递给其他函数作为参数。
- 这个函数是否在其他函数内部被调用。
3.为什么 JavaScript 要加分号(良好的代码编写习惯通用实践)
最常见的错误是 某行没加分号的代码和下一行的小括号连起来,被当成一个调用函数的语句,例如:
js
let a = 3
(function() {
console.log('IIFE')
})()
// 实际上会被解释为:let a = 3(function() { console.log('IIFE') })();
以下是以下常用的编写习惯(通用实践)
有意义的命名
- 变量和函数:使用有意义且描述性的名称,避免使用缩写和模糊的名称。
- 常量:使用大写字母和下划线来命名常量,例如
MAX_COUNT
。
注释
- 必要的注释:在复杂或重要的代码块上添加注释,解释代码的意图和逻辑。
- TODO 注释:使用
TODO
注释标记未来需要改进或实现的地方。
遵循最佳实践
- 避免全局变量:尽量减少使用全局变量,使用局部作用域和闭包来封装变量。
- 模块化代码:将代码分成小的、可重用的模块或函数,每个模块或函数只做一件事(单一职责原则)。
错误处理
- 异常处理:在可能出错的地方使用
try...catch
语句,并提供有意义的错误信息。 - 输入验证:在处理用户输入时,进行充分的验证和消毒,防止安全漏洞。
JavaScript 和 TypeScript
- 严格模式:使用
"use strict";
开启严格模式,帮助捕获常见的错误。 - 箭头函数:尽量使用箭头函数来保持
this
绑定的一致性。 - 类型注解:在 TypeScript 中,尽量为函数和变量添加类型注解,提高代码的可靠性。
HTML
- 语义化标签:使用语义化标签(如
<header>
,<article>
),提高页面结构的可理解性和可访问性。 - 有效的属性:为标签添加必要的属性(如
alt
属性用于<img>
),提高页面的可访问性。
命名约定:
遵循 Java 的命名约定,类名使用大驼峰命名法(如 MyClass
),方法名和变量名使用小驼峰命名法(如 myMethod
)。
4.关于 return 语句的报错
在 return
语句后,JavaScript 引擎会自动插入一个分号,因为它认为 return
语句已经结束。所以实际上它等同于:
js
console.log( function getValue() {
return; // 分号被自动插入
{
value: 42
};
}())
为了让 return
返回一个对象字面量,可以将对象字面量紧跟在 return
之后,或者使用括号包裹对象字面量。
js
console.log( function getValue() {
return {
value: 42
};
}())
或者
js
console.log( function getValue() {
return (
{
value: 42
});
}())
js
const input1 = document.getElementById('input1')
// let timer = null
// input1.addEventListener('keyup', function () {
// if (timer) {
// clearTimeout(timer)
// }
// timer = setTimeout(() => {
// // 模拟触发 change 事件
// console.log(input1.value)
// // 清空定时器
// timer = null
// }, 500)
// })
// 防抖
function debounce(fn, delay = 500) {
// timer 是闭包中的
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
input1.addEventListener('keyup', debounce(function (e) {
console.log(e.target)
console.log(input1.value)
}, 600))
//addEventListener方法接收一个事件和事件发生后所执行的方法,因为想在 input1.addEventListener 中传入的方法经过防抖方法处理,所以在定义防抖函数时有一个形参是函数,且为了让addEventListener接收到函数必须返回一个经过处理后的函数,而不是仅仅只执行一遍逻辑
贡献者
sunchengzhi