js变量和数据类型

变量

JavaScript是弱类型的语言,变量是松散的。所谓松散是可以保存任何类型的变量。即声明不同数据类型的变量使用同一个关键字 var,变量就是变化的量,变量的作用就是用来装数据的容器。声明变量的时候不用考虑类型,但是处理和计算的时候要考虑类型.

定义变量

定义变量使用关键字 var来定义变量名。

1
2
3
4
// 在全局作用域下声明了变量 a
var a;
// 使用赋值运算符来给变量赋值
a = "a此时是字符串";

赋值:

  • 赋值运算符为“=”,这个等号不用判断两者是否相同。
  • 如果判断是否相同,可使用==(===)。

以上两步可简写为:

1
var a = "a此时是字符串";

注意:

1
2
3
function foo(){
msg = "我是函数内部定义的全局变量";
}

上面例子省略了var操作符, msg 就变成了全局变量,函数外部也能访问到,但不要这样做!。

变量命名规范

  • 由字母、数字、下划线、$ 组成且开头不能是数字定义变量名。
  • 不能使用特殊符号或者特殊符号开头来定义变量名(_除外)。
  • 不能以关键字来定义变量名
  • 变量的名称要有实际意义
  • 规则中所说的字母包括ASCII和Unicode字母字符,如汉字,但不推荐使用
  • 变量的命名遵守驼峰命名法,首字母小写,第二个单词的首字母大写 例如:userName

    • 关键字
1
2
3
4
5
6
7
break        do          instanceof     typeof
case else new var
catch finally return void
continue for switch while
debugger* function this with
default if throw
delete in try
  • 不能使用保留字来定义变量名 (保留字)
1
2
3
4
5
6
7
8
abstract        enum         int           short
boolean export interface static
byte extends long super
char final native synchronized
class float package throws
const goto private transient
debugger implements protected volatile
double import public

注意:在JS中,是严格区分大小写的。

执行环境和作用域

执行环境是 JavaScript 中最为重要的一个概念。定义了变量或函数有权访问其它数据。每个环境中都有一个与之关联的变量对象,我们编写的代码无法访问,但是环境中定义的变量存放在这个对象中。

全局执行环境是最外围的一个执行环境。根据 ECMAScript 实现所在的宿主环境的不同,表示执行环境的对象也不一样。在 web 浏览器中,全局执行环境被认为是 window 对象,因此所有的全局变量和函数都是作为 window 对象的属性和方法创建的。某个环境中的代码全部执行完,该环境中的变量被销毁,保存在其中的所有的变量和函数定义也随之销毁。全局执行环境直到应用程序退出才销毁。

每个函数都有自己的执行环境。当代码在一个环境中执行时,会创建作用域链。作用域链式保证对执行环境有权访问的所有变量和函数的有序访问。作用域的前端始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始的时候只包含一个变量,即 arguments 对象。作用域中的下一个变量对象来说包含(外部的环境),而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的变量对象始终都是作用域链中的最后一个对象。

一个变量的作用域是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在 JavaScript 代码中任何地方都是有定义的。而在函数内部声明的变量只有在函数体内有定义,它们是局部变量,作用域是局部的。

在函数体内部,局部变量的优先级高于同名的全局变量。

函数作用域和声明提前

块级作用域是指在一对花括号内的代码都具有各自的作用域,而且变量在声明它们的代码之外是不可见的。但是 JavaScript 没有块级作用域的概念。而是使用了函数作用域。JavaScript 的函数作用域是指函数内声明的所有变量在函数体内始终是可见的。

1
2
3
4
5
6
7
8
9
10
11
function test(o){
var i = 0; // i 在整个函数体内部有定义
if (typeof o == 'object'){
var j = 0; // j 在函数体内有定义
for(var k = 0; k < 10; k++){ // k 在函数体内是有定义的,不仅仅是在循环内
console.log(k); // 输出 0~9
}
console.log(k); // 输出 10
}
console.log(j); // j 已经定义了,但是可能没有初始化
}

作为属性的变量

当声明一个变量时,实际上是定义了一个全局对象的一个属性,当使用 var 声明变量时,创建的这个对象是不可配置的,也就是说这个变量不能通过 delete 操作符来删除。如果在非严格模式下,给一个未声明的全局变量赋值的话, JavaScript 会自动创建一个全局变量。以这种方式创建的变量是全局对象的正常的可配置属性,并且可以删除它们。

作用域链

嵌套的函数体内部,可以访问它上一级作用域中的变量。

延长作用域链:

  • try-catch 语句
  • with 语句

垃圾收集

  • 标记清除
  • 引用计数
  • 性能问题
  • 管理内存

数据类型

javaScript 数据类型有两类: 基本数据类型 和 复杂数据类型,其中基本数据类型(简单类型)有: Number/String/Boolean/Uundefined/Null一种复杂数据类型:object:Array/Date/Math/RegExp/

typeof 操作符

  • “undefined” –> 这个值未定义
  • “boolean” –> 这个值是布尔值
  • “string” –> 这个只是字符串
  • “number” –> 这个值是数值
  • “object” –> 这个值是对象或null
  • “function” –> 这个值是函数

typeof 操作符号后面的操作数可以是变量,也可以是字面量;

typeof 误区:

  • null 值返回 “object”;
  • Safari5 以及之前的版本、Chrome7 以及之前的版本对正则表达式调用返回”object”,
  • 其他浏览器在这种情况下返回”object”
  • 未初始化的变量和没有定义的变量操作符 typeof 都返回 “undefined”, 但它们有本质区别

Number 数据类型

字面量: var num = 数字;

