此文章,来源于印客学院的资料【第一部分:基础篇(105题)】,也有一些从网上查找的补充。
这里只是分享,便于学习。
诸君可以根据自己实际情况,自行衡量,看看哪里需要加强。
概述如下:
立即执行函数,不暴露私有成员
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0vS9jVJl-1689732980409)(https://mmbiz.qpic.cn/sz_mmbiz_png/BOlSgLkrCDbNK7y5xraRyQHGdDibibdWr6Ms2ICYLB9mgibGcGJImqoicYGzx0RjGAZw0dY6zmcdibgAALjpc6gYaoQ/640?wx_fmt=png)]
在 JavaScript 中,模块化开发是一种将代码分割为独立模块的方法,每个模块都有自己的作用域,并且可以通过导入和导出来与其他模块进行交互。这种模块化的方式有助于提高代码的可维护性、重用性和可测试性。
下面是一种常见的 JavaScript 模块化开发方式,使用 ES6 的模块语法:
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
// main.js
import { add, subtract } from './math.js';
console.log(add(5, 2)); // 输出: 7
console.log(subtract(5, 2)); // 输出: 3
在这个例子中,math.js
是一个模块,它定义了 add()
和 subtract()
两个函数,并通过 export
关键字导出。然后,在 main.js
中使用 import
关键字将需要的函数导入,并进行调用。
请注意,上述示例假设你正在使用支持 ES6 模块化的环境,比如现代浏览器或者 Node.js 12.0.0+ 版本。如果你想在不同环境或旧版浏览器中使用模块化开发,可能需要使用工具(如Webpack、Browserify)或降级到其他的模块化方案(如CommonJS、AMD)。
此外,还有其他的模块化规范和库可供选择,例如 CommonJS(Node.js 默认的模块化方案)、AMD(用于浏览器中异步加载模块)、UMD(通用模块定义)等。选择合适的模块化方案取决于你的项目需求和目标环境。
JavaScript 中异步加载 JS 的方式有以下几种常见的方法:
标签:通过 JavaScript 动态创建
标签,并将其添加到页面中,从而异步加载指定的 JS 文件。var script = document.createElement('script');
script.src = 'path/to/script.js';
document.head.appendChild(script);
async
和 defer
属性:在 HTML 中的
标签上可以设置 async
或 defer
属性以实现异步加载。async
:脚本文件的加载和执行不会阻塞页面的解析和渲染。脚本加载完成后立即执行。<script src="path/to/script.js" async>script>
defer
:脚本文件的加载也不会阻塞页面的解析和渲染,但脚本执行会在页面解析完毕后进行(DOMContentLoaded 事件之前)。<script src="path/to/script.js" defer>script>
require(['path/to/module'], function(module) {
// 模块加载完成后执行的回调函数
});
import()
方法,可以异步加载模块并返回一个 Promise 对象。import('path/to/module')
.then(function(module) {
// 模块加载完成后执行的回调函数
});
这些方式都可以实现异步加载 JS 文件,具体选择哪种方式取决于你的项目需求和目标环境。需要注意的是,动态创建 标签、
async
和 defer
属性适用于旧版浏览器和现代浏览器,而模块化加载器和动态 import()
方法则需要考虑目标环境的支持情况。
在 JavaScript 中,以下几种情况可能导致内存泄漏:
无限制地添加事件监听器:如果在 DOM 元素上添加了事件监听器,但没有正确地移除它们,就会导致内存泄漏。这意味着即使元素已经被移除,相关的事件处理函数仍然存在于内存中,无法被回收。
循环引用:JavaScript 中的对象通过引用进行内存管理。如果存在循环引用,即对象 A 引用对象 B,而对象 B 又引用对象 A,那么这两个对象将 无法被垃圾回收机制正常回收,从而造成内存泄漏。
function createObjects() {
var objA = {};
var objB = {};
objA.someProperty = objB;
objB.anotherProperty = objA;
// objA 和 objB 形成了循环引用
}
createObjects();
function startTimer() {
setInterval(function() {
// ...
}, 1000);
}
startTimer();
巨大的数据结构:如果创建了大量的对象、数组或其他数据结构,并且不再需要时没有及时释放它们,就会占用大量的内存并导致内存泄漏。
闭包:如果在函数内部创建了闭包,并且闭包引用了外部函数的变量,即使外部函数执行完毕,闭包仍然保留对这些变量的引用,从而导致内存泄漏。
function createClosure() {
var data = 'sensitive information';
return function() {
// 使用 data 变量
console.log(data);
};
}
var leakedFunction = createClosure();
// 外部函数 createClosure 已经执行完毕,但由于闭包的存在,data 变量无法被正常释放
为避免内存泄漏,需要确保正确地管理事件监听器
、清除定时器
和回调函数
、避免循环引用
以及及时释放不再使用的对象和数据结构
等。
必要时可以使用工具和技术进行性能分析和内存泄漏检测。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BiVe0F09-1689732980411)(https://mmbiz.qpic.cn/sz_mmbiz_png/BOlSgLkrCDbNK7y5xraRyQHGdDibibdWr6Jpu0k22V3kpFdz6ZK6lxVrArFVfVCbt4k7ncWQGV4J24QLFqvrhj5g/640?wx_fmt=png)]
XML(可扩展标记语言)和JSON(JavaScript对象表示)是两种常用的数据交换格式,
它们有以下区别:
语法:XML使用自定义的标签和属性来表示数据结构,而JSON使用简洁的键值对形式表示。因此,XML的结构更加繁琐,而JSON更加紧凑易读。
数据类型支持:XML支持多种数据类型,包括文本、数字、布尔值等,而JSON仅支持字符串、数字、布尔值、数组和对象这几种基本数据类型。
可读性:由于XML使用了自定义标签和属性,使得它比JSON在结构上更加易读。同时,XML可以通过注释和文档类型定义(DTD或XSD)来提供更多的描述和文档结构。
解析和处理:由于XML的语法比较复杂,解析XML文件需要更多的计算资源和时间,而JSON的解析速度更快,通常比XML更高效。
扩展性:XML具有很强的扩展性,可以通过定义自己的标签和属性来适应不同的数据结构。而JSON的扩展性相对较弱,只能使用现有的数据类型。
总体而言,XML适用于复杂结构和较大规模的数据交换,而JSON适用于简单结构和较小规模的数据交换。
选择使用哪种格式取决于具体的需求和应用场景。
Webpack是一个现代化的前端打包工具,它在前端开发中扮演着非常重要的角色,你可以使用 WebPack 管理你的模块依赖, 并编绎输出模块们所需的静态文件。
它能够很好地管理 、打包 Web 开发中所用到的 HTML 、Javascript 、 CSS 以及各种静态文件 ( 图片 、字体等), 让开发过程更加高效。
对于不同类型的资源, webpack 有对应的模块加载器 。 webpack 模块打包器会分析模块间的依赖关系, 最后 生成了优化且合并后的静态资源。
对Webpack有以下几点看法:
模块化打包:Webpack可以将前端项目中的各种资源(例如JavaScript、CSS、图片等)都视为模块,并利用模块化的方式进行打包。这使得我们可以使用import、export等语法来组织代码,提高代码的可维护性和复用性。
自动化构建:Webpack提供了丰富的插件系统,可以自动化地完成一些构建任务,例如代码压缩、文件合并、优化等。通过配置Webpack,我们可以在开发过程中自动完成这些繁琐的工作,提高开发效率。
资源优化:Webpack支持各种优化功能,例如代码分割、异步加载、懒加载等。这些优化策略可以减小打包文件的体积,加快网页加载速度,提升用户体验。
生态丰富:Webpack有庞大的开发社区,有许多插件和工具可以与其配合使用,解决各种开发需求。同时,Webpack也能和其他流行的前端框架(如React、Vue等)无缝集成,提供更好的开发体验。
配置复杂:对于初学者来说,Webpack的配置可能会比较复杂。Webpack提供了非常灵活的配置选项,但这也意味着需要一定的学习和理解成本。然而,一旦掌握了Webpack的核心概念和配置方式,就能发挥其强大的功能。
总的来说,Webpack是一个功能强大且灵活的前端打包工具,它可以帮助我们优化项目结构、提高开发效率和网页性能。
尽管配置可能相对复杂,但通过学习和实践,Webpack可以成为前端开发中不可或缺的一部分。
AMD(Asynchronous Module Definition)和CommonJS是两种主要的模块化规范,用于在JavaScript中组织和管理模块代码。
对它们的理解如下:
AMD(异步模块定义):
CommonJS:
AMD和CommonJS都解决了JavaScript代码模块化的问题,但是它们在语法和加载方式上有所区别,因此在不同的环境和应用场景中会有不同的使用情况。
一般来说,AMD适用于浏览器环境和异步加载的需求,而CommonJS适用于服务器环境和同步加载的需求。
同时,值得注意的是,在现代前端开发中,ES6模块化也已经成为了主流,它在语法和功能上都有所改进,可以逐渐取代AMD和CommonJS
。
常见的Web安全问题包括以下几个方面,同时也提供了相应的防护原理:
跨站脚本攻击(XSS):
跨站请求伪造(CSRF):
注入攻击(包括SQL注入、OS命令注入等):
敏感数据泄露:
常见漏洞(如未授权访问、文件上传漏洞等):
点击劫持:
DDOS攻击:
综上所述,Web安全的防护原理包括良好的输入验证和过滤、安全编码实践、合适的身份认证和授权机制、合适的加密传输、限制访问权限、使用安全的框架和库等。
同时,定期进行漏洞扫描和安全审计,及时更新和修复系统漏洞也是保障Web应用安全的重要措施。
XSS与CSRF有什么区别吗?
XSS是获取信息,不需要提前知道其他用户⻚⾯的代码和数据包 。 CSRF 是代替用户完成指定的动作, 需要知道其他用户⻚⾯的代码和数据包。
要完成⼀次 CSRF 攻击, 受害者必须依次完成两个步骤
CSRF的防御
服务端的 CSRF 方式方法很多样,但总的思想都是⼀致的,就是在客户端页面增加伪随机数,通过验证码的方法。
在JavaScript中,有许多常用的设计模式。以下是一些常见的设计模式及其示例:
单例模式(Singleton Pattern):
示例:实现全局唯一的日志记录器。
const Logger = (function() {
let instance;
function init() {
// 私有方法和属性
function log(message) {
console.log(message);
}
// 公有方法和属性
return {
log: log
};
}
return {
getInstance: function() {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
const logger = Logger.getInstance();
logger.log("Hello, world!");
工厂模式(Factory Pattern):
示例:创建不同类型的产品。
function Product(name, price) {
this.name = name;
this.price = price;
}
function ProductFactory() {
this.createProduct = function(type) {
switch (type) {
case "A":
return new Product("Product A", 100);
case "B":
return new Product("Product B", 200);
default:
return null;
}
};
}
const factory = new ProductFactory();
const productA = factory.createProduct("A");
console.log(productA);
const productB = factory.createProduct("B");
console.log(productB);
观察者模式(Observer Pattern):
示例:实现一个事件订阅发布机制。
function Publisher() {
this.subscribers = [];
this.subscribe = function(subscriber) {
this.subscribers.push(subscriber);
};
this.unsubscribe = function(subscriber) {
const index = this.subscribers.indexOf(subscriber);
if (index !== -1) {
this.subscribers.splice(index, 1);
}
};
this.publish = function(message) {
this.subscribers.forEach(function(subscriber) {
subscriber.notify(message);
});
};
}
function Subscriber(name) {
this.name = name;
this.notify = function(message) {
console.log(this.name + ": " + message);
};
}
const publisher = new Publisher();
const subscriberA = new Subscriber("Subscriber A");
const subscriberB = new Subscriber("Subscriber B");
publisher.subscribe(subscriberA);
publisher.subscribe(subscriberB);
publisher.publish("Hello, subscribers!");
发布/订阅模式(Publish/Subscribe Pattern):
示例:使用第三方库(如EventEmitter)实现自定义事件的发布和订阅。
const EventEmitter = require("events");
const eventEmitter = new EventEmitter();
// 订阅事件
eventEmitter.on("myEvent", function(message) {
console.log("Event received: " + message);
});
// 发布事件
eventEmitter.emit("myEvent", "Hello, subscribers!");
这些只是JavaScript中的一些常见设计模式及其示例。
在实际开发中,根据具体需求选择合适的设计模式可以提高代码的可维护性和扩展性。
JavaScript的同源策略是一种安全机制,用于保护用户隐私和防止恶意网站对用户数据进行滥用。
同源策略要求在浏览器中运行的JavaScript代码,只能与来自 同一源(即协议、域名和端口号都相同) 的页面进行交互,而不能与不同源的页面进行直接的读写操作。
同源策略的主要限制有以下几点:
这些限制主要是为了防止恶意脚本窃取用户敏感信息,并阻止跨站点请求伪造攻击(CSRF)等安全威胁。
同时,浏览器提供了一些机制来允许跨域资源共享(CORS)和在特定情况下放宽同源策略的限制。
举例说明: 比如⼀个黑客程序,他利用 Iframe 把真正的银⾏登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过 Javascript 读取到你的表单中 input 中的内容, 这样用户名,密码就轻松到手了。
为了解决跨域问题,常见的方法包括:
需要注意的是,绕过同源策略可能会带来安全风险。因此,在开发过程中应合理设计接口和权限控制,并遵循最佳安全实践。
在JavaScript中,offsetWidth、offsetHeight、clientWidth、clientHeight、scrollWidth和scrollHeight都是用于获取元素的尺寸信息的属性,但它们有着不同的含义和用途。
offsetWidth和offsetHeight:
clientWidth和clientHeight:
scrollWidth和scrollHeight:
这些属性在处理元素布局、计算滚动区域以及响应式设计等方面非常有用。需要注意的是,这些属性的值通常是以像素为单位的整数,且可能会受到盒模型、浏览器差异和CSS样式等因素的影响。