JavaScript开发网页中不常用但很重要的用法

news/2024/9/28 23:30:56/

一、Proxy对象

在这里插入图片描述

  1. 基本概念
    • Proxy是JavaScript中的一个元编程特性,它允许创建一个代理对象,该代理对象可以拦截并自定义对目标对象的基本操作(如属性查找、赋值、函数调用等)。
    • 例如,创建一个简单的Proxy对象来拦截对目标对象属性的访问:
javascript">const target = {name: 'John'
};
const handler = {get: function(target, property) {console.log(`Getting property ${property}`);return target[property];}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name);
  • 在这个例子中,当访问proxy.name时,会先执行handler中的get方法,在get方法中我们可以添加额外的逻辑,如日志记录,然后再返回目标对象target中对应的属性值。
  1. 数据验证和约束
    • 在处理表单数据或者与后端API交互时,Proxy可以用于数据验证。假设我们有一个对象表示用户信息,我们希望确保某些属性的类型和范围。
javascript">const user = {age: 25
};
const userHandler = {set: function(target, property, value) {if (property === 'age' && (typeof value!== 'number' || value < 0)) {throw new Error('Age must be a non - negative number');}target[property] = value;return true;}
};
const userProxy = new Proxy(user, userHandler);
try {userProxy.age = -5;
} catch (e) {console.log(e.message);
}
  • 这里,当试图将userProxyage属性设置为负数时,会抛出错误,因为handler中的set方法进行了数据验证。
  1. 实现观察者模式
    • 观察者模式是一种设计模式,其中一个对象(主题)的状态变化会通知其他对象(观察者)。Proxy可以用于实现这种模式的简化版本。
javascript">const subject = {_data: 'Initial data'
};
const observers = [];
const subjectHandler = {set: function(target, property, value) {target[property] = value;observers.forEach(observer => observer(value));return true;}
};
const subjectProxy = new Proxy(subject, subjectHandler);
function observer(newValue) {console.log(`Observer received new value: ${newValue}`);
}
observers.push(observer);
subjectProxy._data = 'New data';
  • subjectProxy_data属性被修改时,所有注册的观察者函数都会被调用。

二、WeakMap和WeakSet

  1. WeakMap
    • 基本特性
      • WeakMap是一种键值对的集合,其中键必须是对象,值可以是任意类型。WeakMap的特殊之处在于它对键的弱引用,这意味着如果一个对象只被WeakMap作为键引用,当没有其他引用指向这个对象时,垃圾回收机制可以自动回收这个对象占用的内存。
    • 应用场景:缓存对象数据
      • 在处理大量对象并且需要缓存一些与这些对象相关的数据时,WeakMap非常有用。例如,假设我们有一个函数,它接受一个对象作为参数并进行一些耗时的计算,我们可以使用WeakMap来缓存计算结果,以避免重复计算。
javascript">const cache = new WeakMap();
function expensiveOperation(obj) {if (cache.has(obj)) {return cache.get(obj);}const result = /* 执行一些耗时的计算 */;cache.set(obj, result);return result;
}
  • 当对象不再被其他地方引用时,WeakMap中的对应键值对会被自动清理,不会造成内存泄漏。
  1. WeakSet
    • 基本特性
      • WeakSet是对象的集合,其中的元素必须是对象,并且WeakSet对元素是弱引用。WeakSet主要用于存储对象的引用,并且可以方便地检查一个对象是否在这个集合中。
    • 应用场景:对象标记
      • 例如,在处理DOM元素时,我们可能想要标记某些已经被处理过的元素。我们可以使用WeakSet来实现这个功能。
javascript">const processedElements = new WeakSet();
function processElement(element) {if (processedElements.has(element)) {return;}// 对元素进行处理的逻辑processedElements.add(element);
}
  • 当DOM元素从文档中移除并且没有其他引用时,WeakSet中的对应元素会被自动移除。

三、Generator函数

在这里插入图片描述

  1. 基本概念
    • Generator函数是一种特殊的函数,它可以暂停和恢复执行。Generator函数使用function*语法定义,并且在函数内部可以使用yield关键字来暂停函数的执行并返回一个值。
    • 例如:
javascript">function* generatorFunction() {yield 1;yield 2;return 3;
}
const generator = generatorFunction();
console.log(generator.next().value);
console.log(generator.next().value);
console.log(generator.next().value);
  • 在这个例子中,generatorFunction是一个Generator函数。当调用generator.next()时,函数会执行到yield语句处暂停,并返回yield后面的值。最后一次调用generator.next()会返回函数的返回值。
  1. 异步操作的简化
    • 在处理异步操作时,Generator函数可以与Promise结合使用来简化异步代码的编写。例如,我们可以使用Generator函数来按顺序执行多个异步操作。