包括正数,负数,小数

  • 取值范围:
    • 能表示的最大值是±1.7976931348623157乘以10的308次方
    • 能表示的最小值是±5 乘以10的-324次方
  • 表示方式
    • 十进制
    • 十六进制 以 0x 开头,从 0-9,a(A) 到 f(F)的范围。
    • 八进制 以 0 开头,0-7 组成。
  • NaN (not a number) 也是 number 类型,NaN 不等于自身
  • 两个都为字符串的变量相减,得到的是NaN.

  • 浮点数:

    • 计算浮点数时会丢失精度
    • 通常用整数的计算来表示浮点数的计算
    • 不要以两个浮点数是否相等作为条件判断的依据(判断范围还是可以的)

String,字符串类型

字面量: var str = “字符串”;

字符串的长度: str.length;

  • 凡是用””或者’’引起来的全是字符串类型。

转义字符

  • \” 转双引号
  • \’ 转单引
  • \r 回车
  • \n 换行
  • \t 制表符
  • \f 进纸
  • \xnn 以十六进制表示一个字符(n 是 0~F)
  • \unnnn 以十六进制代码nnnn表示一个 Unicode 字符 (n 是 0~F)

字符串的特点

ECMAScript 中的字符串是不可变的,也就是说,字符串一旦创建,它们的直就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含心智的字符串填充该变量。如:

1
2
var str = "Java";
str = str + "Script";

转换为字符串

数值、布尔值、对象和字符串值都有 toString()方法, 但是 null 和 undefined 没用这个方法。

调用toString() 方法时,大多数情况下不传参数,但是如果传递了一个参数,输出数值的基数。默认情况下,toString() 方法以十进制格式返回数值字符串表示。而通过传递基数,可以输出对应的二进制、八进制、十六进制。

1
2
3
4
5
6
var n = 10;
console.log(n.toString()); // "10"
console.log(n.toString(2)); // "1010"
console.log(n.toString(8)); // "12"
console.log(n.toString(10)); // "10"
console.log(n.toString(16)); // "a"

在不知道要转换的值是什么类型的时候,可以用 String() 函数,它可以将任意类型转成字符串。

Boolean 布尔类型

  • 布尔数据类型两个数据值: true/false
  • 实际运算中,true 代表1, false代表0;

Undefined 表示声明但未赋值的变量

在 js 中,一下四种情况的返回值是 undefined

  • 变量声明了但没有赋值
  • 函数没有返回值默认返回undefined
  • 函数传递的实参个数少于形参个数时,未传递的参数值为undefined
  • 对象没有定义的属性默认为undefined

Null

typeof判断时值为 object(值为空)/引用为空,内存里找不到这个变量。

再如:

1
console.log(undefined == null);  // true 两等号判断,两边都转成false

总的来说,只要意在保存对象的变量还没有真正保存对象,就应该让该变量保存 null 值,这样做体现了 null 作为空对象指针的惯例,也区分了 undefined 和 null。

复杂类型(来自JavaScript高级程序设计)

  • object 对象

ECMAScript 中的对象就是一组数据和功能的集合。可以通过 new 操作符后跟要创建的对象类型的名称来创建。而创建 Object 类型的实例并为其添加属性或方法,就可以创建自定义对象,如:

1
var o = new Object();

Object的每个实例具有的属性和方法

  • constructor: 保存着用于创建当前对象的函数,即构造函数。
  • hasOwnProperty(propertyName): 用于检查给定的属性在当前对象的实例中(而不是在原型中)存在;参数是字符串。
  • isPrototypeOf(object): 检查传入的对象是否是传入对象的原型。
  • propertyIsEnumerable(propertyName): 检查给定的属性是否能够使用 for-in 语言来枚举。参数是字符串。
  • toLocalString(): 返回对象的字符串表示,该字符串与执行环境的地区对应。
  • toString(): 返回对象的字符串表示。
  • valueOf(): 返回对象的字符串、数值、或布尔值表示。通常与 toString() 方法的返回值相同。

数据类型转换

隐式数据类型转换

变量参与到运算中,程序对变量进行的数据类型转换(不是程序员进行的数据类型)

强制数据类型转换

  • 将数字转换为字符串
    • String
    • 变量.toString ,注意:null 和 undefined 没有 toString() 方法
  • 将字符串转换为数字
    • Number
      • 转换后保留原数据,不会对数据进行四舍五入。
      • 非数字类型字符串转换后,比如 undefined,得到 NaN 。
      • 如果字符串中包含有效的十六进制格式,则将其转换为相同大小的十进制整数值。
    • parseInt
      • 对小数转换后保留的是整数部分,不会对数据进行四舍五入。
      • 如果是数字后边有非数字字符串,转换后得到的是前边数字的整数部分。
    • parseFloat
      • 转换为数字类型之后保留原数据,不进行四舍五入。
      • 非数字类型字符串转换后,得到 NaN 。
      • 如果是数字后边有非数字字符串,转换后得到的是前边数字的部分。
  • 将其他类型转换为布尔类型:所有类型的值都可以转化成布尔值
    • Boolean
    • 会转化成false的值有:
      • 空字符串
      • 数值零
      • NaN
      • undefined
      • null

假值:空字符串””/数字0/null/undefined/false/NaN

基本数据类型和复杂数据类型总结

  • 基本类型—值类型— String Undefined Number Boolean Null
  • 复杂类型—引用类型– Object 数组–Array,Date….

  • 基本类型的值存储在—- 栈中

  • 复杂类型的地址(引用)存储在栈中,—地址指向的空间中的对象(对象)—对象存储在堆中

    • 创建对象并返回对象—返回的是对象的地址(对象在堆空间中的地址)
  • 基本类型传值的时候,传递的是值

  • 复杂类型(引用类型)传递的时候,传递的是:地址(引用)

感谢您的支持!
0%