前端面试之变量与数据类型

目录

一、声明变量

(1)let

(2)const

(3)var

var、let 和 const 的作用域差异

二、数据类型 

(1)基本类型

undefined和null

String 

模板字符串拼接:

number和bigint 

字符串转换为整数 :

 boolean

symbol

二、对象类型 

(1)Function函数

1.函数声明

2.函数表达式 

3.箭头函数

4.匿名函数

函数作用域

闭包 

(2)Array数组

常用数组方法

1.添加/删除元素

 2.合并/拼接数组

 3.查找元素

 4.遍历数组

 5.排序和反转

 6.其他实用方法

7. ES6+ 新增数组特性

1.扩展运算符

2. 解构赋值

 3.Array.from()

(3)Object对象

创建对象

访问属性

添加/修改属性

删除属性

常用静态方法

 对象实例方法

原型与继承

原型基础

更规范的继承方式

构造函数与原型

ES6+ 对象新特性

属性简写

计算属性名

对象解构

扩展运算符

对象与JSON


一、声明变量

(1)let
  • let声明的变量可以多次赋值。

(2)const
  • const修饰的值叫常量,只能赋值一次。

(3)var
  • var声明的变量可以多次赋值。
var、let 和 const 的作用域差异
  1. var:函数作用域

    • 在函数内部声明的变量只能在函数内部访问
    • 没有块级作用域
  2. let/const:块级作用域

    • 在 {} 块中声明的变量只能在该块中访问
    • 解决了 var 的变量提升和重复声明问题
function varExample() {if (true) {var x = 10;let y = 20;}console.log(x); // 10 (var 没有块级作用域)console.log(y); // 报错:y is not defined (let 有块级作用域)
}varExample();

二、数据类型 

(1)基本类型
undefined和null

undefined表示变量已被声明,但尚未被赋值。也就是说,变量存在,但没有具体的值。

  • 变量声明后未赋值时,默认值为 undefined

  • 如果函数没有返回值,那么它的返回值默认也是 undefined

  • 如果访问对象中不存在的属性,其值也是 undefined

    let a; // 声明变量 a,未赋值
    console.log(a); // 输出:undefinedfunction test() {// 没有返回值
    }
    console.log(test()); // 输出:undefinedconst obj = {};
    console.log(obj.property); // 输出:undefined

    null表示“空值”或“无对象”。

  • 明确表示变量的值为空,而不是未赋值。

  • 在类型检查中,null 是一个独立的类型,即 null 的类型是 object

总结:

  • undefined 表示变量未被赋值,是一个“未定义”的状态。

  • null 表示变量被明确赋值为空,是一个“空值”或“无对象”的状态。

String 

