JavaScript青少年简明教程:函数及其相关知识(下)

JavaScript青少年简明教程:函数及其相关知识(下)

继续上一节介绍函数相关知识。

箭头函数(Arrow Function)

箭头函数是 ES6(ECMAScript 2015)及更高版本中引入的语法,用于简化函数定义。箭头函数使用=>符号来定义函数:

JavaScript箭头函数(arrow functions)是一种简洁的函数定义方式。它们提供了一种更简洁的语法来创建匿名函数,同时不绑定自己的this值,非常适合回调函数或需要保持上下文的场景。

箭头函数的基本语法如下:

(param1, param2, ..., paramN) => { statements }

或者,对于只有一个参数和单一表达式的箭头函数,可以省略参数括号和花括号:

singleParam => expression

对于没有参数的箭头函数,需要使用空括号:

() => { statements }

☆简单箭头函数,例如:

const add = (a, b) => {return a + b;
};
console.log(add(2, 3)); // 输出 5

☆省略花括号和return关键字

当函数体只有一个表达式时,可以省略花括号和return关键字,例如:

const multiply = (a, b) => a * b;
console.log(multiply(2, 3)); // 输出 6

☆单一参数时省略参数括号,例如:

const square = x => x * x;
console.log(square(4)); // 输出 16

【提示:
const square = x => x * x;
等同于:
const square = function(x) {
    return x * x;
}; 】

☆没有参数的箭头函数,要有空括号,例如:

const greet = () => console.log('Hello, World!');
greet(); // 输出 Hello, World!

【提示:
const greet = () => console.log('Hello, World!');
等同于:
const greet = function() {
    console.log('Hello, World!');
}; 】
 

注意,箭头函数不绑定this

箭头函数不会创建自己的this值,它会捕获其所在上下文的this值。

箭头函数不绑定自己的this,而是继承定义时的上下文this。这意味着箭头函数的this是静态的,不会因为调用方式的不同而改变。

当与传统函数进行对比时,可以更清楚地理解箭头函数不绑定自己的this的行为。下面通过对比来说明这一点:

// 传统函数
function traditionalFunction() {console.log(this);
}// 箭头函数
const arrowFunction = () => {console.log(this);
}const obj = {value: 42,traditional: traditionalFunction,arrow: arrowFunction
};// 作为对象方法调用
obj.traditional(); // 输出 obj 对象
obj.arrow(); // 输出 obj 对象// 全局作用域中调用
traditionalFunction(); // 输出全局对象(浏览器中是 window)
arrowFunction(); // 输出全局对象(浏览器中是 window)// 显式绑定
const explicitBindObj = { value: 99 };
traditionalFunction.call(explicitBindObj); // 输出 explicitBindObj 对象
arrowFunction.call(explicitBindObj); // 输出全局对象(浏览器中是 window)

从上面的例子可以看出,在传统函数中,this的值取决于函数的调用方式,而在箭头函数中,无论是作为对象的方法调用还是在全局作用域中调用,它们的this都是继承定义时的上下文,而不是根据调用方式而改变。

在对象方法调用中,传统函数的this指向调用该方法的对象,而箭头函数的this仍然是继承定义时的上下文。在全局作用域中调用时,传统函数的this是全局对象,而箭头函数的this也是继承自全局作用域的。

函数参数和返回值说明

1 默认参数

在JavaScript中,函数可以使用默认参数(Default Parameters)来指定在调用函数时没有提供某个参数值时的默认值。从ECMAScript 2015(ES6)开始,这个功能就被引入了。

默认参数在函数定义中的参数列表内部设置,如果调用函数时没有提供该参数的值,则使用默认值。以下是默认参数的基本用法:

function greet(name = 'World') {  console.log(`Hello, ${name}!`);  
}  // 调用函数时没有提供name参数  
greet(); // 输出: Hello, World!  // 调用函数时提供了name参数  
greet('Alice'); // 输出: Hello, Alice!

还可以在函数定义时使用先前定义的参数作为默认参数的值,例如:

function add(a, b = a) {return a + b;
}console.log(add(2, 3)); // 输出 5
console.log(add(5)); // 输出 10,b的值默认为a的值,即5

在上述示例中,参数b的默认值使用了参数a的值,当只传递一个参数时,b将自动取a的值,实现了参数间的默认关联。

2 剩余参数(Rest Parameters)

