4. JavaScript入门--vscode插件
눈WSSB눈
2024年09月20日 18:00
收录于文集
共5篇

JavaScript(简称 JS)是一种高效的脚本语言,广泛用于网页开发。以下是 JavaScript 入门的一些基本概念和步骤:

1. 基础知识

  • 变量

代码块
JavaScript
自动换行
复制代码
let name = "Alice"; // 使用 let 声明变量

const age = 25; // 使用 const 声明常量
复制成功
  • 数据类型

代码块
JavaScript
自动换行
复制代码
字符串(String):"Hello, World!"

数字(Number):42

布尔值(Boolean):true 或 false

数组(Array):[1, 2, 3, "四"]

对象(Object):{ name: "Alice", age: 25 }
复制成功
  • 操作符

代码块
JavaScript
自动换行
复制代码
算术操作符:+, -, *, /

比较操作符:==, ===, !=, !==, <, >

逻辑操作符:&&, ||, !
复制成功
  • 注释

  • 单行注释

代码块
JavaScript
自动换行
复制代码
// 这是一个单行注释

let name = "Alice"; // 这是对变量的说明
复制成功
  • 多行注释

代码块
JavaScript
自动换行
复制代码
/*

这是一个多行注释

可以用于注释多行内容

或者解释复杂的逻辑

*/

let age = 25;

/*

let x = 10;

let y = 20;

console.log(x + y); // 这行代码被注释掉

*/
复制成功

2. 控制结构

  • 条件语句

代码块
JavaScript
自动换行
复制代码
if (age >= 18) {

	console.log("成年人");

} else {

	console.log("未成年人");

}
复制成功
  • 循环

代码块
JavaScript
自动换行
复制代码
for (let i = 0; i < 5; i++) {

	console.log(i); // 打印 0 到 4

}



let i = 0;

while (i < 5) {

console.log(i);

	i++;

}
复制成功

3. 函数

  • 函数的定义和调用

代码块
JavaScript
自动换行
复制代码
function greet(name) {

	return `Hello, ${name}`;

}

console.log(greet("Alice")); // 输出: Hello, Alice
复制成功

4.类

4.1. 创建类

您可以使用  关键字来定义一个类,如下所示:

代码块
JavaScript
自动换行
复制代码
class Person {
    // 构造函数,初始化属性
    constructor(name, age) {
        this.name = name; // 属性
        this.age = age;   // 属性
    }

    // 方法
    introduce() {
        console.log(`你好,我是 ${this.name},今年 ${this.age} 岁。`);
    }
}
复制成功

2. 创建对象

使用  关键字可以根据类创建对象:

代码块
JavaScript
自动换行
复制代码
const alice = new Person("Alice", 25);
alice.introduce(); // 输出: 你好,我是 Alice,今年 25 岁。
复制成功

3. 继承

JavaScript 还支持通过继承来创建子类,子类可以继承父类的方法和属性:

代码块
JavaScript
自动换行
复制代码
class Employee extends Person {
    constructor(name, age, position) {
        super(name, age); // 调用父类的构造函数
        this.position = position; // 新增属性
    }

    // 重写方法
    introduce() {
        console.log(`你好,我是 ${this.name},今年 ${this.age} 岁,职位是 ${this.position}。`);
    }
}

const bob = new Employee("Bob", 30, "工程师");
bob.introduce(); // 输出: 你好,我是 Bob,今年 30 岁,职位是 工程师。
复制成功

4. 类的静态方法

您可以定义静态方法,这些方法不属于对象实例,而是属于类本身:

代码块
JavaScript
自动换行
复制代码
class MathUtils {
    static add(x, y) {
        return x + y;
    }
}

// 调用静态方法
const sum = MathUtils.add(5, 10);
console.log(sum); // 输出: 15
复制成功

5. DOM 操作

JavaScript 可以与 HTML 文档中的元素进行交互:

代码块
JavaScript
自动换行
复制代码
<!DOCTYPE html>

