JavaScript入门教程:前端开发第一步

JavaScript 入门教程封面 - 前端开发第一步零基础编程学习指南

前言

记得我第一次想学编程的时候,在网上搜”学编程从哪开始”,结果出来一堆Python、Java、C++,越看越懵。后来有个前辈跟我说:”想写网页?先学JavaScript吧。”

我当时还纳闷,JavaScript和Java是什么关系?是Java的弟弟吗?

后来才知道,它俩除了名字里都有”Java”之外,完全是两回事。JavaScript是专门给网页用的编程语言,运行在浏览器里,能让网页”动”起来——点击按钮弹出提示、输入内容实时验证、滚动加载更多内容,这些都是JavaScript的功劳。

最棒的是,JavaScript现在不只能写网页了,还能写服务器(Node.js)、手机App(React Native)、桌面程序(Electron)……学会了JavaScript,感觉整个编程世界都向你敞开了大门。

JavaScript 基础知识结构图 - 变量函数 DOM 事件与异步编程图解

JavaScript是什么?

一句话解释JavaScript

JavaScript诞生于1995年,最初是为了让网页有点”交互感”——比如表单验证、弹窗提示之类的。那时候网页就是静态的HTML文档,点个按钮要么跳转到新页面,要么啥反应没有。JavaScript的出现,让网页终于能”活”起来了。

打个比方,HTML就是网页的”骨架”,CSS是网页的”皮肤”,而JavaScript就是网页的”肌肉”——让网页能动起来。

JavaScript能做什么

经过二十多年的发展,JavaScript已经成为:

  • Web开发必备技能:任何现代网站都离不开JavaScript
  • 全栈开发语言:前端用React/Vue,后端用Node.js
  • 跨平台开发:手机App用React Native,桌面程序用Electron
  • 最流行的编程语言之一:常年霸占GitHub使用量榜首

JavaScript的特点

  1. 简单易学:语法相对简洁,入门门槛低
  2. 运行即见:浏览器里按F12就能写代码看效果
  3. 应用广泛:从网页到服务器,从手机到桌面
  4. 生态丰富:npm上有上百万个第三方库

环境准备

浏览器内置开发工具

学JavaScript最简单的入门方式就是浏览器。按F12打开开发者工具,切换到”Console”标签,你就可以直接写JavaScript代码了。

试试在控制台输入:

javascript

console.log("Hello, JavaScript!");

按回车,你会看到控制台输出了”Hello, JavaScript!”。这就是你的第一行JavaScript代码!

VS Code编辑器

写更长的代码需要编辑器。推荐VS Code,它是微软出的免费编辑器,对JavaScript支持非常好。

下载地址:https://code.visualstudio.com/

安装好之后,创建一个index.html文件:

html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>我的第一个JavaScript网页</title>
</head>
<body>
    <h1>Hello JavaScript!</h1>
    <div id="app"></div>
    
    <script>
        // 在这里写JavaScript代码
        document.getElementById("app").innerHTML = "<p>JavaScript已加载!</p>";
        console.log("脚本执行了!");
    </script>
</body>
</html>

用浏览器打开这个HTML文件,你会看到页面内容被JavaScript修改了。

JavaScript基础语法

变量声明

JavaScript里有三种声明变量的方式:

javascript

// let:声明可重新赋值的变量
let name = "小明";
name = "小红"; // 可以重新赋值

// const:声明常量,不能重新赋值
const PI = 3.14159;
// PI = 3.14; // 错误!常量不能重新赋值

// var:旧式的声明方式,不推荐使用(有很多坑)
var age = 18;

为什么推荐用let和const?

javascript

// var的问题:可以重复声明,容易出错
var count = 1;
var count = 2; // 不报错,容易造成bug

// let解决:不能重复声明
let count = 1;
let count = 2; // 报错!

// const解决:声明时必须赋值,且不能改
const PI = 3.14159;
PI = 3.14; // 报错!

// const用于对象:引用不能改,但属性可以改
const user = { name: "小明" };
user.name = "小红"; // 可以!只改属性,不改引用
user = {}; // 报错!不能改引用

数据类型

