JavaScript 变量与数据类型

JavaScript 是一门动态类型语言,这意味着你无需提前声明变量的类型。在程序运行时,解释器会自动处理变量的类型。

变量简介

在 JavaScript 中,变量是用来存储数据值的容器。你可以使用 varlet, 或者 const 来声明一个变量。

  • var:在ES6之前广泛使用,定义一个函数作用域的变量或者定义一个全局变量,无块作用域概念。
  • let:ES6引入,定义一个块级作用域变量,只在最近的一组大括号内有效。
  • const:ES6引入,定义一个块级作用域的常量,并且这个常量不可以再赋值。

示例:

var oldWay = "我是老式声明变量的方式";
let newWay = "我是新式声明变量的方式";
const constantValue = "我是一个常量";

console.log(oldWay); // 输出: 我是老式声明变量的方式
console.log(newWay); // 输出: 我是新式声明变量的方式
console.log(constantValue); // 输出: 我是一个常量

数据类型

基本数据类型(原始类型)

JavaScript 有七种基本数据类型,它们是不可变的和可被复制的。

String(字符串)

代表文本数据,可以包括字母、数字或符号,必须用引号(单引号 '、双引号 " 或模板字符串 “`)包裹。

let greeting = 'Hello, World!';
let favNum = '42';
let template = `I said: ${greeting}`;

Number(数字)

JavaScript 里的所有数字都是浮点类型的,即它们都有小数点。 JavaScript也能表示整数,但这些实际上是没有小数点的浮点数。

let integer = 100;
let floatingPoint = 10.5;

Boolean(布尔值

只有两个值:true 和 false。这是 JavaScript 中最简单的数据类型,经常用于逻辑判断。

let isAdult = true;
let isMinor = false;

Null(空值)

null 在 JavaScript 中表示“无的值”或“空值”。它只有一个值:null

let empty = null;

Undefined(未定义)

一个没有被赋值的变量会有一个默认值 undefined

let notAssigned;
console.log(notAssigned); // 输出 "undefined"

Symbol(符号)

ES6 新增的类型,用于创建匿名和唯一的值。

let sym1 = Symbol('desc');
let sym2 = Symbol('desc');
console.log(sym1 === sym2); // 输出 "false",即使描述相同,也是不同的值

BigInt

ES10 引入的新型数据类型,表示大整数。

const bigInt = 1234567890123456789012345678901234567890n;

let bigNumber = BigInt(9007199254740991) + BigInt(1);
console.log(bigNumber);  // 输出:9007199254740992n

对象类型

在 JavaScript 中,对象可以被看作是属性的集合。与基本类型不同的是,对象类型存储的是引用地址,所以当你复制或者传递时,操作的是同一内存地址。除了基本数据类型以外,JavaScript 中的其他值都是对象。

Object

对象是包含一系列“键值对”的集合。可以用大括号 {} 来创建一个新对象。

let person = {
  name: 'Alice',
  age: 25,
  isStudent: true
};

Array

数组是一种特殊的对象,用于保存一系列有序的值。使用方括号 [] 可以创建一个数组。

let colors = ['Red', 'Green', 'Blue'];
console.log(colors[0]); // "Red"

Function

函数实际上是具有相关联代码的对象。

function greet(name) {
  return 'Hello ' + name;
}
console.log(greet('Alice')); // "Hello Alice"

动态类型

JavaScript 是一种动态类型语言,这意味着同一个变量可以被赋予不同类型的值。 示例:

let dynamicVar = "Hello, World";
console.log(typeof dynamicVar); // 输出: string

dynamicVar = 50;
console.log(typeof dynamicVar); // 输出: number

dynamicVar = true;
console.log(typeof dynamicVar); // 输出: boolean

dynamicVar = function() { console.log("Hi!"); };
console.log(typeof dynamicVar); // 输出: function

类型转换

在 JavaScript 中,类型转换发生在当运算符和函数被应用到不同类型的值上时。类型转换主要分为两种:显式转换和隐式转换。

显示转换

显式类型转换,又称为类型强制,是指开发者直接指定变量从一种类型转换为另一种类型。在 JavaScript 中可以通过各种内建函数进行显式转换。

字符串转换

我们可以使用 String 函数或者 .toString() 方法把一个值转换为字符串。

let value = 123;
let stringValue = String(value); // 使用String函数
console.log(stringValue); // 输出:"123"
console.log(typeof stringValue); // 输出:"string"

stringValue = value.toString(); // 使用.toString()方法
console.log(stringValue); // 输出:"123"
console.log(typeof stringValue); // 输出:"string"

数字转换

要将一个值转换为数字,可以使用 Number 函数,或者 parseInt 和 parseFloat 函数,取决于我们想要整数还是浮点数。

let stringNumber = "123";
let numberValue = Number(stringNumber); // 使用Number函数
console.log(numberValue); // 输出:123
console.log(typeof numberValue); // 输出:"number"

stringNumber = "123.456";
numberValue = parseFloat(stringNumber); // 获取浮点数
console.log(numberValue); // 输出:123.456

numberValue = parseInt(stringNumber); // 获取整数
console.log(numberValue); // 输出:123

布尔转换

Boolean 函数用来把任何类型的值转换为布尔类型。在 JavaScript 中,false0-00n""nullundefined, 和 NaN 都是被认为是 falsy(即它们会被转换为 false),而其他所有的值都被当作是 truthy(会被转换为 true)。

let truthyValue = "Hello";
let falsyValue = "";

console.log(Boolean(truthyValue)); // 输出:true
console.log(Boolean(falsyValue)); // 输出:false

隐式类型转换

隐式转换是指当代码中的操作符应用于不同类型的值时,JavaScript 解释器自动将数据类型转换为适合该操作符的类型。这种现象常常会在比较操作、逻辑操作、加法或减法等场合出现。

字符串拼接

使用加号 (+) 来处理字符串和其他类型的值时,JavaScript 会将所有的值转换为字符串。

let result = "Hit points: " + 50; // 数字被转换为字符串
console.log(result); // 输出:"Hit points: 50"

result = "The answer is " + true; // 布尔值被转换为字符串
console.log(result); // 输出:"The answer is true"

数学运算

在执行数学运算时,如果其中一个操作数是字符串,JavaScript 会尝试将这个字符串转换成数字。如果转换失败,则结果为 NaN(Not-a-Number)。

let result = "4" - "2"; // 字符串被转换为数字
console.log(result); // 输出:2,因为两个字符串都可以转换为数字

result = "five" * 2; // 字符串不能被转换为数字
console.log(result); // 输出:NaN

逻辑运算

在逻辑运算如 && 和 || 中,JavaScript 会将值转换为布尔类型来决定运算的结果。

let result = "Cat" && "Dog"; // 两个值都是 truthy
console.log(result); // 输出:"Dog"

result = false || "Dog"; // 第一个值是 falsy,返回第二个值
console.log(result); // 输出:"Dog"

比较运算

比较运算中的类型转换尤其有趣,因为不同的比较运算符有不同的行为。 使用 ==(宽松相等)会进行隐式类型转换。

console.log(123 == "123"); // 输出:true,字符串被转换为数字
console.log(1 == true); // 输出:true,布尔值被转换为数字

而使用 ===(严格相等)不会进行类型转换。

console.log(123 === "123"); // 输出:false,没有类型转换
console.log(1 === true); // 输出:false,没有类型转换

类型转换中的陷阱

比较相等时使用 == 而不是 ===

使用 ==(宽松相等)来比较不同类型的值会引发隐式类型转换,而 ===(严格相等)则不会进行类型转换。

// 这会导致隐式类型转换
console.log(0 == "");     // 输出:true
console.log(0 == "0");    // 输出:true
console.log(false == "0"); // 输出:true

// 严格相等运算符不会进行类型转换
console.log(0 === "");    // 输出:false
console.log(0 === "0");   // 输出:false
console.log(false === "0");// 输出:false

如果使用 + 运算符连接字符串和数字

字符串和数字相加时,数字会被转换为字符串,这可能会导致不是你期望的结果。

console.log("3" + 4 + 5); // 输出:"345"
console.log(3 + 4 + "5"); // 输出:"75"

null 和 undefined 的比较

null 和 undefined 相比较时是一个特例,使用 == 时它们相等,但是与其他值比较时不是这样。

console.log(null == undefined); // 输出:true
console.log(null == 0);         // 输出:false
console.log(null === undefined);// 输出:false

使用 Object 作为键名

对象在转换为字符串时通常会变成 "[object Object]",因此在使用对象作为字典的键名时要小心。

let obj = {};
obj[{}] = "Value";
console.log(obj["[object Object]"]); // 输出:"Value"

NaN 的奇特行为

NaN 是一个表示非数字的特殊值,它与任何值都不相等,包括它自己。

console.log(NaN == NaN); // 输出:false
console.log(NaN === NaN); // 输出:false
console.log(isNaN(NaN));  // 输出:true

NaN 表示“不是一个数字”,但它的类型是 number

let result = 'abc' - 1;
console.log(result);  // 输出:NaN
console.log(typeof result);  // 输出:number

布尔值的转换规则

console.log(Boolean(0));  // 输出:false
console.log(Boolean(1));  // 输出:true
console.log(Boolean(''));  // 输出:false
console.log(Boolean('Hello'));  // 输出:true
console.log(Boolean(null));  // 输出:false
console.log(Boolean(undefined));  // 输出:false
console.log(Boolean([]));  // 输出:true
console.log(Boolean({}));  // 输出:true

严格模式与非严格模式

JavaScript 可以在严格模式下执行,这可以防止某些不安全的操作,如不声明变量就使用它。 开启严格模式很简单,只需在脚本或者函数的开头加上 use strict

'use strict';
let safeMode = "Now I'm in strict mode";

在严格模式下,如果试图使用未声明的变量,JavaScript 会抛出错误。

面试实战

题一:JavaScript中有哪些数据类型?

答案:JavaScript有两大类数据类型:原始数据类型和对象类型。 原始数据类型包括:

  • undefined:表示未定义,变量声明但未初始化时的值。
  • null:表示空值或不存在的对象引用。
  • boolean:表示逻辑实体,可以是true或false。
  • number:表示数字,可以是整数或浮点数,还包括特殊的NaN和Infinity。
  • string:表示文本数据,字符串序列。
  • symbol:ECMAScript 6引入的新类型,表示独一无二的值,常用于对象属性的键。
  • bigint:ECMAScript 2020引入的新数据类型,用于表示大整数。

对象类型(非原始数据类型)包括:

  • Function:表示代码块,可以执行。
  • Object:表示键值对集合,包括如数组(Array)、日期(Date)和正则表达式(RegExp)等特殊对象类型。

题二:解释var, let和const的区别,并举例说明。

答案varlet, 和 const 是JavaScript中声明变量的三个关键字,它们有不同的作用域和特性。

  • var:声明一个变量,作用域为声明所在的函数或全局作用域,可以重复声明同一个变量,可以在声明之前使用(会提升),变量的值可以被修改。
var name = "Alice";
var name; // 重复声明是允许的
console.log(name); // 输出:Alice
  • let:声明一个块级作用域的变量,不能在同一个块级作用域内重复声明,不能在声明之前使用(不会提升),变量的值可以修改。
let age = 30;
// let age; // SyntaxError: Identifier 'age' has already been declared
{
  let age = 25; // 块级作用域内可以声明
  console.log(age); // 输出:25
}
console.log(age); // 输出:30
  • const:声明一个块级作用域的常量,同样不能重复声明且不能在声明前使用,声明时必须初始化,一旦赋值后不能再被修改(但如果值是对象,则对象的属性可以修改)。
const PI = 3.14;
// PI = 3; // TypeError: Assignment to constant variable.
const obj = { key: "value" };
obj.key = "new value"; // 可以修改对象属性
console.log(obj.key); // 输出:new value

解释以下代码的行为

const a = {name: 'Alice'};
a = {name: 'Bob'};

答案:代码会抛出 TypeError: Assignment to constant variable. 错误。const 声明的变量是一个常量,不能被重新赋值。这里尝试为 a 重新赋值一个新对象 {name: 'Bob'},因此会抛出类型错误。不过要注意的是,常量对象的属性是可以修改的。

const a = { name: 'Alice' };
a.name = 'Bob';
console.log(a.name);  // 输出 'Bob'

题三:如何检测变量的数据类型?

答案:可以使用typeof运算符或instanceof运算符,还可以使用Object.prototype.toString.call()方法。

  • typeof: 对于原始数据类型和函数比较有效。
typeof "Hello"; // "string"
typeof 42;      // "number"
typeof true;    // "boolean"
typeof Symbol(); // "symbol"
typeof undefined; // "undefined"
typeof function() {}; // "function"
  • instanceof:用于检查一个对象是否为一个特定的构造函数的实例。
[] instanceof Array;        // true
({}) instanceof Object;    // true
  • Object.prototype.toString.call():可以得到对象类型的最佳方式,对于所有标准的对象和用户定义的对象都有效。
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call({}); // "[object Object]"

题四:说明null和undefined的区别

  • null是JavaScript的字面量,表示空值;它是一个对象类型,故意指定为”没有对象”,这表示该处不应该有值。
  • undefined是全局对象的属性,表示变量已声明但还未被初始化。

一个变量在定义后没有赋值,那么它的值就是undefined。而如果你想表示某个值或变量目前不存在,应该用null来表示。

let foo;
console.log(foo); // undefined

let bar = null;
console.log(bar); // null

解释以下代码的输出

console.log(typeof null);
console.log(typeof undefined);

答案:

  • typeof null 输出 'object'null 是一个特殊的关键字,表示一个空对象引用。在 JavaScript 的最初版本中,typeof null也被定义为了 'object',这是一个早期实现中的错误,但出于兼容性考虑,这个错误被保留下来了。
  • typeof undefined 输出 'undefined'undefined 表示变量已声明但未初始化,所以 typeof undefined 正常返回'undefined'

题五:解释以下代码的输出

let x = 10;
let y = '10';

console.log(x + y);
console.log(x - y);

答案

  • x + y 输出 '1010'。在 x + y中,+ 操作符对一个字符串和一个数字进行操作时,进行字符串拼接,因此结果为 '1010'
  • x - y 输出 0。在 x - y 中,- 操作符会将字符串 '10'转换为10,于是计算结果为数值 0

题六:== 和 === 有什么不同?

答案== 是等值比较运算符,执行相等测试时会进行类型转换。如果两个值不是同一类型,JavaScript 会尝试将它们转换为一个适当的类型来比较。=== 是严格等值比较运算符,不进行类型转换。如果两个值类型不一致,=== 会立即返回 false,而不会试图将它们转换为同一类型。

解释以下代码的输出

let a;
let b = null;
console.log(a == b);
console.log(a === b);

答案

  • a == b 输出 true。== 运算符在比较时,会将 undefined 和 null 看作相等,因此 a == b 输出 true
  • a === b 输出 false=== 是严格相等运算符,它不仅比较值还比较类型。a 是 undefinedb 是 null,类型不同,因此 a === b 输出 false

原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/88368.html

Like (0)
guozi的头像guozi
Previous 2024年6月3日
Next 2024年6月3日

相关推荐

  • 如何做网页

    如何做网页?什么是网页?网页设计的基本原则?网页制作的步骤?常用的网页制作工具和软件?这些问题都曾困扰过不少想要进入云服务器行业的人。在当今互联网发展日新月异的时代,拥有一套优秀的…

    行业资讯 2024年4月20日
    0
  • 服务器回收图片

    服务器回收图片是目前网络安全加速行业中备受关注的一个重要话题。随着互联网的快速发展,服务器回收图片已经成为保障网络安全的必备环节,它不仅可以有效防止黑客入侵和信息泄露,还能够提高服…

    行业资讯 2024年4月15日
    0
  • 买虚拟主机

    云服务器行业中,有一项被称为“买虚拟主机”的服务备受瞩目。它究竟是什么?它有哪些优势和适用场景?它的价格标准如何?如何选择合适的虚拟主机服务商?在这篇文章中,我们将为您一一解答。让…

    行业资讯 2024年4月3日
    0
  • 更换服务器域名,更换服务器会影响权重吗

    互联网行业一直都充满着变化和挑战,但最近一个叫做“域名封杀”的问题再次引起了业界的关注。当您尝试打开网站但无法访问该网站时,您可能遇到过此问题。那么什么是域名被屏蔽呢?更重要的是,…

    行业资讯 2024年5月11日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注