在前端开发中,JavaScript(简称 JS)是实现页面交互与动态逻辑的核心语言。作为一门弱类型语言,它与 Java、C 等强类型语言在变量定义、数据存储和类型转换上存在显著差异。本文将结合实例,系统梳理 JS 中变量定义、数据类型、类型转换、作用域及常量等核心基础,帮助初学者快速建立对 JS 语法的认知。

一、变量定义:隐藏式与显示式

JS 定义变量的方式分为 “隐藏式” 和 “显示式”,核心区别在于是否使用关键字声明,这也是弱类型语言灵活性的体现。

1. 隐藏式定义(不推荐)

无需任何关键字,直接赋值即可创建变量。但不推荐在实际开发中使用—— 未声明的变量会默认挂载到全局对象(如 window)上,容易造成全局污染,且难以追溯变量来源。

a="123";
b=1;
c='a';

2. 显示式定义(推荐)

使用关键字 varletconst 来定义变量,明确变量的创建,避免全局污染风险。JS 作为弱类型语言,无需提前指定数据类型,赋值时会自动根据值判断类型

var h = "123";  // 字符串
var i = 'a';    // 字符
var j = 15.9;   // 数值

区别说明:

关键字 特点
var 变量提升、函数作用域
let 块级作用域、不能重复声明
const 常量、必须初始化、不可修改

二、数据类型与内存存储:弱类型 vs 强类型

理解 JS 的数据类型,首先要区分 “弱类型语言” 与 “强类型语言” 在内存存储上的差异。

1. 强类型语言(如 Java、C)的存储逻辑

强类型语言要求提前声明变量类型,编译器会根据类型直接开辟固定大小的内存空间:

  • int:32bit(1bit 符号位 + 31bit 数值位)
  • char:16bit(无符号,直接存储字符编码)
  • float:32bit(1bit 符号位 + 8bit 阶位 + 23bit 数值位)

例如在 Java 中,int num = 10;会直接开辟 32bit 内存存储整数 10,后续无法将字符串赋值给num(类型不可变)。

2. 弱类型语言(JS)的存储逻辑

JS 无需提前声明类型,赋值时会先判断值的类型,再动态开辟对应内存空间。同一变量可后续赋值不同类型的值(类型可变),这是 JS 与强类型语言的核心区别。

var num = 10;    // 初始为数值类型,开辟数值内存
num = "hello";   // 后续改为字符串类型,内存空间重新分配

3. JS 常见的基本数据类型

JS 的基本数据类型是构成所有逻辑的基础,具体分类及说明如下:

数据类型 说明 示例
数值类型(Number) 包含整数、浮点数、无穷大(Infinity)、非数(NaN)

var a = 10;

var b = 3.14;

字符串类型(String) 单引号 / 双引号包裹的文本,可存储任意字符 var str = "JS学习";
布尔类型(Boolean) 仅两个值:true(真)、false(假),用于逻辑判断 var isOk = true;
undefined 变量已声明但未赋值时的默认值 var x; console.log(x);
null 表示 “空值”,主动赋值给变量,常用于表示 “无对象” var obj = null;

三、类型转换:自动转换与强制转换

由于 JS 是弱类型语言,在运算或判断时会频繁发生类型转换,分为 “自动转换” 和 “强制转换”。

1. 自动类型转换(隐式转换)

JS 会在特定场景下(如算术运算)自动转换类型,最常见的是 “字符串转数值”。

  • 若字符串为合法数值(如"3.14"),会自动转为数值参与运算;
  • 若字符串为非数值(如"abc"),转换后会得到NaN(非数,NaN与任何值运算结果仍为NaN)。
    var a = "3.14";//字符串类型的数据
    var b = a - 2;//在js当中 这就是自动类型转化(将字符串类型转换成数值类型)
    var c = "abc";
    var d = c - 2;// 自动转换失败,结果为NaN
    alert(b);
    alert(d);// 输出:NaN

2. 强制类型转换(显式转换)

当自动转换不符合预期时,需使用内置方法强制转换类型,常用方法有 3 个:

方法名 作用 示例 结果
toString() 将数值 / 布尔值转为字符串 var num = 10; num.toString(); "10"
parseInt() 将值转为整数(忽略小数部分,非数值转 NaN) parseInt("3.14"); parseInt("abc");

3

NaN

parseFloat() 将值转为浮点数(保留小数,非数值转 NaN) parseFloat("3.14"); parseFloat("10");

3.14

