040_JavaScript与Python语法对比学习笔记

引言:我的观察

最近在同时学习Vue 3和Python时,我惊讶地发现这两种语言的语法越来越像了。这让我开始思考:为什么不同的编程语言会趋向类似?

一、语法类似性:我的对比笔记

1.1 基础语法对比

变量声明与赋值

javascript

// JavaScript
let x = 10;
const PI = 3.14;
var name = "Alice"; // 旧方式,目前不推荐

python

# Python
x = 10
PI = 3.14  # 约定俗成的常量,实际可修改
NAME = "Alice"  # 全大写表明常量

我的发现:JavaScript需要显式声明变量类型(let/const/var),而Python不需要。但两者都支持动态类型。

条件语句

javascript

// JavaScript
if (age >= 18) {
    console.log("成年人");
} else if (age >= 13) {
    console.log("青少年");
} else {
    console.log("儿童");
}

python

# Python
if age >= 18:
    print("成年人")
elif age >= 13:
    print("青少年")
else:
    print("儿童")

我的笔记:语法几乎一样!只是Python用冒号和缩进,JavaScript用大括号。Python的elif对应JavaScript的else if。

1.2 函数定义对比

普通函数

javascript

// JavaScript
function greet(name) {
    return `Hello, ${name}!`;
}

// ES6箭头函数
const add = (a, b) => a + b;

python

# Python
def greet(name):
    return f"Hello, {name}!"

# Lambda函数(类似箭头函数)
add = lambda a, b: a + b

我的体会:箭头函数和lambda表达式都是匿名函数的简洁写法,语法很类似。

默认参数

javascript

// JavaScript
function createUser(name, age = 18) {
    return { name, age };
}

python

# Python
def create_user(name, age=18):
    return {"name": name, "age": age}

我的发现:默认参数的语法完全一致,都是在参数后面用等号赋值。

1.3 数组/列表操作对比

创建和访问

javascript

// JavaScript数组
let numbers = [1, 2, 3, 4, 5];
console.log(numbers[0]);  // 1
console.log(numbers.length);  // 5

python

# Python列表
numbers = [1, 2, 3, 4, 5]
print(numbers[0])  # 1
print(len(numbers))  # 5

我的笔记:JavaScript用.length属性,Python用len()函数,这是个小差异。

遍历

javascript

// JavaScript
// for循环
for (let i = 0; i < numbers.length; i++) {
    console.log(numbers[i]);
}

// for...of循环
for (let num of numbers) {
    console.log(num);
}

// forEach方法
numbers.forEach(num => console.log(num));

python

# Python
# for循环
for i in range(len(numbers)):
    print(numbers[i])

# 直接遍历元素
for num in numbers:
    print(num)

# 使用enumerate获取索引和值
for i, num in enumerate(numbers):
    print(f"索引{i}: 值{num}")

我的发现:两种语言都支持多种遍历方式,Python的for…in对应JavaScript的for…of。

数组方法/列表推导式

javascript

// JavaScript数组方法
const squares = numbers.map(x => x * x);
const evens = numbers.filter(x => x % 2 === 0);
const sum = numbers.reduce((total, x) => total + x, 0);

python

# Python列表推导式
squares = [x * x for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
sum_of_numbers = sum(numbers)  # Python内置sum函数

我的体会:JavaScript的数组方法链式调用,Python的列表推导式更简洁。两者都能实现同样的功能。

1.4 对象/字典对比

创建和访问

javascript

// JavaScript对象
let person = {
    name: "Alice",
    age: 25,
    greet: function() {
        return `Hello, I'm ${this.name}`;
    }
};
console.log(person.name);  // "Alice"
console.log(person["age"]); // 25

python

# Python字典
person = {
    "name": "Alice",
    "age": 25
}
print(person["name"])  # "Alice"
print(person.get("age"))  # 25

我的笔记:JavaScript对象可以有方法,Python字典一般只存数据。JavaScript用点号或中括号访问属性,Python主要用中括号。

解构赋值

javascript

// JavaScript解构
let { name, age } = person;
console.log(name, age);  // "Alice", 25

// 数组解构
let [first, second] = numbers;

python

# Python解包(类似解构)
name, age = person["name"], person["age"]
print(name, age)  # "Alice", 25

# 列表解包
first, second = numbers[0], numbers[1]
# 或使用切片
first, second = numbers[:2]

我的发现:JavaScript的解构语法更优雅,Python需要通过手动赋值或切片实现类似功能。

1.5 字符串处理对比

模板字符串/f-string

javascript

// JavaScript模板字符串
let name = "Alice";
let age = 25;
let message = `Hello, my name is ${name} and I'm ${age} years old.`;

python

# Python f-string
name = "Alice"
age = 25
message = f"Hello, my name is {name} and I'm {age} years old."

我的体会:语法几乎一模一样!都是在字符串前加特殊字符,用花括号包裹变量。

字符串方法

javascript

// JavaScript
let str = " Hello, World! ";
console.log(str.trim());  // "Hello, World!"
console.log(str.toUpperCase());  // " HELLO, WORLD! "
console.log(str.includes("World"));  // true

python

# Python
str = " Hello, World! "
print(str.strip())  # "Hello, World!"
print(str.upper())  # " HELLO, WORLD! "
print("World" in str)  # True

我的发现:方法名不同但功能类似。JavaScript是.trim(),Python是.strip();JavaScript是.includes(),Python用in关键字。

二、异步编程对比

这是我学习中最有趣的部分,两种语言的异步模型超级类似。

2.1 Promise vs asyncio

javascript

// JavaScript Promise
function fetchData() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Data fetched!");
        }, 1000);
    });
}