JavaScript有几种基本数据类型:

javascript

// 字符串(String)
let greeting = "你好,世界!";
let name = '小明';
let template = `Hello, ${name}!`; // 模板字符串

// 数字(Number)
let count = 42;
let price = 19.99;
let scientific = 1.5e 6; // 科学计数法:1500000

// 布尔值(Boolean)
let isActive = true;
let isFinished = false;

// 空值和未定义
let empty = null; // 空对象
let notDefined = undefined; // 未定义

// 对象(Object)
let user = {
    name: "小明",
    age: 18,
    isStudent: true,
    sayHello: function() {
        return "你好!";
    }
};

// 数组(Array)
let fruits = ["苹果", "香蕉", "橙子"];
let mixed = [1, "hello", true, null];

// 函数(Function)
let add = function(a, b) {
    return a + b;
};

运算符

javascript

// 算术运算符
let a = 10, b = 3;
console.log(a + b);   // 13,加法
console.log(a - b);   // 7,减法
console.log(a * b);   // 30,乘法
console.log(a / b);   // 3.333...,除法
console.log(a % b);   // 1,取余
console.log(a ** b);  // 1000,幂运算(10的3次方)
console.log(++a);     // 11,自增
console.log(--b);     // 2,自减

// 比较运算符
console.log(5 == "5");   // true,宽松相等(类型转换后比较)
console.log(5 === "5");  // false,严格相等(类型不同直接不等)
console.log(5 != "5");   // false
console.log(5 !== "5");  // true
console.log(3 > 2);      // true
console.log(3 >= 3);     // true

// 逻辑运算符
console.log(true && false); // false,与运算
console.log(true || false); // true,或运算
console.log(!true);         // false,非运算

// 短路运算
console.log(true || console.log("不会执行")); // true
console.log(false && console.log("不会执行")); // false

条件判断

javascript

let score = 85;

// if-else语句
if (score >= 90) {
    console.log("优秀");
} else if (score >= 60) {
    console.log("及格");
} else {
    console.log("不及格");
}

// 三元运算符(简单条件时用)
let result = score >= 60 ? "及格" : "不及格";
console.log(result);

// switch语句(多条件分支)
let day = 3;
switch (day) {
    case 1:
        console.log("星期一");
        break;
    case 2:
        console.log("星期二");
        break;
    case 3:
        console.log("星期三");
        break;
    default:
        console.log("其他日子");
}

// 多条件判断(现代写法)
let grade = score >= 90 ? "A" : 
            score >= 80 ? "B" : 
            score >= 60 ? "C" : "D";

循环

javascript

// for循环(最基本)
for (let i = 0; i < 5; i++) {
    console.log(i); // 输出 0, 1, 2, 3, 4
}

// while循环
let count = 0;
while (count < 3) {
    console.log(count);
    count++;
}

// do-while循环(至少执行一次)
let num = 0;
do {
    console.log(num);
    num++;
} while (num < 0); // 条件为false,但会执行一次

// for...of循环(遍历数组)
let fruits = ["苹果", "香蕉", "橙子"];
for (let fruit of fruits) {
    console.log(fruit);
}

// for...in循环(遍历对象属性)
let user = { name: "小明", age: 18, city: "北京" };
for (let key in user) {
    console.log(key + ": " + user[key]);
}

// 数组的forEach方法
fruits.forEach((fruit, index) => {
    console.log(`${index + 1}. ${fruit}`);
});

函数

函数是JavaScript的核心,它是组织代码的基本单元。

javascript

// 函数声明
function greet(name) {
    return "你好," + name + "!";
}

// 函数表达式
const sayHi = function(name) {
    return "Hi, " + name;
};

// 箭头函数(ES6新增,推荐)
const add = (a, b) => a + b;
const greetArrow = (name) => "你好," + name + "!";

// 带默认参数的函数
function greetWithDefault(name = "陌生人") {
    return "你好," + name;
}

// 函数调用
console.log(greet("小明"));     // 你好,小明!
console.log(add(1, 2));        // 3
console.log(greetWithDefault()); // 你好,陌生人!

