Web - 面向对象

概述

该文档系统梳理了JavaScript面向对象核心知识,涵盖对象操作、this机制、原型链、继承等核心概念,并深入解析了Math和Date两大内置对象的实用方法。内容结构清晰,示例丰富(如深浅克隆对比、日期格式化等),尤其对数学计算和日期处理的讲解全面实用,适合作为开发者的速查手册或学习笔记。

对象

对象(object)是"键key-值value对"的集合,表示属性和值的映射关系,key和value之间用冒号分隔,每组key:value之间用逗号分隔,最后一个key:value对后可以不书写逗号。

如果对象的属性键名不符合JS标识符命名规范,则这个键名必须用引号包裹。

javascript 复制代码
const student = {
    name: '小明',
    age: 12,
    sex: '男',
    hobbys: ['足球', '游泳', '编程'],
    'favorite-book': '舒克和贝塔'
};

1、属性的访问

  • 可以用"点语法"访问对象中指定键的值。
  • 如果属性名不符合JS标识符命名规范,则必须用方括号的写法来访问。
  • 如果属性名以变量形式存储,则必须使用方括号形式。

2、属性的更改

  • 直接使用赋值运算符重新对某属性赋值即可更改属性。

3、属性的创建

  • 如果对象本身没有某个属性值,则用点语法赋值时,这个属性会被创建出来。

4、属性的删除

  • 如果要删除某个对象的属性,需要使用delete操作符。

5、for...in循环

javascript 复制代码
const student = {
    name: '小明',
    age: 12,
    sex: '男',
    hobbys: ['足球', '游泳', '编程'],
    'favorite-book': '舒克和贝塔'
};

for (const k in student){
    console.log('属性'+k+'的值是:'+student[k]);
}

6、对象的深浅克隆

举例 当var a = b变量传值时 当用 == 比较时
基本类型值 数字、字符串、布尔、undefined、null 内存中产生新的副本 比较值是否相等
引用类型值 对象、数组等 内存中不产生新的副本,而是让新变量指向同一个对象 比较内存地址是否相同,即比较是否为同一对象

对象是引用类型值,这意味着:

  • 不能用var obj2 = obj1这样的语法克隆一个对象。
  • 使用==或者===进行对象的比较时,比较的是它们是否为内存中的同一个对象,而不是比较值是否相同。

浅克隆:只克隆对象的"表层"如果对象的某些属性值又是引用类型值,则不进一步克隆它们,只是传递它们的引用,也就是内存中的同一个地址。

深克隆:克隆对象的全貌,不论对象的属性值是否又是引用类型值,都能将它们实现克隆,和数组的深克隆类似,对象的深克隆需要使用递归。

this 上下文

  • 函数中可以使用this关键字,它表示函数的上下文。
  • 与中文中"这"类似,函数中的this具体指代什么必须通过调用函数时的"前言后语"来判断。
  • 同一个函数,用不同的形式调用它,则函数的上下文不同。

规则 1:对象打点调用它的方法函数,则函数的上下文是这个打点的对象。 规则 2:圆括号直接调用函数,则函数的上下文是window对象。 规则 3:多数组(类数组对象) 枚举出函数进行调用,上下文是这个数组((类数组对象)。 规则 4:IIFE中的函数,定时器、延时器调用函数,上下文是window对象。 规则 5:事件处理函数的上下文是绑定事件的DOM元素。 规则6:call和apply能指定函数的上下文。

构造函数与类

用new操作符调用函数

  • JS规定,使用new操作符调用函数会进行"四步走"。

1)函数体内会自动创建出一个空白对象。 2)函数的上下文(this)会指向这个对象。 3)函数体内的语句会执行。 4)函数会自动返回上下文对象,即使函数没有return语句。

