1. 数据类型
1.1 基本类型:存储在栈中
Number、String、Boolean、Undefined、null、Symbol
补充:boolean转换
数据类型 | true | false |
---|---|---|
String | 非空字符串 | "" |
Number | 非零数值 | 0、NaN |
Undefined | N/A | undefined |
Object | 任意对象 | null |
1.2 引用类型:存储在堆中
Object、Array、Function、....
1.3 区分类型的方法
方法 | 基本类型结果 | 引用类型结果 | 注意事项 |
---|---|---|---|
typeof | 返回对应类型字符串(如"number" ,"string" ) | 返回 (函数返回 | 1. 2. 无法区分具体引用类型 |
instanceof | 始终返回false | 返回true (当匹配构造函数时) | 1. 仅适用于检测引用类型 2. 跨窗口实例检测可能失效 |
Object.prototype.toString.call() | 返回格式 如 | 返回具体类型标识 如 | 1. 最精确的类型检测方法 2. 需通过 3. 对 |
示例代码:
// typeof 示例
console.log(typeof 42); // "number"
console.log(typeof {}); // "object"
// instanceof 示例
console.log([] instanceof Array);// true
console.log(123 instanceof Number);// false
// toString 示例
console.log(Object.prototype.toString.call(new Date()));// [object Date]
console.log(Object.prototype.toString.call(null)); // [object Null]
2. 数据结构
数组、链表
栈(Stack):后进先出。在栈里,新元素都接近栈顶,旧元素都接近栈底。
队列(Queue):先进先出。队列在尾部添加新元素,并从顶部移步元素。
字典:以键-值对存储数据的数据结构。
散列表:也称哈希表
3. DOM(文档对象模型)
浏览器将HTML或XML文档解析为结构化树形对象的接口。
3.1 获取元素
document.getElementById('id属性值');
document.getElementsByClassName('class属性值');
document.getElementsByTagName('标签名');
document.getElementsByName('name属性值');
// 只返回第一个匹配的元素
document.querySelector('CSS选择器');
// 返回所以匹配的元素
document.querySelectorAll('CSS选择器');
// 获取页面中的html标签
document.documentElement;
document.body;
document.all[''];
3.2 更新节点
// innerHTML 替换原来的子节点
var p = document.getElementById('p');
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
p.textContent= 'ABC';
// appendChild:把一个子节点添加到父节点的最后一个子节点
// insertBefore:把子节点插入到指定的位置
parentElement.insertBefore(newElement, referenceElement);
// setAttribute:在指定元素中添加一个属性节点,如果元素中已有该属性改变属性值
const div = document.getElementById('id')
div.setAttribute('class', 'white');
// removeChild:删除一个节点,首先要获取该节点本身以及父节点
const self = document.getElementById('to-be-removed');
const parent = self.parentElement;
parent.removeChild(self);
// 修改文字颜色
p.style.color = 'red';
// 添加CSS类
p.classList.add('active');
4. BOM(浏览器对象模型)
与浏览器做一些交互效果,比如页面的后退、前进、刷新、窗口变化等等,以及获取客户的一些信息,比如屏幕分辨率等。
4.1 window
window.open():导航到一个特定的url,也可以打开一个新的浏览器窗口
window.close():仅用于window.open()打开的窗口
4.2 location
location.reload():重新刷新当前页面。如果要强制从服务器中重新加载,传递一个参数true。
4.3 navigator
用来获取浏览器的属性,区分浏览器类型。
以下是常见navigator
对象接口定义的属性和方法表格:
属性/方法 | 描述 |
---|---|
navigator.userAgent | 返回浏览器用户代理字符串 |
navigator.platform | 返回浏览器运行的操作系统平台 |
navigator.language | 返回浏览器首选项语言 |
navigator.onLine | 返回布尔值表示浏览器是否联网 |
navigator.cookieEnabled | 返回布尔值表示是否启用cookie |
navigator.geolocation | 提供访问设备地理位置的能力 |
navigator.mediaDevices | 提供访问媒体设备(摄像头/麦克风)的接口 |
navigator.plugins | 返回已安装浏览器插件的列表 |
navigator.javaEnabled() | 返回布尔值表示浏览器是否支持并启用了Java |
navigator.sendBeacon() | 异步发送少量数据到Web服务器 |
navigator.share() | 调用原生分享机制(需用户触发) |
navigator.vibrate() | 触发设备振动(移动端支持) |
navigator.getBattery() | 返回Promise对象,获取设备电池信息 |
navigator.storage | 提供存储管理接口(如持久化存储请求) |
注意:
- 部分API需要安全上下文(HTTPS环境)
- 部分功能受浏览器兼容性限制
- 某些属性(如
plugins
)在现代浏览器中可能返回空值或受限信息
4.4 screen
以下是浏览器对象模型(BOM)中screen对象的常用属性和方法表格:
属性/方法 | 描述 | 示例值 |
---|---|---|
screen.width | 屏幕的总宽度(像素) | 1440 |
screen.height | 屏幕的总高度(像素) | 900 |
screen.availWidth | 可用显示区域宽度(排除系统任务栏等界面元素) | 1392 |
screen.availHeight | 可用显示区域高度(排除系统任务栏等界面元素) | 848 |
screen.colorDepth | 显示器的颜色深度(比特/像素) | 24 |
screen.pixelDepth | 显示器的像素深度(现代浏览器通常与colorDepth相同) | 24 |
screen.orientation | 返回屏幕方向信息的对象(包含type 和angle 属性) | { angle: 0, type: "landscape-primary" } |
使用示例:
console.log("当前屏幕分辨率:" + screen.width + "x" + screen.height);
console.log("可用工作区尺寸:" + screen.availWidth + "x" + screen.availHeight);
console.log("屏幕方向:" + screen.orientation.type);
4.5 history
history对象主要用来操作浏览器url的历史记录。
以下是浏览器history对象的常用方法总结表格:
方法名称 | 参数 | 返回值 | 描述 |
---|---|---|---|
back() | 无 | void | 回退到上一个浏览记录,相当于点击浏览器后退按钮 |
forward() | 无 | void | 前进到下一个浏览记录,相当于点击浏览器前进按钮 |
go(n) | 整数(正/负) | void | 跳转到指定步数的历史记录,如go(-2)后退两步,go(1)前进一步 |
pushState() | state, title, url | void | 添加新的历史记录条目(不刷新页面) |
replaceState() | state, title, url | void | 替换当前历史记录条目(不刷新页面) |
说明:
-
pushState/replaceState参数说明:
- state:关联的状态对象(最大640KB)
- title:大多数浏览器忽略此参数
- url:可选的新地址(需符合同源策略)
-
使用示例:
// 添加新记录
history.pushState({page:1}, "", "/page1");
// 替换当前记录
history.replaceState({page:2}, "", "/page2");
// 导航控制
history.back();
history.go(-2);
- 注意事项:
- 这些方法不会触发页面刷新
- 需要配合popstate事件监听历史记录变化
- URL参数需符合同源策略要求
5. ==和===
在JavaScript中,==
和===
的区别主要体现在类型转换机制上:
5.1 宽松相等(==)
- 执行类型转换后比较值
- 转换规则示例:
0 == false
→true
(数值转换)'' == 0
→true
(空字符串转0)'5' == 5
→true
(字符串转数字)null == undefined
→true
(特殊规则)
5.2 严格相等(===)
- 不进行类型转换
- 必须类型和值都相同:
0 === false
→false
'' === 0
→false
'5' === 5
→false
null === undefined
→false
特殊案例:
NaN === NaN // false(所有NaN比较都返回false)
+0 === -0 // true
{} === {} // false(对象比较内存地址)
6. 原型与原型链
6.1 原型对象
每个函数创建时都会自动获得prototype
属性(构造函数的原型对象),该对象包含constructor
属性指回构造函数:
function Person(name) {
this.name = name
}
// 原型方法
Person.prototype.sayHello = function() {
console.log(`你好,我是${this.name}`)
}
const p1 = new Person('小明')
p1.sayHello() // 输出:你好,我是小明
6.2 原型链结构
访问对象属性时的查找顺序:
- 对象自身属性
__proto__
指向的原型对象- 原型对象的原型(形成链式结构)
- 直到
Object.prototype.__proto__
为null
6.3 原型继承示例
function Student(name, grade) {
Person.call(this, name)
this.grade = grade
}
// 建立原型链关系
Student.prototype = Object.create(Person.prototype)
Student.prototype.constructor = Student
Student.prototype.showGrade = function() {
console.log(`我是${this.grade}年级学生`)
}
const s1 = new Student('小红', 3)
s1.sayHello() // 继承自Person
s1.showGrade() // 自身方法
6.4 关键特性
特性 | 说明 |
---|---|
Object.getPrototypeOf() | 获取对象的原型 |
obj.hasOwnProperty() | 检测是否自身属性 |
instanceof | 检测原型链关系 |
Object.create() | 创建指定原型的新对象 |
6.5 注意事项
- 避免修改内置对象的原型(如Array.prototype)
- 使用
Object.create(null)
创建无原型对象 - 现代代码推荐使用
class
语法(本质仍是原型继承):
class Teacher extends Person {
constructor(name, subject) {
super(name)
this.subject = subject
}
}
7. this对象
在JavaScript中,this
是一个动态绑定的特殊对象,其指向取决于函数的调用方式。以下是常见场景分析:
7.1 全局环境
在全局作用域中,this
指向全局对象:
console.log(this === window); // 浏览器环境输出true
7.2 函数调用
普通函数中的this
指向取决于调用模式:
function showThis() {
console.log(this);
}
showThis(); // 非严格模式指向window,严格模式为undefined
7.3 方法调用
当函数作为对象方法调用时,this
指向调用对象:
const obj = {
name: 'Object',
logThis: function() {
console.log(this.name); // 输出"Object"
}
}
obj.logThis();
7.4 构造函数
通过new
调用构造函数时,this
指向新创建实例:
function Person(name) {
this.name = name;
}
const p = new Person('Alice');
console.log(p.name); // 输出"Alice"
7.5 箭头函数
箭头函数没有自己的this
,继承外层上下文:
const obj = {
traditional: function() {
setTimeout(function() {
console.log(this); // 指向window
}, 100);
},
arrow: function() {
setTimeout(() => {
console.log(this); // 指向obj
}, 100);
}
}
7.6 显式绑定方法
通过call/apply/bind
强制指定this
:
function greet() {
console.log(`Hello ${this.name}`);
}
const user = {name: 'Bob'};
greet.call(user); // 输出"Hello Bob"
7.7 常见误区
回调函数中的this
丢失:
const obj = {
data: 1,
handle: function() {
// 此处this可能丢失
setTimeout(this.logData, 100);
},
logData: function() {
console.log(this.data); // 输出undefined
}
}
// 正确写法应使用箭头函数或bind绑定
8. bind、call、apply区别
这三个方法均用于显式绑定函数执行时的this
指向,实现不同对象间方法的复用。
8.1 具体用法
- call:立即执行函数,第一个参数为
this
绑定对象,后续参数逐个传递
func.call(thisArg, arg1, arg2, ...)
- apply:立即执行函数,第一个参数为
this
绑定对象,第二个参数为数组形式的参数列表
func.apply(thisArg, [argsArray])
- bind:返回新函数,第一个参数为永久绑定的
this
对象,可预设初始参数
const boundFunc = func.bind(thisArg, arg1, arg2)
boundFunc() // 后续调用
8.2 典型场景
- 对象方法借用
const person = { name: 'Alice' };
function showName() { console.log(this.name) }
showName.call(person) // 输出:Alice
- 参数处理
// 求数组最大值
Math.max.apply(null, [1, 5, 3]) // 5
// 合并数组
const arr1 = [1, 2]
const arr2 = [3, 4]
arr1.push.apply(arr1, arr2) // arr1变为[1,2,3,4]
- 事件绑定
class Button {
constructor() {
this.text = 'Click me'
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
console.log(this.text)
}
}
8.3 关键区别
特性 | call | apply | bind |
---|---|---|---|
执行时机 | 立即执行 | 立即执行 | 返回绑定函数 |
参数形式 | 逗号分隔参数 | 单个数组参数 | 逗号分隔参数 |
应用场景 | 明确参数数量 | 动态参数数量 | 延迟执行场景 |