// 立即执行函数(IIFE)
(function() {
    console.log("立即执行!");
})();

// 回调函数
function doSomething(callback) {
    console.log("做点什么...");
    callback();
}

doSomething(() => console.log("回调执行了!"));

DOM操作:让网页动起来

DOM(Document Object Model)是JavaScript操作网页的接口。通过DOM,你可以获取、修改、添加、删除HTML元素。

获取元素

javascript

// 通过ID获取(最常用)
let title = document.getElementById("title");

// 通过标签名获取
let paragraphs = document.getElementsByTagName("p");

// 通过类名获取
let cards = document.getElementsByClassName("card");

// 通过选择器获取(CSS选择器语法,推荐)
let firstCard = document.querySelector(".card");  // 第一个匹配
let allCards = document.querySelectorAll(".card"); // 所有匹配的

// 获取body
let body = document.body;

// 获取表单元素
let form = document.querySelector("form");
let inputs = form.elements; // 获取所有表单控件

修改元素内容

javascript

// 修改文本内容
let heading = document.querySelector("h1");
heading.textContent = "新的标题";   // 纯文本(安全,防止XSS)
heading.innerHTML = "<strong>加粗的标题</strong>"; // 支持HTML

// 修改样式
heading.style.color = "red";
heading.style.fontSize = "24px";
heading.style.fontWeight = "bold";

// 添加/删除类
heading.classList.add("highlight");
heading.classList.remove("old-style");
heading.classList.toggle("active"); // 切换类

// 修改属性
let link = document.querySelector("a");
link.href = "https://example.com";
link.target = "_blank";
link.setAttribute("data-id", "123"); // 设置自定义属性

// 获取属性
let href = link.getAttribute("href");
let id = link.dataset.id; // 获取data-*属性

事件处理

事件是用户和网页交互的动作,比如点击、鼠标悬停、键盘输入等。

javascript

// 获取按钮
let button = document.querySelector("#myButton");

// 添加点击事件
button.addEventListener("click", function(event) {
    console.log("按钮被点击了!");
    console.log("事件对象:", event);
});

// 使用箭头函数(更简洁)
button.addEventListener("click", (e) => {
    console.log("点击了:", e.target);
});

// 带参数的事件处理
button.addEventListener("click", () => {
    handleClick(123);
});

function handleClick(id) {
    console.log("处理的ID:", id);
}

// 常见的其他事件
// mouseover/mouseout - 鼠标悬停
// mousedown/mouseup - 鼠标按下/抬起
// keydown/keyup - 键盘按键
// submit - 表单提交
// change - 输入框内容变化且失去焦点
// input - 输入框内容实时变化
// focus/blur - 获得/失去焦点

// 表单提交事件
let form = document.querySelector("form");
form.addEventListener("submit", (e) => {
    e.preventDefault(); // 阻止默认提交行为
    console.log("表单提交了!");
    // 在这里发送数据
});

// 键盘事件
document.addEventListener("keydown", (e) => {
    if (e.key === "Enter") {
        console.log("按下了回车键!");
    }
    if (e.ctrlKey && e.key === "s") {
        e.preventDefault();
        console.log("Ctrl+S 快捷键");
    }
});

实战:做一个简单的计数器

完整的HTML+CSS+JavaScript示例:

html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计数器</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        }
        .counter {
            background: white;
            padding: 40px;
            border-radius: 20px;
            box-shadow: 0 10px 40px rgba(0,0,0,0.2);
            text-align: center;
            min-width: 300px;
        }
        .counter h2 {
            color: #333;
            margin-bottom: 10px;
        }
        .count {
            font-size: 80px;
            color: #333;
            margin: 20px 0;
            font-weight: bold;
        }
        button {
            padding: 15px 35px;
            font-size: 18px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            margin: 0 8px;
            transition: all 0.3s;
            color: white;
            font-weight: bold;
        }
        .decrease { background: #ff6b6b; }
        .reset { background: #95a5a6; }
        .increase { background: #4ecdc4; }
        button:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }
        button:active {
            transform: translateY(0);
        }
    </style>
</head>
<body>
    <div class="counter">
        <h2>计数器</h2>
        <div class="count" id="count">0</div>
        <button class="decrease" onclick="decrease()">减少</button>
        <button class="reset" onclick="reset()">重置</button>
        <button class="increase" onclick="increase()">增加</button>
    </div>

    <script>
        // 初始化计数器
        let count = 0;
        const countDisplay = document.getElementById("count");

        // 更新显示
        function updateDisplay() {
            countDisplay.textContent = count;
            
            // 根据数字大小改变颜色
            if (count > 0) {
                countDisplay.style.color = "#4ecdc4";
            } else if (count < 0) {
                countDisplay.style.color = "#ff6b6b";
            } else {
                countDisplay.style.color = "#333";
            }
        }

        // 增加
        function increase() {
            count++;
            updateDisplay();
            // 添加点击动画效果
            countDisplay.style.transform = "scale(1.2)";
            setTimeout(() => {
                countDisplay.style.transform = "scale(1)";
            }, 100);
        }

        // 减少
        function decrease() {
            count--;
            updateDisplay();
            countDisplay.style.transform = "scale(0.8)";
            setTimeout(() => {
                countDisplay.style.transform = "scale(1)";
            }, 100);
        }

        // 重置
        function reset() {
            count = 0;
            updateDisplay();
        }

        // 键盘控制
        document.addEventListener("keydown", (e) => {
            if (e.key === "ArrowUp" || e.key === "+") {
                increase();
            } else if (e.key === "ArrowDown" || e.key === "-") {
                decrease();
            } else if (e.key === "r" || e.key === "R") {
                reset();
            }
        });
    </script>
</body>
</html>

异步编程:Promise和async/await

传统网页要获取新数据需要刷新整个页面,AJAX让网页可以在不刷新的情况下获取服务器数据。

Promise基础

Promise是ES6引入的异步编程解决方案,比回调函数更清晰。

javascript

// 创建Promise
const myPromise = new Promise((resolve, reject) => {
    // 模拟异步操作
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve("操作成功!");
        } else {
            reject("操作失败!");
        }
    }, 1000);
});

// 使用Promise
myPromise
    .then(result => console.log(result))
    .catch(error => console.error(error))
    .finally(() => console.log("无论成功失败都会执行"));

async/await

async/await是Promise的语法糖,让异步代码看起来像同步代码。

javascript

// 定义async函数
async function fetchUserData() {
    try {
        // await等待Promise完成
        const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
        const user = await response.json();
        console.log(user);
        return user;
    } catch (error) {
        console.error("获取数据失败:", error);
    }
}

// 调用async函数
fetchUserData().then(user => {
    console.log("获取到的用户:", user.name);
});

fetch API获取数据

javascript

// 简单的GET请求
fetch("https://jsonplaceholder.typicode.com/users")
    .then(response => {
        if (!response.ok) {
            throw new Error("网络响应失败");
        }
        return response.json();
    })
    .then(users => {
        users.forEach(user => {
            console.log(`${user.name} - ${user.email}`);
        });
    })
    .catch(error => console.error("请求失败:", error));

// 更现代的async/await写法
async function getUsers() {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/users");
        if (!response.ok) throw new Error("获取失败");
        
        const users = await response.json();
        users.forEach(user => {
            console.log(`${user.name} - ${user.email}`);
        });
    } catch (error) {
        console.error("请求失败:", error);
    }
}

getUsers();

// 发送POST请求
async function createUser(userData) {
    try {
        const response = await fetch("https://jsonplaceholder.typicode.com/users", {
            method: "POST",
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(userData)
        });
        
        const result = await response.json();
        console.log("创建成功:", result);
        return result;
    } catch (error) {
        console.error("创建失败:", error);
    }
}

createUser({
    name: "张三",
    email: "zhangsan@example.com"
});

常用JavaScript库

Lodash

实用的工具函数库,提供数组、对象、字符串等操作的辅助函数。

javascript

// 安装:npm install lodash
// 或CDN引入:<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>

import _ from 'lodash';

// 防抖函数
const debouncedSearch = _.debounce(searchFunction, 300);

// 节流函数
const throttledScroll = _.throttle(handleScroll, 100);