10

    var c = parseInt(a) - 2;
    alert(c + '\n' + b)
    //parseInt(),paresFloat()如果转换成功就转化为数值,如果转换失败就是NAN
    alert(parseInt("abc"));

四、变量作用域:全局变量与局部变量

“作用域” 指变量的可访问范围,JS 中变量分为全局变量局部变量,核心区别在于定义位置。

  变量:全局变量和局部变量

  局部变量:定义在方法当中的变量

  全局变量的作用范围是全局

  局部变量的作用只在方法中

    var a = "全局变量"
    function myfun(){
        arg = 20;
        var b = "局部变量"
        alert(a);
    }
    myfun();//调用方法
    alert(a);
    //alert(b);

全局变量和局部变量重名时候,在方法内部变量覆盖全局变量,在方法外部局部变量失效

    var h = "hello";
    function test(){
        var h = "world";
        alert(h);
    }
    test();
    alert(h);

五、变量提升:JS 的 “预解析” 特性

JS 在执行代码前,会先进行 “预解析”—— 将函数内部用var声明的变量提升到函数顶部(仅提升声明,不提升赋值)。这会导致 “变量未赋值却被访问” 的情况,需特别注意。

    var a = 10;
    function test1(){
        //var a
        console.log(a);
        //a = 20
        var a = 20;
        console.log(a);
    }
    test();

在方法当中定义的变量自动提升到方法的最顶部,但是提示变量不提升值;方法中定义的a会覆盖掉原来的全局变量的值,让a变成一个没有赋值的变量,let关键字可解决 “变量提升” 问题 ——let声明的变量不会提升,且存在 “块级作用域”,建议优先使用let替代var

六、常量:用 const 声明不可变的值

“常量” 指一旦定义就无法修改的值,JS 中用const关键字声明,需遵循以下规则:

  1. 声明时必须立即赋值(不能先声明后赋值);
  2. 赋值后不可修改(修改会报错);
  3. 命名约定:常量名通常用 “大写字母 + 下划线”(如MAX_AGE),与变量区分。
    const MAX_AGE = 100;//正确的定义形式
    MAX_AGE = 101;//一旦定义,不能修改
    var a = 10;
    a = 11;
    //const MAX_HEIGHT;//没有初始值

七、字符串常用 API(扩展)

字符串是 JS 中最常用的数据类型之一,掌握以下常用 API 可提高开发效率:

API 方法 作用 示例 结果
charAt(index) 获取指定索引的字符(索引从 0 开始) "abc".charAt(1) "b"
charCodeAt(index) 获取指定索引字符的 Unicode 编码 "abc".charCodeAt(0) 97
length 获取字符串长度(属性,非方法) "abc".length 3
toUpperCase() 转为大写字母 "abc".toUpperCase() "ABC"
indexOf(substr, start) 从 start 位置开始,查找子串首次出现的索引(无则返回 - 1) "abcabc".indexOf("b", 2) 4
substring(start, end) 截取 [start, end) 区间的字符(不包含 end) "abcde".substring(1, 3) "bc"
split(sep) 按分隔符 sep 分割字符串,返回数组 "a,b,c".split(",") ["a","b","c"]
var text="jhgftyuiolkjhyuhj";
var a = text.charAt(0);//获取第一个字符*
var b = text.charCodeAt(1);//获取第二个字符对应的unicode值
var c = text.length;
var d = text.toUpperCase()//转换为大写
var e = text.indexOf("gf");//寻找l字串第一次出现的位置,如果没有就返回-1,有的话就返回位置
var g = text.indexOf("i",6);
//跳过6个字符后,寻找l字串第一次出现的位置,如果没有就返回-1,有的话就返回位置
var k = text.substring(3,6);//从原字符串中截取索引处3,4,5三个字符*
var r = text.slice(3,10);
//*截取的范围是索引 3 到索引 9 的字符(共 7 个字符),最终 r 的值就是这部分字符组成的新字符串。
var arr = text.split("a");//以a来把字符串分隔成组数(一般以,或者 空格 来进行分割)

注意:

slice 与 substring 的区别

slice 和 substring 都可用于截取字符串,核心区别在于对负数参数的处理:

  • slice 允许负数参数(表示从字符串末尾开始计数,例如 slice(-3) 表示从倒数第 3 个字符截取到末尾)。
  • substring 会将负数参数自动转为 0,不支持从末尾计数。
var str = "abcdef";
console.log(str.slice(2, -1)); // 输出 "cde"(从索引2到倒数第2个字符)
console.log(str.substring(2, -1)); // 等效于 substring(0, 2),输出 "ab"

最后希望这篇博客对你有帮助!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