字符串是由字符组成的序列,用于表示文本数据。在 JavaScript 中,字符串可以用单引号(')、双引号(")或反引号(`)来定义。 

let singleQuoted = 'Hello, world!';
let doubleQuoted = "Hello, world!";
let backtickQuoted = `Hello, world!`;console.log(singleQuoted); // 输出:Hello, world!
console.log(doubleQuoted); // 输出:Hello, world!
console.log(backtickQuoted); // 输出:Hello, world!

传统字符串拼接:

let name = "Alice";
let age = 30;
let greeting = "Hello, " + name + "! You are " + age + " years old.";
console.log(greeting); // 输出:Hello, Alice! You are 30 years old.
模板字符串拼接:

(模板字符串是 ES6 的新特性)

模板字符串(Template Literals)是 ES6 引入的一种新的字符串表示方式,使用反引号(`)定义,并支持嵌入表达式和多行字符串。

let name = "Alice";
let age = 30;
let greeting = `Hello, ${name}! You are ${age} years old.`;
console.log(greeting); // 输出:Hello, Alice! You are 30 years old.
number和bigint 

Number 类型基于 IEEE 754 标准的双精度浮点数表示,因此可以表示小数。可以表示的数值范围是 -2^53 + 12^53 - 1。由于 Number 是基于浮点数表示的,因此在处理大整数或高精度计算时可能会出现精度问题。

console.log(0.1 + 0.2); // 输出:0.30000000000000004
console.log(9007199254740991 + 1); // 输出:9007199254740992
console.log(9007199254740992 + 1); // 输出:9007199254740992(精度丢失)
字符串转换为整数 :

1.parseInt

console.log(parseInt("12345")); // 输出:12345
console.log(parseInt("123.45")); // 输出:123(忽略小数部分)
console.log(parseInt("123abc")); // 输出:123(忽略非数字部分)
console.log(parseInt("abc123")); // 输出:NaN(开头不是数字)

 2.Number 构造函数

console.log(Number("123.45")); // 输出:123.45
console.log(Number("123abc")); // 输出:NaN

 3.一元加号运算符

console.log(+ "123.45"); // 输出:123.45
console.log(+ "123abc"); // 输出:NaN

 BigInt 是 ES2020 引入的一种新的数值类型,用于表示任意大小的整数。BigInt 可以表示任意大小的整数,没有上限。BigInt 保证整数的精确表示,不会出现精度问题。BigInt 字面量以 n 结尾,例如 123n。BigInt 支持基本的算术运算,但不能与 Number 类型直接进行运算,需要显式转换。

// Number
let num1 = 12345678901234567890;
let num2 = 12345678901234567890;
console.log(num1 + num2); // 输出:24691357802469135780,但可能会有精度问题// BigInt
let bigInt1 = 12345678901234567890n;
let bigInt2 = 12345678901234567890n;
console.log(bigInt1 + bigInt2); // 输出:24691357802469135780n,精确无误
 boolean

在 JavaScript 中,truthyfalsy 是两个非常重要的概念,用于描述值在布尔上下文中的表现。这些概念在条件语句(如 ifwhile 等)和逻辑运算中非常重要。

falsy:false、0、-0、""(空字符串)、null、undefined、NaN

truthy:true、1、{}(空对象)、[](空数组)等。

symbol

在 JavaScript 中,Symbol 是一种原始数据类型,用于表示唯一的、不可变的值。Symbol 是 ES6(ECMAScript 2015)引入的,旨在解决对象属性名称冲突的问题,并提供一种更安全的方式来定义对象的属性。

二、对象类型 

(1)Function函数

函数本质上是对象。这使得函数具有对象的特性,例如可以拥有属性和方法,可以作为变量赋值,可以作为参数传递,也可以作为返回值。这种特性使得 JavaScript 的函数非常强大和灵活。

1.函数声明
function greet(name) {return `Hello, ${name}!`;
}console.log(greet("Alice")); // 输出:Hello, Alice!
2.函数表达式 
const greet = function(name) {return `Hello, ${name}!`;
};console.log(greet("Bob")); // 输出:Hello, Bob!
3.箭头函数

ES6 引入了箭头函数(Arrow Function),它是一种更简洁的匿名函数语法。箭头函数省略了 function 关键字,并且可以省略花括号和 return 关键字(如果函数体只有一条语句)。

const greet = (name) => `Hello, ${name}!`;console.log(greet("Charlie")); // 输出:Hello, Charlie!
4.匿名函数

匿名函数也经常被用作高阶函数的参数,例如 mapfilterreduce

const numbers = [1, 2, 3, 4, 5];
const squared = numbers.map(function(num) {return num * num;
});console.log(squared); // 输出:[1, 4, 9, 16, 25]
函数作用域
  1. 函数作用域:在函数内部声明的变量只能在函数内部访问
  2. 局部变量:函数内部声明的变量
  3. 全局变量:函数外部声明的变量

JavaScript 使用作用域链来解析变量:

  1. 首先在当前函数作用域查找
  2. 如果找不到,向上一级作用域查找
  3. 直到全局作用域
  4. 如果全局作用域也没有,则报错
var a = 1;function outer() {var b = 2;function inner() {var c = 3;console.log(a + b + c); // 6 (可以访问所有外层变量)}inner();
}outer();
闭包 

闭包是指一个函数能够记住并访问其词法作用域,即使该函数在其词法作用域之外执行。

简单来说,闭包让函数可以"记住"它被创建时的环境,即使这个函数在创建它的环境之外被调用。

function outer() {let count = 0; // 外部函数的局部变量function inner() {count++; // 内部函数访问外部函数的变量console.log(count);}return inner; // 返回内部函数
}const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3

 在这个例子中,inner 函数就是一个闭包,它可以访问 outer 函数的 count 变量,即使 outer 函数已经执行完毕

闭包的特点

1.记忆环境:闭包会记住创建时的词法环境

2.持久性:闭包中的变量会一直存在,不会被垃圾回收

3.私有性:可以创建私有变量和方法

(2)Array数组

常用数组方法
1.添加/删除元素
方法描述返回值是否修改原数组
push()末尾添加一个或多个元素新长度
pop()删除最后一个元素被删除元素
unshift()开头添加一个或多个元素新长度
shift()删除第一个元素被删除元素
let arr = [1, 2, 3];arr.push(4); // [1, 2, 3, 4]
arr.pop();   // [1, 2, 3]
arr.unshift(0); // [0, 1, 2, 3]
arr.shift();    // [1, 2, 3]
 2.合并/拼接数组
// concat() - 合并数组(不修改原数组)
let arr1 = [1, 2];
let arr2 = [3, 4];
let combined = arr1.concat(arr2); // [1, 2, 3, 4]// splice() - 强大的数组修改方法(修改原数组)
let fruits = ['Apple', 'Banana', 'Orange'];
fruits.splice(1, 1, 'Mango', 'Peach'); 
// 从索引1开始,删除1个元素,插入'Mango'和'Peach'
// 结果: ['Apple', 'Mango', 'Peach', 'Orange']
 3.查找元素
let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];// indexOf() - 查找元素首次出现的位置
console.log(numbers.indexOf(3)); // 2// lastIndexOf() - 查找元素最后一次出现的位置
console.log(numbers.lastIndexOf(3)); // 6// includes() - 检查是否包含某元素
console.log(numbers.includes(5)); // true// find() - 查找第一个符合条件的元素
let found = numbers.find(item => item > 3); // 4// findIndex() - 查找第一个符合条件的元素索引
let foundIndex = numbers.findIndex(item => item > 3); // 3
 4.遍历数组
let fruits = ['Apple', 'Banana', 'Orange'];// forEach() - 遍历数组
fruits.forEach(function(item, index) {console.log(index, item);
});// map() - 映射新数组
let lengths = fruits.map(fruit => fruit.length); // [5, 6, 6]// filter() - 过滤数组
let longFruits = fruits.filter(fruit => fruit.length > 5); // ['Banana', 'Orange']// reduce() - 累积计算
let numbers = [1, 2, 3, 4];
let sum = numbers.reduce((total, num) => total + num, 0); // 10
 5.排序和反转
let numbers = [3, 1, 4, 2, 5];// sort() - 排序(修改原数组)
numbers.sort(); // [1, 2, 3, 4, 5]// 自定义排序
let scores = [88, 95, 70, 92];
scores.sort((a, b) => b - a); // 降序排序 [95, 92, 88, 70]// reverse() - 反转数组(修改原数组)
numbers.reverse(); // [5, 4, 3, 2, 1]
 6.其他实用方法
// slice() - 截取数组(不修改原数组)
let arr = [1, 2, 3, 4, 5];
let part = arr.slice(1, 3); // [2, 3]// join() - 数组转字符串
let str = arr.join('-'); // "1-2-3-4-5"// Array.isArray() - 检查是否为数组
console.log(Array.isArray(arr)); // true// fill() - 填充数组
let newArr = new Array(3).fill(0); // [0, 0, 0]// flat() - 扁平化数组
let nested = [1, [2, [3]]];
let flatArr = nested.flat(2); // [1, 2, 3]
7. ES6+ 新增数组特性
1.扩展运算符
// 复制数组
let arr = [1, 2, 3];
let arrCopy = [...arr]; // [1, 2, 3]// 合并数组
let combined = [...arr, 4, 5, ...[6, 7]]; // [1, 2, 3, 4, 5, 6, 7]
2. 解构赋值
let [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]
 3.Array.from()
// 从类数组对象创建数组
let arrayLike = {0: 'a', 1: 'b', length: 2};
let realArray = Array.from(arrayLike); // ['a', 'b']// 从可迭代对象创建数组
let set = new Set([1, 2, 3]);
let arrayFromSet = Array.from(set); // [1, 2, 3]

(3)Object对象

对象是 JavaScript 中最重要的数据类型之一,用于存储键值对集合。几乎所有 JavaScript 的值都可以视为对象,除了原始类型(string、number、boolean、null、undefined、symbol、bigint)。

创建对象
// 1. 对象字面量语法(最常用)
let person = {name: '张三',age: 30,isStudent: false
};// 2. 使用 Object 构造函数
let car = new Object();
car.make = 'Toyota';
car.model = 'Camry';// 3. 使用 Object.create()
let animal = Object.create(null);
animal.type = 'dog';
访问属性
// 点表示法
console.log(person.name); // '张三'// 方括号表示法(适用于动态属性名或包含特殊字符的属性名)
console.log(person['age']); // 30let key = 'isStudent';
console.log(person[key]); // false
添加/修改属性
// 添加新属性
person.job = '工程师';// 修改现有属性
person.age = 31;// 使用方括号表示法
person['favorite color'] = '蓝色'; // 属性名包含空格时
删除属性
delete person.isStudent; // 删除属性
console.log(person.isStudent); // undefined
常用静态方法
// Object.keys() - 获取对象所有可枚举属性的键
let keys = Object.keys(person); // ['name', 'age', 'job', 'favorite color']// Object.values() - 获取对象所有可枚举属性的值
let values = Object.values(person); // ['张三', 31, '工程师', '蓝色']// Object.entries() - 获取键值对数组
let entries = Object.entries(person); 
// [ ['name', '张三'], ['age', 31], ['job', '工程师'], ['favorite color', '蓝色'] ]// Object.assign() - 合并对象(浅拷贝)
let target = { a: 1 };
let source = { b: 2, c: 3 };
Object.assign(target, source); // { a: 1, b: 2, c: 3 }// Object.freeze() - 冻结对象,防止修改
let frozenObj = Object.freeze({ x: 1 });
frozenObj.x = 2; // 静默失败(严格模式下会报错)
 对象实例方法
let obj = {name: '示例对象',// 定义方法greet: function() {return `你好,我是${this.name}`;},// ES6简写方法语法sayHello() {return 'Hello!';}
};console.log(obj.greet()); // "你好,我是示例对象"
console.log(obj.sayHello()); // "Hello!"
原型与继承
原型基础
// 每个对象都有一个原型(__proto__属性,不推荐直接使用)
let animal = {eats: true
};let rabbit = {jumps: true,__proto__: animal // 设置原型(现代写法应使用Object.create)
};console.log(rabbit.eats); // true (通过原型继承)
更规范的继承方式
// 使用Object.create()创建带有指定原型的对象
let animal = {eats: true
};let rabbit = Object.create(animal);
rabbit.jumps = true;console.log(rabbit.eats); // true
构造函数与原型
// 构造函数
function Person(name, age) {this.name = name;this.age = age;
}// 通过原型添加方法
Person.prototype.greet = function() {return `你好,我是${this.name},今年${this.age}岁`;
};let john = new Person('John', 30);
console.log(john.greet()); // "你好,我是John,今年30岁"
ES6+ 对象新特性
属性简写
let name = '李四';
let age = 25;let person = {name,  // 等同于 name: nameage,   // 等同于 age: agegreet() {return `我是${this.name}`;}
};
计算属性名
let propKey = 'foo';let obj = {[propKey]: true,['b' + 'ar']: 123,[Symbol('id')]: 'symbolId'
};console.log(obj.foo); // true
console.log(obj.bar); // 123
对象解构
let options = {title: '菜单',width: 100,height: 200
};// 解构赋值
let { title, width, height } = options;console.log(title);  // '菜单'
console.log(width);  // 100
console.log(height); // 200
扩展运算符
let obj1 = { a: 1, b: 2 };
let obj2 = { c: 3, d: 4 };let merged = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
对象与JSON
// 对象转JSON字符串
let user = {name: "张三",age: 30
};let json = JSON.stringify(user);
console.log(json); // '{"name":"张三","age":30}'// JSON字符串转对象
let parsed = JSON.parse(json);
console.log(parsed.name); // "张三"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/85960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python queue

Python中的queue模块提供了多种队列实现,主要用于线程间安全通信。以下是主要用法: 基本队列类型: Queue:先进先出(FIFO)队列LifoQueue:后进先出(LIFO)队列,即栈PriorityQueue:优先级队列 常用方…

Linux驱动:class_create、device_create

udev是什么 动态管理设备文件 传统的 Linux 系统通过静态创建 /dev 目录下的设备文件(如早期的 mknod 命令),但现代系统中硬件设备(如 USB 设备、存储设备、串口等)热插拔频繁,udev 可实时响应设备事件&…

【vLLM 学习】Cpu Offload Lmcache

vLLM 是一款专为大语言模型推理加速而设计的框架,实现了 KV 缓存内存几乎零浪费,解决了内存管理瓶颈问题。 更多 vLLM 中文文档及教程可访问 →https://vllm.hyper.ai/ *在线运行 vLLM 入门教程:零基础分步指南 源码 examples/offline_inf…

基于深度强化学习的Scrapy-Redis分布式爬虫动态调度策略研究

在大数据时代,网络数据的采集与分析变得至关重要,分布式爬虫作为高效获取海量数据的工具,被广泛应用于各类场景。然而,传统的爬虫调度策略在面对复杂多变的网络环境和动态的抓取需求时,往往存在效率低下、资源浪费等问…

openlayers实现可拖拽的节点(类似知识图谱)

/** * 本文介绍了实现知识图谱可视化的技术方案,主要分为两个图层实现: * 1、线图层 不拖动 * 2、点图层 需要拖动 */ 线图层 - 负责绘制静态连接线,使用LineString创建线要素并添加到矢量图层; // 线图层 export function add…

酷黑NBA足球赛事直播源码体育直播M39模板赛事源码

源码名称:NBA足球赛事直播源码酷黑体育直播M39模板赛事源码 开发环境:帝国cms7.5 空间支持:phpmysql 带软件采集,可以挂着自动采集发布,无需人工操作! 演示地址:https://www.52muban.com/shop…

Verilog编程技巧01——如何编写三段式状态机

前言 Verilog编程技巧系列文章将聚焦于介绍Verilog的各种编程范式或者说技巧,编程技巧和编程规范有部分重合,但并非完全一样。规范更注重编码的格式,像变量命名、缩进、注释风格等,而编程技巧则更偏重更直观易读、更便于维护、综合…

豆包和deepseek 元宝 百度ai区别是什么

豆包、DeepSeek、元宝和百度 AI 有以下区别: 开发公司 豆包5:由字节跳动公司基于云雀模型开发。DeepSeek4:是深度求索打造的开源多模态大模型。元宝1:是腾讯混元模型的落地产品,整合了 DeepSeek - R1 与混元模型。百…

网页端 js 读取发票里的二维码信息(图片和PDF格式)

起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的&#xff…

读文献先读图:GO弦图怎么看?

GO弦图(Gene Ontology Chord Diagram)是一种用于展示基因功能富集结果的可视化工具,通过弦状连接可以更直观的展示基因与GO term(如生物过程、分子功能等)之间的关联。 GO弦图解读 ①内圈连线表示基因和生物过程之间的…

pandas随笔

主要操作两个对象:一维带标签数组 和 二维表格DataFrame 一维带标签数组Series pd.Series([1, 3, 5, np.nan, 6, 8]) ,结果如下: 可指定索引,pd.Series([1, 3, 5], index[a, b, c]) 二维表格DataFrame 创建时需要指定列名&a…

java教程笔记(十一)-泛型

Java 泛型(Generics)是 Java 5 引入的重要特性之一,它允许在定义类、接口和方法时使用类型参数。泛型的核心思想是将类型由具体的数据类型推迟到使用时再确定,从而提升代码的复用性和类型安全性。 1.泛型的基本概念 1. 什么是泛…

力扣刷题(第四十九天)

灵感来源 - 保持更新,努力学习 - python脚本学习 反转链表 解题思路 迭代法:通过遍历链表,逐个改变节点的指针方向。具体步骤如下: 使用三个指针:prev(初始为None)、curr(初始为…

设置应用程序图标

(1)找一张图片 (2)然后转ico图片 在线生成透明ICO图标——ICO图标制作 验证16x16就可以 降低exe大小 (3) 在xxx.pro修改 添加 (4) 删除 build 和 xxxpro_user文件 (5)编译project 和运行xx.exe (6)右键 设置快捷方式

免费wordpress模板下载

西瓜红色的免费wordpress模板,简洁实用又容易上手,适合新手使用。 下载 https://www.waimaoyes.com/moban/2231.html

【React】React 18 并发特性

React 18 引入了 并发特性(Concurrent Features),这是一次对 React 渲染机制的重大升级,让 React 更加智能、响应更流畅、资源更节省。 我们来详细讲解一下它的原理、特性、API 以及实际应用。 🧠 一、什么是并发特性…

FFMPEG 提取视频中指定起始时间及结束时间的视频,给出ffmpeg 命令

以下是提取视频中指定起始时间及结束时间的 ffmpeg 命令示例: bash 复制 ffmpeg -i input.mp4 -ss 00:01:30.00 -to 00:05:00.00 -c copy output.mp4 其中,-i input.mp4 是指定要处理的输入视频文件为 “input.mp4”。 -ss 00:01:30.00 表示指定视频的起始时间为 1 分 30 …

mybatis的if判断==‘1‘不生效,改成‘1‘.toString()才生效的原因

mybatis的xml文件中的if判断‘1’不生效&#xff0c;改成’1’.toString()才生效 Mapper接口传入的参数 List<Table> queryList(Param("state") String state);xml内容 <where><if test"state ! null and state 1">AND EXISTS(select…

AI 模型分类全解:特性与选择指南

人工智能&#xff08;AI&#xff09;技术正以前所未有的速度改变着我们的生活和工作方式。AI 模型作为实现人工智能的核心组件&#xff0c;种类繁多&#xff0c;功能各异。从简单的线性回归模型到复杂的深度学习网络&#xff0c;从文本生成到图像识别&#xff0c;AI 模型的应用…

01-python爬虫-第一个爬虫程序

开始学习 python 爬虫 第一个获取使用最多的网站-百度 源代码 并将源代码保存到文件中 from urllib.request import urlopenurl https://www.baidu.com resp urlopen(url)with open(baidu.html, w, encodingutf-8) as f:f.write(resp.read().decode(utf-8))知识点&#xf…