// 深拷贝对象
const copied = _.cloneDeep(originalObject);

// 数组去重
const unique = _.uniq([1, 2, 2, 3, 3, 3]); // [1, 2, 3]

// 数组扁平化
const flat = _.flattenDeep([1, [2, [3, [4]]]]); // [1, 2, 3, 4]

// 查找满足条件的第一个元素
const user = _.find(users, { active: true });

// 对象合并
const merged = _.assign({}, obj1, obj2);

Axios

比fetch更好用的HTTP请求库。

javascript

// 安装:npm install axios
import axios from 'axios';

// GET请求
axios.get('https://api.example.com/users')
    .then(response => console.log(response.data));

// POST请求
axios.post('https://api.example.com/users', {
    name: '小明',
    age: 18
})
    .then(response => console.log(response.data))
    .catch(error => console.error('请求失败:', error));

// 同时发送多个请求
async function loadData() {
    const [users, posts] = await Promise.all([
        axios.get('/api/users'),
        axios.get('/api/posts')
    ]);
    console.log(users.data, posts.data);
}

// 设置全局配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.timeout = 10000;
axios.defaults.headers.common['Authorization'] = 'Bearer token';

常见错误和调试

语法错误

javascript

// 常见错误1:忘记引号配对
let str = '这是一个字符串"; // 语法错误

// 常见错误2:变量未声明
console.log(nmae); // ReferenceError: name is not defined

// 常见错误3:数组越界
let arr = [1, 2, 3];
console.log(arr[10]); // undefined

// 常见错误4:在异步回调中访问this
class Timer {
    constructor() {
        this.time = 0;
        setTimeout(function() {
            this.time++; // 这里的this不是Timer实例!
        }, 1000);
    }
}

// 解决:使用箭头函数或bind
setTimeout(() => {
    this.time++;
}, 1000);

使用console调试

javascript

// 基本输出
console.log("普通信息");

// 警告和错误
console.warn("警告信息");
console.error("错误信息");

// 查看对象(更详细)
let obj = { name: "小明", age: 18 };
console.log(obj); // 普通日志
console.dir(obj); // 交互式属性列表
console.table(obj); // 表格形式显示

// 分组显示
console.group("用户信息");
console.log("姓名:", obj.name);
console.log("年龄:", obj.age);
console.groupEnd();

// 格式化输出
console.log("用户%s今年%d岁", obj.name, obj.age);

// 计时
console.time("循环");
for (let i = 0; i < 10000; i++) {}
console.timeEnd("循环");

使用断点调试

在浏览器开发者工具的Sources面板中:

  1. 点击行号添加断点
  2. 刷新页面执行到断点处暂停
  3. 在右侧面板查看变量值
  4. 使用调试工具栏单步执行

JavaScript学习路线

作为一个过来人,我的建议是:

  1. HTML/CSS基础:先学会写静态网页
  2. JavaScript基础:变量、函数、DOM操作
  3. ES6+新特性:箭头函数、模块化、async/await
  4. 框架学习:Vue、React、Angular选一个
  5. 工程化:Webpack、Vite、npm/yarn

推荐的学习资源

  • MDN Web Docs:最权威的JavaScript文档
  • 《JavaScript高级程序设计》:经典书籍
  • 阮一峰的博客:中文教程写得很好
  • LeetCode:刷算法题巩固基础

总结

JavaScript是一门很”宽容”的语言,语法相对简单,入门门槛低,但要想精通却需要不断实践。

今天这篇文章涵盖了JavaScript入门的大部分核心内容:

  • JavaScript简介和应用场景
  • 变量声明和数据类型
  • 运算符和表达式
  • 条件判断和循环
  • 函数定义和调用
  • DOM操作和事件处理
  • 异步编程基础
  • 常用JavaScript库
  • 调试技巧

建议的学习方法是:多动手敲代码。不要只看教程,看完一个知识点就自己写几个例子试试。遇到问题就Google,很多你遇到的问题别人早就遇到过了。

相关推荐

动手实践是最好的学习方式,打开你的编辑器,开始写代码吧!

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注