javascript">function asyncOperation1() {return new Promise(resolve => {setTimeout(() => {resolve('Result of async operation 1');}, 1000);});
}
function asyncOperation2(result1) {return new Promise(resolve => {setTimeout(() => {resolve(result1 +'and result of async operation 2');}, 1000);});
}
function* asyncGenerator() {const result1 = yield asyncOperation1();const result2 = yield asyncOperation2(result1);return result2;
}
const generator = asyncGenerator();
function runGenerator(generator) {const next = function(result) {const {value, done} = generator.next(result);if (done) {return value;}if (value instanceof Promise) {value.then(next);}};next();
}
runGenerator(generator).then(result => console.log(result));
  • 这里,asyncGenerator函数按顺序执行了两个异步操作,通过runGenerator函数来驱动Generator函数的执行,使得异步代码看起来更像同步代码的逻辑。

四、Symbol

在这里插入图片描述

  1. 基本特性
    • Symbol是一种新的数据类型,它的值是唯一的且不可变。Symbol可以用作对象的属性名,以避免属性名冲突。
    • 例如:
javascript">const symbol1 = Symbol('description');
const symbol2 = Symbol('description');
console.log(symbol1 === symbol2); // false
const obj = {[symbol1]: 'Value for symbol1'
};
console.log(obj[symbol1]);
  • 在这个例子中,symbol1symbol2虽然有相同的描述,但它们是不同的Symbol值。并且我们可以使用Symbol作为对象的属性名来存储特定的值。
  1. 元编程和私有属性
    • 在JavaScript中没有真正的私有属性概念,但可以使用Symbol来模拟。例如,在一个类中,我们可以使用Symbol来定义一些不希望被外部直接访问的属性。
javascript">const _privateProperty = Symbol('privateProperty');
class MyClass {constructor() {this[_privateProperty] = 'This is a private value';}getPrivateValue() {return this[_privateProperty];}
}
const myObject = new MyClass();
// 外部无法直接访问_privateProperty
console.log(myObject.getPrivateValue());
  • 这样,外部代码不能直接通过常规的属性访问方式访问_privateProperty,只能通过类内部定义的方法来获取其值。

五、CustomEvent和事件委托

在这里插入图片描述

  1. CustomEvent
    • 基本概念
      • 在JavaScript中,除了使用原生的事件(如clickmouseover等),我们还可以创建自定义事件(CustomEvent)。CustomEvent允许我们定义自己的事件类型,并在需要的时候触发这些事件。
    • 示例:自定义事件的创建和触发
javascript">const element = document.createElement('div');
const customEvent = new CustomEvent('myCustomEvent', {detail: {message: 'This is a custom event'}
});
element.addEventListener('myCustomEvent', function(event) {console.log(event.detail.message);
});
element.dispatchEvent(customEvent);
  • 在这个例子中,我们创建了一个名为myCustomEvent的自定义事件,并且在事件对象中添加了一个detail属性来传递额外的信息。然后我们将这个事件添加到一个div元素的事件监听器中,并触发这个事件。
  1. 事件委托
    • 基本概念
      • 事件委托是一种利用事件冒泡机制的技术,它允许将事件监听器添加到父元素上,而不是为每个子元素都添加一个监听器。当子元素上发生事件时,事件会冒泡到父元素,父元素的事件监听器可以根据事件的目标(event.target)来判断是哪个子元素触发了事件。
    • 示例:在列表中的事件委托
javascript">const list = document.createElement('ul');
for (let i = 0; i < 5; i++) {const item = document.createElement('li');item.textContent = `Item ${i}`;list.appendChild(item);
}
document.body.appendChild(list);
list.addEventListener('click', function(event) {if (event.target.tagName === 'LI') {console.log(`Clicked on item: ${event.target.textContent}`);}
});
  • 在这个例子中,我们创建了一个ul列表,里面有多个li子元素。我们只在ul元素上添加了一个click事件监听器,当点击li元素时,事件会冒泡到ul元素,然后在ul元素的事件监听器中根据event.target判断是哪个li元素被点击了。

六、Intl对象

  1. 基本特性
    • Intl对象是JavaScript中的国际化API,它提供了一些方法来处理不同语言和地区的格式化需求,如日期和时间格式化、数字格式化等。
  2. 日期和时间格式化
    • 例如,使用Intl.DateTimeFormat来格式化日期和时间。
javascript">const date = new Date();
const options = {year: 'numeric',month: 'long',day: '2 - digit'
};
const formatter = new Intl.DateTimeFormat('en - US', options);
console.log(formatter.format(date));
  • 这里我们指定了日期的格式化选项(年份为数字、月份为全名、日期为两位数),并且指定了语言环境为en - US,然后使用Intl.DateTimeFormat来格式化当前日期。
  1. 数字格式化
    • 使用Intl.NumberFormat来格式化数字。