这点前面已提到过。在JavaScript中,特别是从ECMAScript 2015(ES6)开始,你可以使用剩余参数(Rest Parameters)来收集一个函数中被视为单个参数的多个值到一个数组中。这在你不知道将有多少个参数传递给函数时非常有用。

剩余参数使用三个点(...)语法,并且必须作为函数参数的最后一个参数。这允许你将一个不定数量的参数作为数组处理。

示例:

function sum(...numbers) {let total = 0;for (let number of numbers) {total += number;}return total;
}console.log(sum(1, 2, 3, 4)); // 输出 10
console.log(sum(5, 10, 15)); // 输出 30

在上述示例中,sum函数使用剩余参数...numbers来收集所有传入的参数,并将它们存储在名为numbers的数组中。然后,通过遍历数组中的元素,可以对参数进行处理。

需要注意的是,剩余参数只能出现在函数的最后一个参数位置,因为它会将所有未匹配的参数收集到一个数组中。如果在剩余参数之后还定义了其他参数,将会引发语法错误。

3 返回值

JavaScript函数的返回值是指函数执行完毕后返回给调用者的值。使用return语句可以指定函数的返回值。当函数执行到return语句时,函数将停止执行,并将指定的值返回给调用者。

以下是一些关于JavaScript函数返回值的要点:

1)使用return语句指定返回值:

function multiply(a, b) {return a * b;
}let result = multiply(3, 4);
console.log(result); // 输出 12

在上述示例中,multiply函数使用return语句返回两个参数的乘积。调用函数时,返回值被赋给变量result。

2)函数可以有多个return语句,但只有一个会被执行:

function getGreeting(name) {if (name) {return 'Hello, ' + name + '!';}return 'Hello, Guest!';
}console.log(getGreeting('Alice')); // 输出 "Hello, Alice!"
console.log(getGreeting()); // 输出 "Hello, Guest!"

在上述示例中,getGreeting函数根据传入的参数name返回不同的问候语。如果name存在,则返回个性化的问候语;否则,返回默认的问候语。

3)如果函数没有显式的return语句,或者return语句后面没有指定值,函数将返回undefined:

function doSomething() {// 没有return语句
}let result = doSomething();
console.log(result); // 输出 undefined

4)函数执行完return语句后会立即停止执行,return语句后面的代码不会被执行:

function processData(data) {if (!data) {return; // 如果没有数据,立即返回}// 处理数据的逻辑console.log('Processing data...');
}processData(null);

在上述示例中,如果data为假值(例如null或undefined),函数会立即返回,不会执行后续的数据处理逻辑。

5)返回值可以是任意类型,包括基本类型(如数字、字符串、布尔值等)和引用类型(如对象、数组、函数等)。

返回值允许函数将计算结果、处理后的数据或其他有意义的值传递给调用者,使函数具有更强的可重用性和灵活性。

提示,本节中后面的内容,初学者对可以先不必深究,作为完整性,有一个初步认识即可。

构造函数(Constructor Function)

JavaScript的构造函数是一种特殊的函数,用于创建和初始化对象。它们通常与new关键字一起使用,以创建对象的新实例。

构造函数可以定义对象的属性和方法。使用this关键字来设置对象的属性和方法。

在构造函数内部,this 指向新创建的对象。

构造函数通常不需要返回值,它会自动返回创建的对象。

构造函数名称通常以大写字母开头(这是一个命名约定)。

例如:

function Person(name, age) {// 设置属性this.name = name;this.age = age;// 设置方法this.sayHello = function() {console.log("Hello, my name is " + this.name);};this.haveBirthday = function() {this.age++;console.log(this.name + " is now " + this.age + " years old.");};
}// 创建 Person 实例
const john = new Person("John", 30);console.log(john.name);  // 输出: John
console.log(john.age);   // 输出: 30
john.sayHello();         // 输出: Hello, my name is John
john.haveBirthday();     // 输出: John is now 31 years old.

在这个例子中:

this.name 和 this.age 设置了对象的属性。

this.sayHello 和 this.haveBirthday 设置了对象的方法。

需要注意的几点:

1)这种方法在每次创建新实例时都会创建新的函数对象,可能会占用更多内存。为了更高效地共享方法,通常会使用原型:
Person.prototype.sayHello = function() {
  console.log("Hello, my name is " + this.name);
};

2)在 ES6 及以后,可以使用类语法来实现相同的功能,这提供了一种更清晰的class语法:

class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log("Hello, my name is " + this.name);}haveBirthday() {this.age++;console.log(this.name + " is now " + this.age + " years old.");}
}