<html>

	<head>

		<meta charset="UTF-8">

		<meta name="viewport" content="width=device-width, initial-scale=1.0">

		<title>Document</title>

	</head>

	<body>

		<h1 id="title">Hello, World!</h1>

		<button onclick="changeTitle()">改变标题</button>

		<script>

			function changeTitle() {

			document.getElementById("title").innerText = "标题已改变!";

			}

		</script>

	</body>

</html>
复制成功

6. 练习

基础知识很简单,更复杂的函数调用,可以将具体问题输入给AI,让AI解决问题

开始练习是学习 JavaScript 的重要一步。您可以尝试以下练习:

代码块
JavaScript
自动换行
复制代码
创建一个简单的计算器。

制作一个待办事项列表应用。

使用循环打印特定的图案。
复制成功

7. 学习资源

代码块
JavaScript
自动换行
复制代码
MDN Web 文档:提供详细的 JavaScript 文档和示例。

JavaScript.info:现代 JavaScript 教程。

Codecademy:互动式 JavaScript 学习平台。
复制成功

8.vscode插件制作

打开插件项目的extension.js文件

代码块
JavaScript
自动换行
复制代码
// 引入所需的模块
const fs = require("fs");
const path = require("path");
const vscode = require("vscode");
const { exec } = require('child_process');
const net = require('net');
// 声明客户端变量
let client;

/**
 * 插件激活函数
 * @param {vscode.ExtensionContext} context - 扩展上下文
 */
function activate(context) {
    // 创建命令
    let disposable = vscode.commands.registerCommand(
        "extension.showChatPanel",
        function () {
            // 创建Webview面板
            const panel = vscode.window.createWebviewPanel(
                "chatPanel", // 视图类型
                "Chat Panel", // 面板标题
                vscode.ViewColumn.Two, // 显示位置: 第二列,通常为右侧
                {
                    enableScripts: true, // 允许执行脚本
                    retainContextWhenHidden: true, // 保留上下文
                }
            );
            // 加载HTML内容到Webview,ui界面
            panel.webview.html = getWebviewContent();
            // 监听Webview消息
            panel.webview.onDidReceiveMessage(
                async (message) => {
                    switch (message.command) {
                        case "insertText":
                            const editor = vscode.window.visibleTextEditors[0];
                            if (editor) {
                                const selection = editor.selection; // 获取当前选择范围
                                if (!selection.isEmpty) {
                                    // 在这里可以执行替换或其他逻辑
                                    await editor.edit((editBuilder) => {
                                        // 用新文本替换选中的文本
                                        editBuilder.replace(selection, message.text);
                                    });
                                } else {
                                    // 获取左侧编辑窗口当前光标位置
                                    const leftPosition = editor.selection.active;
                                    await editor.edit((editBuilder) => {
                                        // 在光标位置插入文本
                                        editBuilder.insert(leftPosition, message.text);
                                    });
                                }
                            }
                            break;
                        case "alert":
                            vscode.window.showInformationMessage(message.text);
                            break;
                        case "sendMessage":
                            vscode.window.showInformationMessage(
                                `Received message: ${message.text}`
                            );
                            break;
                        case "sendMessageToPython":
                            console.log(`准备发送消息: ${message.text}`);
                            // 判断 Python client.connect(65432, 'localhost', () 服务器是否存在
                            if (!client || !client.writable){
                                // 判断是否连接
                                console.log('开始链接');
                                createClient(panel);
                            }
                            let attempt = 0;
                            let maxRetries = 5;
                            const writetext = () => {
                                try{   
                                    if (attempt < maxRetries) {
                                        console.log('发送信息');
                                        client.write(message.text);
                                    }
                                } catch (error) {
                                    attempt++;
                                    console.log(`发送失败:${error}`);
                                    setTimeout(writetext,1000);
                                }
                            }
                            writetext();
                            break;
                        default:
                            break;
                    }
                },
                undefined,
                context.subscriptions
            );
        }
    );
    // 注册命令
    context.subscriptions.push(disposable);
}

/**
 * 创建 TCP 客户端连接
 * @param {vscode.WebviewPanel} panel - Webview面板实例
 */