fetchData()
    .then(data => console.log(data))
    .catch(error => console.error(error));

python

# Python asyncio
import asyncio

async def fetch_data():
    await asyncio.sleep(1)
    return "Data fetched!"

async def main():
    try:
        data = await fetch_data()
        print(data)
    except Exception as e:
        print(f"Error: {e}")

asyncio.run(main())

我的体会:JavaScript的Promise链式调用对应Python的async/await。两种方式都能处理异步操作。

2.2 async/await语法对比

javascript

// JavaScript async/await
async function getUserData(userId) {
    try {
        const response = await fetch(`/api/users/${userId}`);
        const data = await response.json();
        return data;
    } catch (error) {
        console.error("Failed to fetch user:", error);
        throw error;
    }
}

python

# Python async/await
import aiohttp

async def get_user_data(user_id):
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(f'/api/users/{user_id}') as response:
                data = await response.json()
                return data
    except Exception as error:
        print(f"Failed to fetch user: {error}")
        raise

我的发现:语法结构几乎完全一样!都是async声明异步函数,await等待异步操作完成。

三、面向对象编程对比

3.1 类定义

javascript

// JavaScript类
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    
    greet() {
        return `Hello, I'm ${this.name}`;
    }
    
    static createAnonymous() {
        return new Person("Anonymous", 0);
    }
}

const alice = new Person("Alice", 25);
console.log(alice.greet());  // "Hello, I'm Alice"

python

# Python类
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def greet(self):
        return f"Hello, I'm {self.name}"
    
    @staticmethod
    def create_anonymous():
        return Person("Anonymous", 0)

alice = Person("Alice", 25)
print(alice.greet())  # "Hello, I'm Alice"

我的笔记:语法超级类似!构造函数:JavaScript是constructor,Python是__init__。实例方法:JavaScript不需要特殊参数,Python需要self参数。静态方法:JavaScript用static关键字,Python用@staticmethod装饰器。

3.2 继承

javascript

// JavaScript继承
class Student extends Person {
    constructor(name, age, studentId) {
        super(name, age);
        this.studentId = studentId;
    }
    
    study() {
        return `${this.name} is studying`;
    }
}

python

# Python继承
class Student(Person):
    def __init__(self, name, age, student_id):
        super().__init__(name, age)
        self.student_id = student_id
    
    def study(self):
        return f"{self.name} is studying"

我的发现:继承语法几乎一样!都是extends/括号指定父类,用super()调用父类构造函数。

四、实际应用对比

4.1 数据处理场景

过滤和转换数据

javascript

// JavaScript
const users = [
    { name: "Alice", age: 25, active: true },
    { name: "Bob", age: 30, active: false },
    { name: "Charlie", age: 20, active: true }
];

// 获取活跃用户的姓名
const activeUserNames = users
    .filter(user => user.active)
    .map(user => user.name);

console.log(activeUserNames);  // ["Alice", "Charlie"]

python

# Python
users = [
    {"name": "Alice", "age": 25, "active": True},
    {"name": "Bob", "age": 30, "active": False},
    {"name": "Charlie", "age": 20, "active": True}
]

# 获取活跃用户的姓名
active_user_names = [user["name"] for user in users if user["active"]]

print(active_user_names)  # ['Alice', 'Charlie']

我的体会:JavaScript的函数式链式调用和Python的列表推导式都能优雅地处理数据,虽然语法不同,但思路类似。

4.2 API调用场景

javascript

// JavaScript(使用fetch)
async function getWeather(city) {
    const response = await fetch(`https://api.weather.com/${city}`);
    if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return data.temperature;
}

// 使用
getWeather("Beijing")
    .then(temp => console.log(`Temperature: ${temp}°C`))
    .catch(error => console.error("Failed to get weather:", error));

python

# Python(使用requests)
import requests

async def get_weather(city):
    response = requests.get(f"https://api.weather.com/{city}")
    response.raise_for_status()  # 如果状态码不是200,抛出异常
    data = response.json()
    return data["temperature"]