关于class语法,后面还将介绍。

JavaScript中的构造函数和普通函数在语法上是相同的,但它们的用途和使用方式有明显的区别。构造函数主要用于创建对象并设置初始状态,而普通函数用于执行特定的任务或计算。让我们来比较一下:

用途方面

普通函数:执行特定任务或计算

构造函数:创建和初始化对象实例

返回值方面

普通函数:可以返回任何值,或者不返回值(返回 undefined)

构造函数:通常不显式返回值,默认返回创建的对象实例

this 关键字方面

普通函数:this 的值取决于函数如何被调用

构造函数:this 指向新创建的对象实例

另外,命名约定方面(这只是约定,不是强制的)

普通函数:通常以小写字母开头

构造函数:通常以大写字母开头

递归函数

递归函数是一种在函数体内调用自身的函数。这是一种强大的编程技术,特别适合解决可以被分解成相似子问题的问题。

基本概念:

递归函数包含两个主要部分:

基本情况(Base case):停止递归的条件

递归情况(Recursive case):函数调用自身的部分

基本结构:

function recursiveFunction(parameters) {
  if (/* base case condition */) {
    return /* base case value */;
  } else {
    // 递归调用
    return recursiveFunction(/* modified parameters */);
  }
}

示例 - 计算阶乘

阶乘是一个数学上的重要概念,它表示从1乘到某个数n的所有整数的乘积。阶乘用符号n!来表示。定义如下:

n! = n × (n-1) × (n-2) × ... × 3 × 2 × 1

特别地,0! = 1,这是阶乘的基础情况。

例如:

3! = 3 × 2 × 1 = 6

示例源码:

function factorial(n) {if (n <= 1) return 1;  // 基本情况return n * factorial(n - 1);  // 递归情况
}console.log(factorial(5));  // 输出: 120

递归函数注意事项:

必须有基本情况以避免无限递归,即要确保有正确的终止条件

大量递归可能导致栈溢出

有时可能比迭代解决方案效率低

计算1至5的累计和,就是1+2+3+4+5。源码:

function add(n) {// 当 n === 1 的时候要结束if (n === 1) {return 1} else {// 不满足条件的时候,就是当前数字 + 比自己小 1 的数字return n + add(n - 1) ;}
}
add(5)

递归函数的优点是可以将复杂的问题分解成更小的子问题,使问题解决过程更加清晰和简洁。它可以提供一种自然的思考方式,并且在某些情况下可以使代码更易于理解和维护。

然而,递归函数也有一些缺点需要考虑。首先,递归函数可能会占用大量的内存空间,因为每次递归调用都会在内存堆栈中创建一个新的函数调用帧。这可能导致堆栈溢出的问题,特别是当递归的层级非常深时。

其次,递归函数的性能可能不如迭代函数。递归函数需要频繁地进行函数调用和返回操作,这会增加函数调用的开销。相比之下,迭代函数通常可以通过循环结构实现相同的功能,并且在某些情况下可以更高效地执行。

另外,递归函数的设计需要小心处理边界条件和递归结束条件,否则可能导致无限递归的情况,造成程序崩溃或死循环。

闭包

闭包(Closure)是一个非常重要的概念,它允许函数记住并访问其词法环境,即使该函数在其词法环境之外执行。简单来说,闭包就是函数和声明该函数的词法环境的组合。

闭包通常在你创建了一个内部函数,并且这个内部函数访问了外部函数的变量时自然形成。内部函数会保留对外部函数变量的引用,即使外部函数执行完成后,这些变量不会被垃圾回收机制(Garbage Collection)清除。例如:

function outerFunction() {let outerVariable = 100;  // 外部变量function innerFunction() {console.log(outerVariable);  // 访问外部变量}return innerFunction;
}const myClosure = outerFunction();  // outerFunction执行完毕
myClosure();  // 输出: 100

在这个例子中,outerVariable是outerFunction中的一个局部变量。innerFunction访问了这个变量,尽管outerFunction在调用myClosure()时已经执行完毕,outerVariable的值仍然被innerFunction保留访问。

闭包的基本特性

1)函数是第一类对象:在 JavaScript 中,函数是对象,可以像其他对象一样被传递和操作。这意味着函数可以:

被赋值给变量

作为参数传递给其他函数

作为函数的返回值

示例:

// 函数赋值给变量
const greet = function(name) {return `Hello, ${name}!`;
};// 函数作为参数
function executeFunction(fn, param) {return fn(param);
}
console.log(executeFunction(greet, "Alice")); // 输出: Hello, Alice!// 函数作为返回值
function createMultiplier(factor) {return function(number) {return number * factor;};
}
const double = createMultiplier(2);
console.log(double(5)); // 输出: 10

2)词法作用域:JavaScript 使用词法作用域(也称为静态作用域),这意味着作用域是基于函数在哪里被声明来确定的,而不是基于函数在哪里被调用。示例:

let x = 10;function createFunction() {let x = 20;return function() {console.log(x); // 这里的 x 引用的是 createFunction 中的 x,而不是全局的 x};
}const f = createFunction();
f(); // 输出: 20

3)内部函数可以访问外部函数的变量:当一个函数内部定义了另一个函数时,内部函数可以访问外部函数的变量,即使外部函数已经执行完毕。

这是闭包最关键的特性。即使外部函数已经执行完毕,内部函数仍然可以访问外部函数的变量。

示例:

function outerFunction(x) {let y = 10;function innerFunction() {console.log(x + y);}return innerFunction;
}const closure = outerFunction(5);
closure(); // 输出: 15

在这个例子中,即使 outerFunction 已经执行完毕,返回的 innerFunction 仍然可以访问 outerFunction 的参数 x 和局部变量 y。

闭包主要特点

a)内部函数可以访问外部函数的变量。这个特点是闭包的核心,内部函数不仅可以访问自己的变量,还可以访问外部函数的变量和参数。示例:

function outerFunction(x) {let y = 20;function innerFunction() {console.log(x + y);}innerFunction();
}outerFunction(10); // 输出: 30

在这个例子中,innerFunction 可以访问 outerFunction 的参数 x 和局部变量 y。

b)即使外部函数已经返回,内部函数仍然可以访问这些变量

这个特点让闭包变得特别强大。内部函数会保留对外部函数作用域的引用,即使外部函数已经执行完毕。示例:

function createGreeter(name) {return function() {console.log(`Hello, ${name}!`);};
}const greetAlice = createGreeter('Alice');
greetAlice(); // 输出: Hello, Alice!

在这个例子中,即使 createGreeter 函数已经返回,返回的函数仍然可以访问 name 参数。

c)可以用来创建私有变量和方法

闭包允许我们创建在外部不可直接访问的变量和方法,从而实现数据的封装和私有性。示例:

function createBankAccount(initialBalance) {let balance = initialBalance;return {deposit: function(amount) {balance += amount;return balance;},withdraw: function(amount) {if (amount > balance) {return "Insufficient funds";}balance -= amount;return balance;},getBalance: function() {return balance;}};
}const account = createBankAccount(100);
console.log(account.getBalance()); // 输出: 100
account.deposit(50);
console.log(account.getBalance()); // 输出: 150
console.log(account.withdraw(200)); // 输出: "Insufficient funds"
console.log(account.balance); // 输出: undefined

在这个例子中:balance 是一个私有变量,外部无法直接访问或修改。deposit、withdraw 和 getBalance 是公共方法,可以操作私有变量 balance。外部代码只能通过这些公共方法来与账户余额交互,保证了数据的安全性和一致性。

闭包的用途

闭包允许我们创建有状态的函数,同时又不暴露内部状态,这在很多编程模式中非常有用,比如惰性加载(Lazy Loading)、记忆化函数(Memoization)、柯里化(Currying)等。

☆惰性加载

定义:延迟初始化或计算,直到实际需要时才执行。

目的:优化性能,减少初始加载时间。

闭包可以用于延迟初始化,只在首次需要时执行某些操作。例子:

let heavyComputation = (function() {let result;return function() {if (result === undefined) {console.log("Computing...");result = /* 复杂计算 */;}return result;};
})();console.log(heavyComputation()); // 输出: Computing... 然后返回结果
console.log(heavyComputation()); // 直接返回结果,不再计算

☆记忆化函数

定义:缓存函数的计算结果,以便在后续调用中快速返回。

目的:优化计算密集型函数的性能。

使用闭包来缓存函数的计算结果,提高性能。例子:

function memoize(fn) {const cache = {};return function(...args) {const key = JSON.stringify(args);if (key in cache) {return cache[key];}const result = fn.apply(this, args);cache[key] = result;return result;};
}const slowFibonacci = memoize(function(n) {if (n <= 1) return n;return slowFibonacci(n - 1) + slowFibonacci(n - 2);
});console.log(slowFibonacci(40)); // 快速计算,结果被缓存

