JavaScript基础知识扫盲
JavaScript有几种方式声明函数?
函数声明(Function Declaration):
1
2
3function functionName(parameters) {
// 函数体
}函数表达式(Function Expression):
1
2
3var functionName = function(parameters) {
// 函数体
};箭头函数(Arrow Function)(ES6引入):
1
2
3var functionName = (parameters) => {
// 函数体
};Function构造函数:
1
var functionName = new Function('parameters', 'function body');
这些方式各有特点,函数声明和函数表达式是最常见和推荐的方式,而箭头函数是在ES6中引入的一种更简洁的写法,而Function构造函数则较少使用,因为它会在运行时解析字符串,有一定的性能开销和安全风险。
原生Javascript获取DOM节点有哪些方式?
document.getElementById
获取具有指定的ID,ID唯一。
1 | leta=document。getElementById('id'); |
document.getElementByTagName
返回一个包含所有给定标签名元素的HTML
1 | let a=document.getElementByTagName('div'); |
1document.getElementByClassName
返回一个包含所有给定类名的元素的
HTMLCollection
。
1 | let a=document.getElementByClassName('myclass'); |
在原生 JavaScript 中,有多种方式可以获取或选择 DOM (Document Object Model) 元素。这些方法提供了从简单到复杂的不同级别的选择功能,可以让你根据 ID、类名、标签名、CSS 选择器等多种方式选择元素。以下是一些最常用的方法:
1. document.getElementById
获取具有指定 ID 的一个元素。ID 在一个文档中应该是唯一的。
1 | var element = document.getElementById('myId'); |
2. document.getElementsByTagName
返回一个包含所有给定标签名的元素的 HTMLCollection
。
1 | var elements = document.getElementsByTagName('div'); |
3. document.getElementsByClassName
返回一个包含所有给定类名的元素的 HTMLCollection
。
1 | var elements = document.getElementsByClassName('myClass'); |
4. document.querySelector
返回文档中匹配指定 CSS 选择器的第一个元素。如果没有找到匹配项,返回 null
。
1 | var element = document.querySelector('.myClass'); |
5. document.querySelectorAll
返回一个 NodeList
,其中包含文档中所有符合指定 CSS 选择器的元素。
1 | var elements = document.querySelectorAll('.myClass'); |
6. document.forms
这是一个比较老的方法,用来获取文档中的表单元素。
1 | var form = document.forms[0]; // 获取第一个表单 |
7. document.getElementsByName
这个方法返回一个 NodeList
,其中包含所有具有指定的 name 特性的元素。
1 | var elements = document.getElementsByName('name'); |
8. 使用 CSS 属性选择器
你也可以使用 querySelector
和 querySelectorAll
方法配合属性选择器来选择具有特定属性的元素。
1 | var element = document.querySelector('input[type="checkbox"]'); |
使用建议:
- 如果你只需要选择一个元素,并且该元素具有 ID,那么
getElementById
是最快的选择。 - 如果需要根据类名、标签名或者更复杂的 CSS 选择器选择多个元素,
querySelectorAll
是非常强大的工具。 - 对于需要兼容性考虑,所有上述方法除了较新的
querySelector
和querySelectorAll
,其他都有很好的兼容性。querySelector
和querySelectorAll
主要不支持 IE8 及以下版本。
这些方法都是原生 JavaScript 提供的,无需依赖任何库或框架即可在现代浏览器中使用。
Javascript的this绑定
在JavaScript中,
this
关键字是非常核心的一个概念,它引用的是函数执行时的上下文对象。理解this
如何绑定到不同的上下文是理解和掌握JavaScript非常重要的一部分。this
的绑定规则可以通过以下几种方式确定:
默认绑定
当函数独立调用时(即不作为某个对象的方法或未被显式绑定到某个对象),this
默认绑定到全局对象。在非严格模式下,this
指向全局对象(浏览器中的window
,Node.js中的global
);在严格模式下(函数或全局代码中使用'use strict';
),this
会被绑定到undefined
。
1 | function show() { |
隐式绑定
当函数作为对象的方法被调用时,this
隐式绑定到该对象。
1 | const obj = { |
如果存在多层对象嵌套,this
将绑定到最近一层的对象上。
显式绑定
使用call()
、apply()
或 bind()
方法可以显式地指定this
的绑定对象。
1 | function show() { |
new绑定
当一个函数通过new
关键字被作为构造函数调用时,this
被绑定到新创建的对象上。
1 | function Person(name) { |
箭头函数绑定
箭头函数不使用以上四种规则,而是捕获其所在上下文的this
值,作为自己的this
值,也称为词法绑定。
1 | const obj = { |
在箭头函数中,this
绑定到外围函数的上下文中,即使是在setTimeout
这样的异步函数中。
总结
JavaScript的this
绑定是动态的,除了箭头函数外,其绑定取决于函数调用的上下文。理解这些绑定规则对于编写可预测的JavaScript代码非常重要。
JS主线程有哪些
在JavaScript中,特别是在浏览器环境下,存在一个称为“主线程”的概念,通常也被称为“UI线程”。JavaScript 是单线程运行的,意味着在任一时刻只能执行一个任务。主线程负责执行代码、渲染界面、处理用户的交互操作等任务。这里主要解释的是JavaScript在浏览器中的运行环境:
JavaScript 主线程的职责
执行代码:
- JavaScript 主线程执行所有的JavaScript代码。无论是从
<script>
标签引入的代码,还是通过事件触发的函数,都在这个单一的线程上执行。
- JavaScript 主线程执行所有的JavaScript代码。无论是从
UI 渲染:
- 浏览器使用主线程来渲染页面。这包括HTML的解析、CSS的应用、DOM的操作以及最终的画面渲染。这也是为什么在执行重计算或大量DOM操作时,页面可能会感觉卡顿或冻结,因为这些操作会占用主线程的资源,影响到UI的更新。
用户交互:
- 主线程还处理来自用户的所有交互,如点击、滚动、键盘输入等。这意味着如果JavaScript代码执行耗时过长,它可以阻塞用户交互,导致不良的用户体验。
与主线程交互的其他组件
尽管JavaScript是单线程执行的,但现代浏览器和Node.js环境提供了多种机制来处理异步事件和后台任务,以避免阻塞主线程,如:
Web Workers:
- 提供一种在浏览器背景下运行脚本的方法,不影响主线程。Web Workers运行在与主线程完全独立的线程上,可以执行复杂计算或处理大量数据,不会导致界面卡顿。
事件队列和事件循环:
- 浏览器维护一个事件队列,所有异步事件,如网络请求、定时器触发、用户输入等,都会被排到这个队列中。主线程在执行完当前代码后,会查看这个队列,并处理队列中的事件。
异步API:
- 浏览器提供了许多异步API,如
setTimeout
、setInterval
、fetch
(网络请求)等,这些API的回调不会立即执行,而是在合适的时机被推入事件队列,待主线程空闲时执行。
- 浏览器提供了许多异步API,如
注意事项
由于主线程的多重职责,作为开发者在编写JavaScript代码时,需要注意不要执行过于复杂或耗时的同步代码,这可能会阻塞主线程,影响到UI的渲染和用户的交互体验。在处理大量数据或复杂计算时,应考虑使用Web Workers或其他异步处理方法,以提高应用性能和响应性。
事件捕获、目标、冒泡
在Web开发中,事件冒泡是一种事件处理机制,其中从一个元素发起的事件会逐层向上传播到其父元素,直至根元素。有时候,我们可能需要阻止这种冒泡行为,以避免触发父元素上的事件处理函数。这可以通过JavaScript中的事件对象提供的方法来实现。
以下是如何在不同情况下阻止事件冒泡的方法:
使用 event.stopPropagation()
这是阻止事件冒泡的标准方法。当在事件处理函数中调用此方法时,当前事件将不会进一步传播到父元素。
1 | element.addEventListener('click', function(event) { |
返回 false
在使用jQuery时,你可以通过在事件处理函数中返回false
来同时阻止事件冒泡和默认行为。在原生JavaScript中,这种方法只适用于通过HTML属性添加的事件处理器。
1 | // 使用 jQuery |
使用 event.stopImmediatePropagation()
这个方法不仅阻止事件继续冒泡到更高的父元素,还阻止任何当前元素上的其他事件监听器被调用。这是一个比stopPropagation()
更强大的方法。
1 | element.addEventListener('click', function(event) { |
应用场景
- 阻止链接默认打开新页面:阻止
<a>
标签的默认行为。 - 防止表单提交:阻止表单的自动提交行为。
- 组织事件传播到其他元素:如在弹出菜单中阻止点击事件传播到背景页面。
注意
虽然阻止事件冒泡可以解决一些问题,但过度使用它可能会导致维护困难,因为这改变了事件的正常流动。合理使用这一特性,并确保理解其对整体交互逻辑的影响。
JavaScript的对象方法
JavaScript
的对象(Object
)有许多内置的方法,这些方法可以帮助我们操作和管理对象。以下是一些常见的对象方法及其示例:
Object.keys()
返回一个数组,包含对象自身可枚举属性的键。
1 | const person = { |
Object.values()
返回一个数组,包含对象自身可枚举属性的值。
1 | const person = { |
Object.entries()
返回一个数组,包含对象自身可枚举属性的键值对数组。
1 | const person = { |
Object.assign()
将所有可枚举的自身属性从一个或多个源对象复制到目标对象。它返回目标对象。
1 | const target = { a: 1, b: 2 }; |
Object.freeze()
冻结对象:一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。该对象的原型也不能被修改。
1 | const person = { |
Object.seal()
密封对象:一个密封的对象不能再添加新的属性,且所有现有属性将变为不可配置的。现有属性的值仍然可以修改。
1 | const person = { |
Object.create()
使用指定的原型对象及其属性创建一个新对象。
1 | const personPrototype = { |
Object.defineProperty()
直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。
1 | const person = {}; |
Object.getOwnPropertyDescriptor()
返回指定对象上一个自有属性对应的属性描述符。
1 | const person = { |
Object.getPrototypeOf()
返回指定对象的原型(即,内部[[Prototype]]属性的值)。
1 | const personPrototype = { |
总结
JavaScript对象有许多内置方法,可以帮助我们操作和管理对象。上述列举的只是其中的一部分,实际开发中可以根据需要选择合适的方法来处理对象