JS知识小笔记

目录

一、作用域(可拓展)

二、闭包

1.闭包(Closure)

2.闭包的使用场景

3.闭包的实际应用(可拓展)

4.闭包的缺陷

三.this

四.面向过程和面向对象

5. 模块化 (import / export)

6. Promise

7. async / await

8. Class (类)

总结

实践建议


提示:以下是本篇文章正文内容,下面案例可供参考

一、作用域(可拓展)

作用域决定了变量、函数和对象在代码中的可访问性。JavaScript中的作用域分为以下几种:

  • 全局作用域
  • 函数作用域
  • 块级作用域
  • 词法作用域
  • 模块作用域
  • 动态作用域
  • 作用域链

二、闭包

1.闭包(Closure)

是指一个函数能够访问并记住其词法作用域(Lexical Scope),即使这个函数在其词法作用域之外执行。闭包是 JavaScript 中非常强大的特性,它允许函数“记住”并访问定义时的环境,即使这个环境已经不再存在。

const foo = ()=>{
    var arr=[];
    var i;
    for (i=0;i<10;i++){
        arr[i]=function In(){
           console.log(i);
           
        }
    }
    return arr[0];
}
   

 在这个代码中,由于内部函数In调用外部变量i 即使foo函数执行完毕,var i 仍会被In记住,此时In就形成了一个闭包

2.闭包的使用场景

-当使用FP的时候基本就会使用闭包

-当一个函数执行,和上下文相关,就有闭包

-闭包是用来保存执行环境的,也包括环境内的变量

3.闭包的实际应用(可拓展)

3.1.1 数据封装

3.1.2 回调函数

3.1.3 函数柯里化

3.1.4 模块模式

4.闭包的缺陷

影响性能:过度使用闭包尤其是循环创建会降低性能

内存泄漏:闭包会导致其词法作用域中的变量无法被垃圾回收,从而可能导致内存泄漏


三.this

非严格模式this

普通函数被调用时,因为全局的方法和属性都是window对象的方法和属性,所以this指向全局对象(浏览器中的window),严格模式下,this的值是undefined。

函数调用对象this

当函数作为对象的方法调用时,this指向该对象。

当函数作为构造函数调用时,this指向新创建的对象。(函数通过new关键字调用,this指向新创建的实例对象)

箭头函数中的this

首先,箭头函数没有自己的this,全局作用域下,箭头函数的this指向全局对象,而在对象的方法中使用箭头函数时,this指向定义箭头函数时所在上下文的this值。

注意

  • 箭头函数没有自己的 arguments对象。

  • 不能用作构造函数(不能用 new调用)。

  • 没有 prototype属性。

事件处理函数中的this

在DOM事件处理函数中,this默认指向触发事件的DOM元素。


显式绑定this

call,apply,bind可以显式的绑定this指向特定对象。


四.面向过程和面向对象

1.JS对象的创建

//JS对象的创建
Object.create();
var bar = {};
new 关键字;
//三者的区别
Object.create()创建了一个对象

let p =  Object.create(q) ; // ->p._proto_===q;

旧的var声明有作用域混乱、变量提升等问题。

p的原型指向q; //原型链

当需要调用p对象的一个方法或属性时,如果p上没有则去q 

5. 模块化 (import / export)

为什么需要?

将代码拆分成独立的模块,便于管理、复用和维护,避免全局污染。

  • 导出(export

// module.js
// 1. 命名导出(可以有多个)
export const apiKey = '123abc';
export function sum(a, b) { return a + b; }
export class Person {}

// 或统一导出
const apiKey = '123abc';
function sum(a, b) { return a + b; }
export { apiKey, sum }; // 推荐此方式

// 2. 默认导出(只能有一个)
export default function() { console.log('默认导出'); }
// 或
const myFunc = () => {};
export default myFunc;

导入(import

// app.js
// 1. 导入命名导出(必须用花括号,名字要匹配)
import { apiKey, sum } from './module.js';
// 重命名
import { apiKey as key, sum as add } from './module.js';
// 全部导入为一个对象
import * as module from './module.js';
console.log(module.apiKey);

// 2. 导入默认导出(不用花括号,名字任意)
import myFunction from './module.js';

// 3. 混合导入
import myFunction, { apiKey, sum } from './module.js';

6. Promise

为什么需要?

解决传统回调函数的“回调地狱”问题,用更优雅的方式处理异步操作。

  • 三种状态pending(进行中)、fulfilled(已成功)、rejected(已失败)。

  • 基本用法

const myPromise = new Promise((resolve, reject) => {
  // 执行异步操作,比如网络请求
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve('操作成功!'); // 状态从 pending -> fulfilled
    } else {
      reject('操作失败!');  // 状态从 pending -> rejected
    }
  }, 1000);
});