☆柯里化:

定义:将接受多个参数的函数转换成一系列使用一个参数的函数。

目的:增加函数的灵活性和可复用性。

闭包使得函数柯里化成为可能,柯里化函数使用闭包来保存部分应用的参数。例子:

function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args);} else {return function(...args2) {return curried.apply(this, args.concat(args2));};}};
}const sum = curry((a, b, c) => a + b + c);
console.log(sum(1)(2)(3)); // 6
console.log(sum(1, 2)(3)); // 6

闭包注意事项

内存泄漏:由于闭包会保持对外部变量的引用,这可能导致内存无法释放,形成内存泄漏。适当的生命周期管理和及时的解除引用是必要的。

性能考虑:创建闭包可能会稍微消耗更多的内存,因为需要保存外部函数的活动对象。

进一步还需要学习回调函数、高阶函数、异步函数等。较少用到就不涉及了。

附录、JavaScript函数 https://blog.csdn.net/cnds123/article/details/109405136

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/49607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode:删除排序链表中的重复元素(C语言)

1、问题概述&#xff1a;给定一个已排序链表的头&#xff0c;删除重复元素&#xff0c;返回已排序的链表 2、示例 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例 2&#xff1a; 输入&#xff1a;head [1,1,2,3,3] 输出&#xff1a;[1,2,3] 3…

深度解析Memcached:内存分配算法的优化之旅

&#x1f525; 深度解析Memcached&#xff1a;内存分配算法的优化之旅 Memcached是一个高性能的分布式内存缓存系统&#xff0c;广泛用于提高Web应用程序的性能。它通过减少数据库查询次数来加速数据检索。然而&#xff0c;Memcached的性能在很大程度上取决于其内存分配算法的…

前端三方库零碎(持续更新)

本文主要记录开发实践过程中遇到的前端库&#xff0c;做个记录总结&#xff0c;以备不时之需 easyui-datagrid EasyUI 是一个基于 jQuery 的用户界面插件库&#xff0c;提供了丰富的用户界面组件和工具&#xff0c;其中包括 datagrid&#xff08;数据表格&#xff09;组件。E…

2024年国际高校数学建模大赛(IMMCHE)问题A:金字塔石的运输成品文章分享(仅供学习)

2024 International Mathematics Molding Contest for Higher Education Problem A: Transportation of Pyramid Stones&#xff08;2024年国际高校数学建模大赛&#xff08;IMMCHE&#xff09;问题A&#xff1a;金字塔石的运输&#xff09; 古埃及金字塔石材运输优化模型研究…

spring(一)

一、spring特点 1.非侵入式&#xff1a;使用 Spring Framework 开发应用程序时&#xff0c;Spring 对应用程序本身的结构影响非常小。对领域模型可以做到零污染&#xff1b;对功能性组件也只需要使用几个简单的注解进行标记&#xff0c;完全不会破坏原有结构&#xff0c;反而能…

2024最新Selenium面试题(附带答案),建议收藏备用

一.你在TestNG中使用了哪些注解&#xff1f; TestBeforeSuiteAfterSuiteBeforeTestAfterTestBeforeClassAfterClassBeforeMethodAfterMethod 二.如何从Excel中读取数据&#xff1f; FileInputStream fs new FileInputStream(“excel文件路径”); Workbook wb WorkbookFact…

探索智慧校园资产入库功能,构建高效校园资产管理体系

在智慧校园的资产管理框架下&#xff0c;资产入库功能作为资产生命周期管理的开端&#xff0c;扮演着至关重要的角色。这一功能确保了新购置或转入的资产能够迅速而准确地被记录在系统中&#xff0c;从而无缝融入日常的管理流程。当资产入库时&#xff0c;系统要求详细登记一系…

2024最新前端学习路线指南!

2024最新前端学习路线指南&#xff01; 如果你正在寻找一份全面的前端学习路线图&#xff0c;那么这份精心打造的学习大纲恰好符合您的需求。无论您是新手还是经验丰富的开发者&#xff0c;这份路线图都能够帮助您系统地掌握前端开发的关键知识点&#xff0c;并在实践中不断提…

git连接远程仓库

一、本地新建代码,上传到远程仓库 1.git init #初始化本地仓库 2.git remote -v #查看当前仓库的远程地址 3.git remote add origin 远程仓库的URL 4.git branch master / git branch dev 创建 主分支或者 dev 分支 5.git checkout master/dev. 切换到主分支或者dev 分支…