2、原型原型链

  • 普通函数来说的prototype属性没有任何用处,而构造函数的prototype属性非常有用。
  • 构造函数的prototype属性是它的实例的原型。
  • Javascript规定:实例可以打点访问它的原型的属性和方法,这被称为原型链查找。
  • hasownProperty方法可以检查对象是否真正"自己拥有某属性或者方法。
  • in运算符只能检查某个属性或方法是否可以被对象访问,不能检查是否是自己的属性或方法。

把方法直接添加到实例身上的缺点:每个实例和每个实例的方法函数都是内存中不同的函数,造成了内存的浪费。

3、继承

  • 继承描述了两个类之间的"is a kind of"关系,比如学生"是一种"人,所以人类和学生类之间就构成继承关系
  • People是"父类"(或"超类"、"基类");student是"子类"(或"派生类"
  • 子类丰富了父类,让类描述得更具体、更细化

实现继承的关键点:子类必须拥有父类的全部属性和方法同时子类还应该能定义自己特有的属性和方法,使用Javascript特有的原型链特性来实现继承,是普遍的做法。

内置对象

1、包装类

  • Number()、string()和Boolean()分别是数字、字符串布尔值的包装类。
  • 很多编程语言都有"包装类"的设计,包装类的目的就是为了让基本类型值可以从它们的构造函数的prototype上获得方法。
  • Number()、String()和Boolean()的实例都是object类型它们的Primitivevalue属性存储它们的本身值。
  • new出来的基本类型值可以正常参与运算。

2、数学 Math对象

舍入方法

Javascript 复制代码
console.log(Math.round(2.4)); // 输出:2(四舍五入)
console.log(Math.floor(2.9)); // 输出:2(向下取整)
console.log(Math.ceil(2.1));  // 输出:3(向上取整)
console.log(Math.trunc(2.8)); // 输出:2(去除小数部分)

最大值和最小值

Javascript 复制代码
console.log(Math.max(5, 3, 8, 1)); // 输出:8
console.log(Math.min(5, 3, 8, 1)); // 输出:1

幂运算与平方根

Javascript 复制代码
console.log(Math.pow(2, 3)); // 输出:8(2 的 3 次方)
console.log(Math.sqrt(16));  // 输出:4(16 的平方根)
console.log(Math.cbrt(27));  // 输出:3(27 的立方根)

绝对值与符号

Javascript 复制代码
console.log(Math.abs(-5)); // 输出:5(-5 的绝对值)
console.log(Math.sign(-5)); // 输出:-1(负数返回 -1)
console.log(Math.sign(5));  // 输出:1(正数返回 1)
console.log(Math.sign(0));  // 输出:0(零返回 0)

随机数生成

Javascript 复制代码
 // 生成一个大于等于 0 且小于 1 的随机小数
console.log(Math.random());

// 生成一个 1 到 10 之间的随机整数
console.log(Math.floor(Math.random() * 10) + 1);

三角函数

Javascript 复制代码
console.log(Math.sin(Math.PI / 2)); // 输出:1(sin(90°))
console.log(Math.cos(Math.PI));     // 输出:-1(cos(180°))
console.log(Math.tan(0));           // 输出:0(tan(0°))

对数与指数

Javascript 复制代码
console.log(Math.log(Math.E)); // 输出:1(自然对数,底数为 e)
console.log(Math.log10(100));  // 输出:2(以 10 为底的对数)
console.log(Math.exp(2));      // 输出:e²(约等于 7.389)

常量

Javascript 复制代码
console.log(Math.PI);   // 输出:π(约等于 3.14159)
console.log(Math.E);    // 输出:e(自然对数的底数,约等于 2.718)
console.log(Math.SQRT2); // 输出:√2(约等于 1.414)

3、日期 Date对象

创建日期实例

Javascript 复制代码
const now = new Date(); // 当前日期和时间
const specificDate = new Date(2023, 5, 15); // 2023年6月15日(月份从0开始,0=1月)
const fromString = new Date("2023-06-15T08:30:00"); // 从字符串解析
const timestamp = new Date(1686827400000); // 从时间戳(毫秒)创建

获取日期和时间信息

Javascript 复制代码
const date = new Date();

date.getFullYear(); // 返回年份(如:2023)
date.getMonth(); // 返回月份(0-11,0=1月)
date.getDate(); // 返回日(1-31)
date.getDay(); // 返回星期几(0-6,0=星期日)
date.getHours(); // 返回小时(0-23)
date.getMinutes(); // 返回分钟(0-59)
date.getSeconds(); // 返回秒(0-59)
date.getMilliseconds(); // 返回毫秒(0-999)
date.getTime(); // 返回时间戳(自1970年1月1日以来的毫秒数)

设置日期和时间

Javascript 复制代码
const date = new Date();

date.setFullYear(2024); // 设置年份
date.setMonth(11); // 设置月份(11=12月)
date.setDate(25); // 设置日
date.setHours(14); // 设置小时
date.setMinutes(30); // 设置分钟
date.setSeconds(45); // 设置秒
date.setMilliseconds(500); // 设置毫秒
date.setTime(1703524200000); // 通过时间戳设置日期

日期格式化

Javascript 复制代码
const date = new Date();

date.toDateString(); // "Mon Jun 03 2025"
date.toTimeString(); // "14:30:45 GMT+0800 (中国标准时间)"
date.toLocaleDateString(); // 根据本地格式显示日期(如:"2025/6/3")
date.toLocaleTimeString(); // 根据本地格式显示时间(如:"下午2:30:45")
date.toISOString(); // ISO 8601格式(如:"2025-06-03T06:30:45.000Z")

时间戳转换

Javascript 复制代码
// 获取当前时间戳
const timestamp = Date.now(); // 等同于 new Date().getTime()

// 从时间戳创建日期
const date = new Date(timestamp);

日期比较

Javascript 复制代码
const date1 = new Date(2023, 0, 1); // 2023-01-01
const date2 = new Date(2023, 11, 31); // 2023-12-31

date1 < date2; // true
date1.getTime() === date2.getTime(); // false

计算时间差

Javascript 复制代码
const start = new Date(2023, 0, 1);
const end = new Date(2023, 11, 31);
const diffMs = end - start; // 毫秒差
const diffDays = diffMs / (1000 * 60 * 60 * 24); // 天差(约364天)

时区转换

Javascript 复制代码
const date = new Date();
date.toUTCString(); // 转换为UTC时间字符串
date.getTimezoneOffset(); // 返回本地时区与UTC的时差(分钟)
相关推荐
musashi几秒前
学会这招,可以录制所有 web 端的视频(附完整实现代码)
前端·javascript·浏览器
加油乐4 分钟前
uniapp开发微信小程序---分包
前端·微信小程序·uni-app
摆烂工程师9 分钟前
快上车!教你白嫖ChatGPT Team的教程以及怎么取消和支付ChatGPT Team订阅的教程
前端·人工智能·后端
有梦想的攻城狮10 分钟前
从0开始学vue:vue3和vue2的关系
前端·javascript·vue.js·vue3·vue2
我家猫叫佩奇12 分钟前
🔥 React 模版版本升级 React19.0.0 ->19.1.0
前端·javascript·开源
CAD老兵12 分钟前
TypeScript 类型判断方法详解与比较
前端
LIUSAi11112 分钟前
使用gsap实现加载进度条功能
前端
yinke小琪13 分钟前
t06_vue在mac操作系统中热更新失效问题包括cli与vite
前端
不一样的少年_16 分钟前
🚨 别再乱用will-change了!前端翻车的"性能优化"陷阱
前端·浏览器
北京_宏哥17 分钟前
🔥《刚刚问世》系列初窥篇-Java+Playwright自动化测试-16- iframe操作-监听事件和执行js脚本 (详细教程)
java·前端·自动化运维