javascript">const number = 12345.67;
const numberFormatter = new Intl.NumberFormat('de - DE');
console.log(numberFormatter.format(number));
  • 在这个例子中,我们将数字12345.67按照德国(de - DE)的数字格式进行了格式化。

七、MutationObserver

  1. 基本概念
    • MutationObserver是一个用于监听DOM树变化的接口。它可以观察DOM节点的属性变化、子节点的添加或移除等操作。
  2. 示例:监听DOM变化
javascript">const targetNode = document.body;
const observer = new MutationObserver(function(mutations) {mutations.forEach(function(mutation) {console.log(mutation.type);});
});
const config = {attributes: true,childNodes: true,subtree: true
};
observer.observe(targetNode, config);
// 在这里进行一些会导致DOM变化的操作,如添加或移除元素、修改元素属性等
  • 在这个例子中,我们创建了一个MutationObserver对象,并且配置它来观察document.body的属性变化和子节点变化(包括子树中的变化)。当有符合条件的DOM变化发生时,MutationObserver的回调函数会被调用,并且可以通过mutations参数获取到具体的变化信息。

八、总结

  • 在JavaScript网页开发中,虽然这些特性可能不常用于日常的简单开发任务,但它们在处理复杂的需求、优化性能、提高代码的可维护性和实现特定的设计模式等方面具有重要的价值。掌握这些用法可以让开发者在面对更具挑战性的项目时,有更多的工具和技术手段可供选择。
//python 因为爱,所以学
print("Hello, Python!")

关注我,不迷路,共学习,同进步

关注我,不迷路,共学习,同进步


http://www.ppmy.cn/news/1531265.html

相关文章

Python中的数据处理与分析:从基础到高级

在数据科学和数据分析领域&#xff0c;Python凭借其丰富的库和强大的生态系统&#xff0c;成为了最受欢迎的语言之一。本文将从基础到高级&#xff0c;详细介绍如何使用Python进行数据处理和分析&#xff0c;涵盖数据清洗、数据转换、数据可视化等多个方面。 1. 数据导入与导出…

跨游戏引擎的H5渲染解决方案(腾讯)

本文是腾讯的一篇H5 跨引擎解决方案的精炼。 介绍 本文通过实现基于精简版的HTML5&#xff08;HyperText Mark Language 5&#xff09;来屏蔽不同引擎&#xff0c;平台底层的差异。 好处&#xff1a; 采用H5的开发方式&#xff0c;可以将开发和运营分离&#xff0c;运营部门自…

心理教育辅导系统的设计与Spring Boot实现

2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言&#xff0c;在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中&#xff0c;Java的身影无处不在&#xff0c;并且拥有旺盛的生命力。Java的跨平台能力十分强大&#xff0c;只需一次编译&#xff0c;任…

声波定位技术在地下管道中如何应用

随着城市化进程的加速&#xff0c;地下管道作为城市基础设施的重要组成部分&#xff0c;其安全、高效的维护与管理显得尤为重要。声波定位技术作为一种非破坏性探测手段&#xff0c;在地下管道中的应用日益广泛&#xff0c;成为提升管道维护和管理水平的重要工具。接下来给大家…

python dict函数介绍

在 Python 中,dict() 是用来创建字典对象的内置函数。字典(dictionary)是一个无序的可变容器,存储键-值对。dict() 函数有多种使用方式,能够接受不同的参数形式来创建字典。 dict() 函数的语法: dict(**kwargs) dict(mapping, **kwargs) dict(iterable, **kwargs)参数说…

华为HarmonyOS灵活高效的消息推送服务(Push Kit) -- 7 推送卡片刷新消息

场景介绍 如今衣食住行娱乐影音应用占据了大多数人的手机&#xff0c;一部手机可以满足日常大多需求&#xff0c;但对需要经常查看或进行简单操作的应用来说&#xff0c;总需要用户点开应用体验较繁琐。针对此种场景&#xff0c;HarmonyOS提供了Form Kit&#xff08;卡片开发服…

关于宝塔PHP getenv无法获取环境变量问题解决办法

今天有用ThinkPHP8接入阿里云OSS时&#xff0c;需要用的用到getenv()来读取环境变量&#xff0c;因为新版OSS SDK是用环境变更来设置AK的。 现象 正常执行PHP文件&#xff0c;可以取到环境变量&#xff1b;但是通过nginxphp-fpm调用脚本取到不到环境变量 原因 php-fpm为了防止…

IDEA插件开发入门

前置条件: Java17、Gradle8 1. 安装插件 Plugin DevKit 2. 新建项目 File → New → Project 3. 项目结构 &#x1f4e2; 新建一个XxxAction 4. 插件入口 XxxAction 继承 AnAction &#xff0c;实现 actionPerformed 方法&#xff0c;这是一个插件的入口 5. 插件配置 …