Mysql-生产环境实战经验总结

文章目录 真实生产环境下的Mysql数据库机器配置如何规划互联网公司的生产环境数据库是如何进行性能压测1. 准备测试环境2. 构建测试场景3. 性能测试4. 监控与分析5. 资源压力测试6. 故障恢复测试7. 文档记录与复盘8. 安全与合规注意事项 如何为生产环境中的数据库部署监控系统1…

<PLC><HMI><汇川>在汇川HMI画面中,如何为UI设置全局样式?

前言 汇川的HMI软件是使用了Qt来编写的,因此在汇川的HMI程序编写过程,是支持使用qt的样式来自定义部件样式的,即qss格式。 概述 汇川的软件本身提供三个系统的style样式,我们可以直接使用,但是,如果系统提供的样式不符合你的需求,那么你可以对其进行修改,或者自己新建…

修改linux服务器上的mariadb/mysql数据库的密码

文章目录 一、查看数据库的状态二、修改密码 可能我们在最初安装数据库时没有设置密码或者已经设置了但是又想修改另一个密码&#xff0c;可以这样操作来修改我们的密码。 以数据库 mariadb 为例。 一、查看数据库的状态 使用命令 systemctl is-active mariadb 查看当前数据库…

Github 2024-07-27开源项目日报 Top10

根据Github Trendings的统计,今日(2024-07-27统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目2C++项目2C项目2TypeScript项目1JavaScript项目1Java项目1Python项目1C#项目1免费编程学习平台:freeCodeCamp.org 创建周期:33…

JMeter接口测试:测试中奖概率!

介绍 Apache JMeter 是 Apache 组织基于 Java 开发的压力测试工具&#xff0c;用于对软件做压力测试。JMeter 最初被设计用于 Web 应用测试&#xff0c;但后来扩展到了其他测试领域&#xff0c;可用于测试静态和动态资源&#xff0c;如静态文件、Java 小服务程序、CGI 脚本、J…

如何开发无障碍的前端Web 网页

Web 无障碍设计&#xff08;Accessibility in Web design&#xff0c;也叫网站可及性 &#xff09;是要让所创建的网站对所有用户都可用/可访问&#xff0c;不管用户的生理/身体能力如何、不管用户是以何种方式访问网站。 让网页完全支持无障碍功能有一定成本&#xff0c;我们…

Redis 缓存

安装 安装 Redis 下载&#xff1a; Releases tporadowski/redis (github.com) winr ----services.msc-----将redis 设置为手动(只是学习&#xff0c;如果经常用可以设置为自动) 安装 redis-py 库 pip install redis-py Redis 和 StrictRedis redis-py 提供 Redis 和 Str…

Java高频面试题分享

文章目录 1. 策略模式怎么控制策略的选取1.1 追问&#xff1a;如果有100种策略呢&#xff1f;1.2 追问&#xff1a;什么情况下初始化Map 2. 什么是索引&#xff1f;什么时候用索引&#xff1f;2.1 追问&#xff1a;怎么判断系统什么时候用量比较少2.2 追问&#xff1a;如何实时…

C++多态的底层原理

目录 1.虚函数表 &#xff08;1&#xff09;虚函数表指针 &#xff08;2&#xff09;虚函数表 2.虚函数表的继承--重写&#xff08;覆盖&#xff09;的原理 3.观察虚表的方法 &#xff08;1&#xff09;内存观察 &#xff08;2&#xff09;打印虚表 虚表的地址 函数 传参…

SSM电子商务系统-计算机毕业设计源码68470

基于SSM框架的电子商务系统的设计与实现 摘 要 随着电子商务的迅猛发展和计算机信息技术的全面跃升&#xff0c;网上购物系统由于其迎合了人们诉求和期望而渗入社会生活各个层面和角落。本文设计并实现了一个基于SSM框架的电子商务系统。该系统旨在为用户提供一个舒适且快捷的…

Python基础——第一个Python程序

Python基础——第一个Python程序 一、编写和运行代码的工具1.1 为什么需要工具1.2 默认的交互式环境1.3 文本编辑神器 - Visual Studio Code1.4 专业的集成开发环境 - PyCharm 二、编写第一个Python程序2.1 在PyCharm中编写“Hello, World!”程序2.2 运行“Hello, World!”程序…