# 使用(在异步环境中)
import asyncio

async def main():
    try:
        temp = await get_weather("Beijing")
        print(f"Temperature: {temp}°C")
    except Exception as e:
        print(f"Failed to get weather: {e}")

asyncio.run(main())

我的发现:处理HTTP请求的模式超级类似:发送请求、检查响应、解析JSON、处理错误。

五、重大差异笔记

尽管语法类似,但两种语言仍有重大区别:

5.1 类型系统差异

javascript

// JavaScript是动态弱类型
let x = 10;      // 数字
x = "hello";     // 可以重新赋值为字符串
x = x + 5;       // "hello5",隐式类型转换

// TypeScript添加了静态类型检查
let y: number = 10;
y = "hello";     // TypeScript会报错

python

# Python是动态强类型
x = 10          # 整数
x = "hello"     # 可以重新赋值为字符串
# x = x + 5     # 这会报错:不能将字符串和整数相加
x = x + "5"     # 正确:"hello5"

我的笔记:JavaScript会进行隐式类型转换,Python不会。Python是强类型,类型转换必须显式进行。

5.2 执行模型差异

javascript

// JavaScript是单线程事件循环
console.log("Start");

setTimeout(() => {
    console.log("Timeout after 0ms");
}, 0);

Promise.resolve().then(() => {
    console.log("Promise resolved");
});

console.log("End");

// 输出顺序:Start, End, Promise resolved, Timeout after 0ms

python

# Python支持真正的多线程(但有GIL限制)
import threading
import time

def worker():
    time.sleep(0.1)
    print("Worker done")

print("Start")
threads = []
for i in range(3):
    t = threading.Thread(target=worker)
    t.start()
    threads.append(t)

for t in threads:
    t.join()

print("End")

我的体会:JavaScript的异步模型基于事件循环,所有代码都在单线程中执行。Python支持多线程,但由于全局解释器锁(GIL),CPU密集型任务并不能真正并行。

5.3 包管理和模块系统

javascript

// JavaScript模块(ES6)
// math.js
export const add = (a, b) => a + b;
export const PI = 3.14159;

// app.js
import { add, PI } from './math.js';
console.log(add(2, 3));  // 5

// 或使用CommonJS(Node.js旧方式)
// const { add } = require('./math');

python

# Python模块
# math.py
def add(a, b):
    return a + b

PI = 3.14159

# app.py
from math import add, PI
print(add(2, 3))  # 5

# 或
import math
print(math.add(2, 3))

我的发现:两种语言的模块系统概念类似,但语法不同。JavaScript有export/import关键字,Python用import语句。

六、学习心得和提议

6.1 我的学习策略

  1. 先掌握概念,再记语法:许多编程概念是相通的(如变量、函数、循环、条件判断),先理解概念,不同语言的语法只是表达方式不同。
  2. 对比学习法:同时学习两种语言时,有意识地对比它们的类似点和差异点,这样能加深理解。
  3. 实践驱动学习:通过实际项目学习,列如用JavaScript写前端,用Python写后端,在实践中体会两种语言的异同。

6.2 常见陷阱

  1. 语法混淆:有时候会把两种语言的语法混用,列如在Python中写console.log()或在JavaScript中写print()。
  2. 缩进差异:Python对缩进超级严格,JavaScript相对宽松但提议保持一致风格。
  3. 回调风格:JavaScript早期大量使用回调函数,目前多用Promise/async;Python的异步编程也经历了演进。

6.3 实用技巧

  1. IDE/编辑器配置:使用支持多种语言的编辑器(如VS Code),安装相应的语法高亮和代码提示插件。
  2. 代码转换思维:尝试用两种语言实现同一个功能,对比哪种方式更简洁、更高效。
  3. 查阅官方文档:遇到问题时,优先查阅官方文档,了解语言设计的初衷和最佳实践。

七、个人总结

通过学习JavaScript和Python的对比,我深刻体会到:

  1. 编程语言是工具:不同的语言适合不同的场景,没有绝对的优劣。JavaScript适合Web开发,Python适合数据分析和脚本编写。
  2. 语法趋同是趋势:现代编程语言的确 在相互借鉴优秀特性,这让学习新语言变得越来越容易。
  3. 理解本质更重大:与其死记硬背语法,不如理解背后的编程思想和设计模式。
  4. 保持好奇心:技术不断发展,新的语言特性不断出现,保持学习的心态很重大。

作为开发者,掌握多种语言不仅能扩大技术视野,还能在不同场景中选择最合适的工具。JavaScript和Python的语法类似性让我在切换时更加顺畅,这也许就是编程语言发展的必然方向——让开发者更专注于解决问题,而不是纠结于语法细节。

© 版权声明

相关文章

1 条评论

none
暂无评论...