JavaScript面试题一

1. 数据类型

1.1 基本类型:存储在栈中

        Number、String、Boolean、Undefined、null、Symbol

        补充:boolean转换

数据类型truefalse
String非空字符串""
Number非零数值0、NaN
UndefinedN/Aundefined
Object任意对象null

 

1.2 引用类型:存储在堆中

        Object、Array、Function、....

1.3 区分类型的方法

方法基本类型结果引用类型结果注意事项
typeof返回对应类型字符串(如"number","string"

返回"object"

(函数返回"function"

1. typeof null 返回"object"

2. 无法区分具体引用类型

instanceof 始终返回false返回true(当匹配构造函数时)

1. 仅适用于检测引用类型

2. 跨窗口实例检测可能失效

Object.prototype.toString.call()

返回格式[object Type]

[object Number]

返回具体类型标识

[object Array]

1. 最精确的类型检测方法

2. 需通过call()调用

3. 对null/undefined返回[object Null/Undefined]

示例代码:

// 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提供存储管理接口(如持久化存储请求)

注意:

  1. 部分API需要安全上下文(HTTPS环境)
  2. 部分功能受浏览器兼容性限制
  3. 某些属性(如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返回屏幕方向信息的对象(包含typeangle属性){ 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, urlvoid添加新的历史记录条目(不刷新页面)
replaceState()state, title, urlvoid替换当前历史记录条目(不刷新页面)

说明:

  1. pushState/replaceState参数说明:

    • state:关联的状态对象(最大640KB)
    • title:大多数浏览器忽略此参数
    • url:可选的新地址(需符合同源策略)
  2. 使用示例:

// 添加新记录
history.pushState({page:1}, "", "/page1");

// 替换当前记录
history.replaceState({page:2}, "", "/page2");

// 导航控制
history.back();
history.go(-2);
  1. 注意事项:
  • 这些方法不会触发页面刷新
  • 需要配合popstate事件监听历史记录变化
  • URL参数需符合同源策略要求

5. ==和===

在JavaScript中,=====的区别主要体现在类型转换机制上:

5.1  宽松相等(==)

  • 执行类型转换后比较值
  • 转换规则示例:
    • 0 == falsetrue(数值转换)
    • '' == 0true(空字符串转0)
    • '5' == 5true(字符串转数字)
    • null == undefinedtrue(特殊规则)

5.2  严格相等(===)

  • 不进行类型转换
  • 必须类型和值都相同:
    • 0 === falsefalse
    • '' === 0false
    • '5' === 5false
    • null === undefinedfalse

特殊案例:

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 关键区别

特性callapplybind
执行时机立即执行立即执行返回绑定函数
参数形式逗号分隔参数单个数组参数逗号分隔参数
应用场景明确参数数量动态参数数量延迟执行场景

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值