// 使用 .then() 处理成功,.catch() 处理失败
myPromise
  .then(result => {
    console.log(result); // "操作成功!"
  })
  .catch(error => {
    console.error(error); // "操作失败!"
  })
  .finally(() => {
    console.log('无论如何都会执行'); // 清理工作
  });

doSomething()
  .then(result => doSomethingElse(result))
  .then(newResult => doThirdThing(newResult))
  .then(finalResult => console.log(`最终结果: ${finalResult}`))
  .catch(error => console.error(`错误: ${error}`));
// 清晰、线性,避免了层层嵌套的回调

Promise.all([promise1, promise2, promise3]) // 全部成功才成功,一个失败就失败
  .then(values => { /* values 是结果的数组 */ });

Promise.race([promise1, promise2]) // 哪个先完成就用哪个的结果
  .then(value => { /* 第一个完成的结果 */ });

Promise.allSettled([promise1, promise2]) // 等全部完成,无论成功失败
  .then(results => { /* 包含状态和结果的数组 */ });

7. async / await

为什么需要?

让异步代码的写法像同步代码一样直观,是基于 Promise 的语法糖。

  • 基本规则

    • async函数总是返回一个 Promise

    • await只能在 async函数内部使用,它会暂停函数的执行,等待 Promise 完成,并返回结果。

  • 用法

// 用 async/await 重写上面的 Promise 链
async function doTasks() {
  try {
    const result = await doSomething(); // 等待 doSomething() 完成
    const newResult = await doSomethingElse(result); // 用上一个结果继续
    const finalResult = await doThirdThing(newResult);
    console.log(`最终结果: ${finalResult}`);
  } catch (error) {
    console.error(`错误: ${error}`);
  } finally {
    console.log('清理工作');
  }
}

doTasks(); // 调用 async 函数返回的也是 Promise
  • 优点:代码完全是线性的,没有回调,可读性极强。

  • 并行处理

async function fetchData() {
  // 顺序执行(一个接一个)
  const user = await fetchUser();
  const posts = await fetchPosts();

  // 并行执行(同时开始)
  const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
}

8. Class (类)

为什么需要?

为 JavaScript 提供更接近传统面向对象语言的、清晰的语法来创建对象和处理继承。

  • 基本语法

class Person {
  // 构造函数
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  // 实例方法(添加到原型上)
  greet() {
    return `你好,我是${this.name}`;
  }

  // 静态方法(属于类本身,实例不能调用)
  static info() {
    return '这是一个Person类';
  }
}

const p1 = new Person('元', 1);
console.log(p1.greet()); // "你好,我是元"
console.log(Person.info()); // "这是一个Person类"

继承

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // 必须先调用父类的 constructor
    this.grade = grade;
  }

  // 重写父类方法
  greet() {
    return super.greet() + `,是一名${this.grade}年级学生。`;
  }
}

const s1 = new Student('小明', 18, '高三');
console.log(s1.greet()); // "你好,我是小明,是一名高三年级学生。"

Getter / Setter

class Rectangle {
  constructor(width, height) {
    this._width = width;
    this._height = height;
  }

  get area() { // 像属性一样访问
    return this._width * this._height;
  }

  set width(value) { // 像属性一样设置
    if (value > 0) this._width = value;
  }
}

const rect = new Rectangle(10, 5);
console.log(rect.area); // 50 (不是 rect.area())
rect.width = 20; // 触发 setter

重要提示:JavaScript 的 class 本质仍是基于原型的继承的语法糖,理解原型链仍然至关重要。


总结

变量提升,函数提升

Js本身没有类,Js万物皆对象

this 是动态绑定的,取决于函数调用的上下文。
普通函数调用时,this 指向全局对象(非严格模式)或 undefined(严格模式)。
对象方法调用时,this 指向该对象。
构造函数调用时,this 指向新创建的实例。
箭头函数没有自己的 this,它会继承外部函数的 this。
显式绑定:通过 call()、apply() 或 bind() 可以显式设置 this。
理解 this 的关键在于调用时的环境,它决定了 this 的指向。

实践建议

立即实践:在你的代码中全面替换掉 var,改用 let/const。

拥抱简洁:在合适的场景(特别是需要固定 this时)使用箭头函数。

告别拼接:所有字符串拼接都用模板字符串。

善用解构:在函数参数、数组/对象取值时优先考虑解构。

模块化思维:任何项目都应拆分为模块,用 import/export管理。

异步首选:处理异步操作时,优先使用 async/await,其次是 Promise,尽量避免传统回调。

组织代码:当需要创建多个相似对象或有继承关系时,使用 class来组织代码。

这些特性共同构成了现代 JavaScript 开发的“标准语法”,掌握它们是写出高质量、可维护代码的前提

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值