function createClient(panel) {

    const scriptPath = path.join(__dirname, 'python', 'client.py'); 
    // 执行 Python 脚本
    exec(`python ${scriptPath}`, (err, stdout, stderr) => {
        if (err) {
            console.error('Failed to run Python script:', err);
            return;
        }
        console.log(`Python script output: ${stdout}`);
        if (stderr) {
            console.error(`Python script error: ${stderr}`);
        }        
    });
    const maxRetries = 5; // 最大重试次数
    let attempt = 0; // 当前尝试次数

    const connectWithRetry = () => {
        if (client) {
            client.destroy();
        }
        client = new net.Socket();
        client.connect(65431, 'localhost', () => {
            console.log('链接成功');
            // 现在可以发送消息
        });

        // 监听连接错误
        client.on('error', (err) => {
            console.error('Connection error:', err.message);
            attempt++;
            if (attempt < maxRetries) {
                console.log(`Retrying connection... (Attempt ${attempt + 1} of ${maxRetries})`);
                setTimeout(connectWithRetry, 1000); // 等待2秒后重试连接
            } else {
                console.error('Max retries reached. Connection failed.');
            }
        });

        // 监听数据接收
        client.on('data', (data) => {
            console.log(`Received from Python: ${data.toString()}`);   
            // 处理接收到的数据并更新 Webview
            panel.webview.postMessage({
                command: 'updateMessageDisplay',
                output: data.toString()
            });
        });

        // 监听连接关闭
        client.on('close', () => {
            console.log('Connection closed');
            client = null; 
        });
    };
    //睡眠2s
    setTimeout(connectWithRetry, 2000);
}

/**
 * 生成Webview HTML内容
 * @returns {string} - HTML内容字符串
 */
function getWebviewContent() {
    // 获取当前插件的目录路径,并拼接出 HTML 文件路径
    const filePath = path.join(__dirname, "chatPanel.html");
    // 读取 HTML 文件内容,并返回
    return fs.readFileSync(filePath, "utf8");
}

/**
 * 插件禁用函数
 */
function deactivate() {}

/**
 * 导出 activate 和 deactivate 函数
 * @type {{ activate: Function, deactivate: Function }}
 */
module.exports = {
  activate,
  deactivate,
};
复制成功

在activate函数中注册了一个命令,触发这个命令时,在文本编辑窗口右侧创建一个AI对话界面。实际中还调用HTML界面程序和python创建本地服务器,这些内容在后续讲解。

打开package.json文件

代码块
JavaScript
自动换行
复制代码
{
  "name": "my-ai",  
  "displayName": "myAI",  
  "description": "编程助手",  
  "repository": {
      "type": "git",  
      "url": "https://github.com/yourusername/my-ai.git"  
  },  
  "version": "0.0.1",  
  "engines": {
    "vscode": "^1.93.0"  
  },  
  "categories": [
    "Other"  
  ],  
  "activationEvents": [],  
  "main": "./extension.js",  
  "contributes": {
    "commands": [  
      {
        "command": "extension.showChatPanel",  
        "title": "AI助手"  
      }  
    ]  
  },  
  "scripts": {  
    "lint": "eslint .",  
    "pretest": "npm run lint",  
    "test": "vscode-test"  
  },  
  "devDependencies": {  
    "@types/vscode": "^1.93.0",  
    "@types/mocha": "^10.0.7",  
    "@types/node": "20.x",  
    "eslint": "^9.9.1",  
    "@vscode/test-cli": "^0.0.10",  
    "@vscode/test-electron": "^2.4.1"  
  }
}
复制成功

添加需要注册的命令名称及实际名称 在extension.js界面点击F5进行调试

会打开一个新的vscode窗口

快捷键ctrl+shift+p打开命令输入窗口,输入之前设置的实际名称"title": "AI助手" ,输入 "AI助手" ,菜单会弹出该选项。

点击选择AI助手

在右侧窗口会显示一个对话框

输入命令:切换开发人员工具,调用调试窗口

点击打开

第二个选项是控制台,在里面查看实时的信息。

在代码编辑界面点击重启调试,调试窗口会重启,控制台以前的信息会重新输出,一步步查看,可以排查出具体的报错信息,然后询问AI如何解决。