JavaScript基本概念之变量与数据类型

    • 变量
      • 变量定义
      • 变量的作用域
        • 全局作用域
        • 名字空间的概念
        • 局部作用域
        • 常量
    • 数据类型
      • 基本数据类型
        • Undefined类型
        • Null类型
        • Number类型
        • Number类型的NaN
        • 字符串类型
      • 引用类型
        • Object类型
        • Array类型
        • Date类型
        • RegExp类型
        • Function类型
        • 基本包装类型

变量

变量定义

ECMAScript的变量是松散类型,也就是说可以用来保存任何类型的数据。每个变量仅仅是一个用于保存值的占位符。
我们通过var操作符来声明一个变量:var message;

var message = "hi";
message = 100; // 有效,但不推荐

我们不建议修改变量保存值的类型。

变量的作用域

JavaScript中用var申明的变量是有作用域的。
1. 如果变量在函数内部申明,则该变量的作用域为整个函数体,在函数外不可引用(会报ReferenceError)
2. 由于函数可以嵌套,内部函数可以访问外部函数定义的变量,反过来不可以。

变量提升:JS函数定义会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部

'use strict';

function foo() {
    var x = 'Hello, ' + y;//这里不会报错,因为y在后面有申明。但是此时y为undefined。
    alert(x);
    var y = 'Bob';
}

foo();

我们要严格遵守:在函数内部首先申明所有变量。
常见的做法是用一个var申明函数内的所有变量,用逗号隔开:

function foo() {
    var 
        x = 1, // x初始化为1
        y = x + 1, // y初始化为2
        z, i; // z和i为undefined
    // 其他语句:
    for (i=0; i<100; i++) {
        ...
    }
}

全局作用域

不在任何函数内定义的变量就具有全局作用域。而window是JavaScript的一个全局对象(Node里面没有window全局对象)。而全局作用域的变量实际上是被绑定在window的一个属性。而 函数对于JavaScript来说也是一个对象,所以我们也可以通过window来访问。
由此,可以推断出来,常用的alert()函数也是window对象的一个属性。(所以我们可以对alert函数重构,但是最好不要这么做)。
—->说明JS只有一个全局作用域。

名字空间的概念

问题:因为全局变量都会绑定到window上面。而不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都可能会造成命名冲突,而且很难察觉。

解决办法:我们可以把自己的所有变量和函数全部绑定到一个全局变量当中。

// 唯一的全局变量MYAPP:
var MYAPP = {};

// 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0;

// 其他函数:
MYAPP.foo = function () {
    return 'foo';
};

MYAPP就是一个名字空间,可以大大减少全局变量的冲突。(比如JQuery,underscore)

局部作用域

需要注意的是,for循环等语句是无法定义具有局部作用域的变量的(也就是说没有块级作用域)。

function foo() {
    for (var i=0; i<100; i++) {
        //
    }
    i += 100; // 仍然可以引用变量i
}

所以,ES6引入了新的关键字let,用来解决块级作用域的问题。

'use strict';

function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    i += 1; // SyntaxError
}

常量

问题:ES6之前,没有专门的常量。只是通过全部大写来习惯性规定为是常量(但还是变量)。
所以ES6引入了新的关键字const来定义常量,const和let都具有块级作用域。

const PI = 3.14;

数据类型

ECMAScript中的变量包含两种不同数据类型值:基本类型值和引用类型值。

基本数据类型

基本类型值指的是简短的数据段。有Undefined、 Null、 Boolean、 Number 和 String这5种基本数据类型。

Undefined类型

Undefined类型只有一个值,即特殊的undefined。
我们使用var声明变量但还没有初始化,这个变量的值就是undefined。(引入undefined的目的是为了正式区分空对象指针和未经初始化的变量)

var message; // 这个变量声明之后默认取得了 undefined 值
// 下面这个变量并没有声明
// var age
alert(message); // "undefined"
alert(age); // 产生错误

然而我们对为初始化的变量和未声明的变量使用typeof操作符,都返回undefined。(奇怪,但是有其逻辑上的合理性)

Null类型

Null类型只有一个值,即null。null值逻辑上表示空对象指针。所以typeof返回“object”。
如果我们定义的变量准备将来用于保存对象,我们最好将变量显式初始化为null。(可以进一步区分null和undefined)

Number类型

JS不区分整数和浮点数(双精度型),同一使用number表示。
比如:

123; // 整数123
0.456; // 浮点数0.456
1.2345e3; // 科学计数法表示1.2345x1000,等同于1234.5
-99; // 负数
NaN; // NaN表示Not a Number,当无法计算结果时用NaN表示
Infinity; // Infinity表示无限大,当数值超过了JavaScript的Number所能表示的最大值时,就表示为Infinity

对于NaN和infinity的区别,Infinity表示无穷大,比如 1/0 就是 Infinity;而 0/0就是NaN。

Number类型的NaN

NaN(not a number),是一个特殊的number类型。用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
NaN与任何值都不相等,任何涉及NaN的操作都会返回NaN。
isNaN( )函数用于判断是否是NaN.比如“”就不是(因为其可以转为0),而“a”就是(无法转为number)。

字符串类型

JS字符串使用‘ ’或“ ”表示,如果字符串包含 ’,可以在外面使用 ”包括,如果字符串包含 ”和 ’,可以使用 \ 转义,比如\n,\t等,
\u4e2d\u6587 表示中文

ES6新增加了一种表示多行字符串的方式(是反引号),直接使用:

`这是
多行
字符串
`;

模板字符串
多个字符串相联可以使用+号,自动转换成字符串。
而ES6新增加了一种模板字符串,可以自动替换字符串中的变量,也是使用反引号。

常见的操作字符串
假定 var s="abc"
s.length 返回字符串长度
字符串可以使用下标操作,但是溢出的时候不报错,但一律返回undefined。
强调的是,字符串是不可变的,如果对字符串某个索引赋值,不会报错,但是没有效果
toUpperCase() toLowerCase() 返回新的字符串,原字符串没有修改
indexOf() 检索,检索失败返回-1
substring()返回指定区间的子串

引用类型

引用类型值是保存在内存中的对象。变量赋值对象的时候,其实里面是对象的指针(我的理解)。所以基本类型值的赋值直接是新的值,对新的值修改不会改变原来的值:
JavaScript基本概念之变量与数据类型_第1张图片
JavaScript基本概念之变量与数据类型_第2张图片
而对引用类型变量的复制其实只是引用的复制。
另外,函数的参数传递仍然是值传递。

Object类型

通常有两种方式来创建Object类型的实例:

  • new Object()来创建一个新的对象
  • 直接通过{ }字面量表示法来创建

在ECMAScript中,所有的对象都是Object类型(这是重要的思想)。
每个Object的实例都有下面的属性和方法:

  • constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是 Object()。
  • hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如: o.hasOwnProperty(“name”))。
  • isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型(第 5 章将讨论原型) 。
  • propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句(本章后面将会讨论)来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
  • toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
  • toString():返回对象的字符串表示。
  • valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。

ECMA-262中的对象行为不一定适用于JS中的其他对象。比如浏览器环境中的对象。BOM和DOM都属于宿主对象。

我们通过new和对象字面量{}创建新的对象的区别在于,{}不会调用构造函数

  1. JS的对象是无序的集合数据类型,我们可以通过 . 操作符 或者下标来访问对象的属性。

  2. 如果对象的属性必须是有效的变量名。如果属性名包含特殊字符,需要用‘ ’包括起来(并且不能直接通过 . 操作符访问)。如果访问不存在的属性不会报错,,直接返回undefined。

  3. JS的对象是动态类型,可以自由地给其添加或删除属性(通过delete)。

Array类型

JS中的Array类型可以包含任意数据类型,通过索引下标来访问。
注意:

  • 如果直接给Array的length赋值的话,会改变Array的大小,Array变大使用undefined填充
  • 直接通过索引赋值(索引超出范围),同样会引起Array大小的变化
    不建议直接修改Array的大小,确保索引不会越界

数组的常用方法

  • Array.indexOf( ) : 搜索指定元素的位置

  • Array.slice():切片操作,返回新的Array,可以通过不传递参数复制一个新的数组(返回的是新的数组)

  • push和pop:在末尾添加若干元素;删除末尾的一个元素

  • unshift和shift:在开头添加若干元素;删除开头的一个元素(push,pop,unshift和shift都是在原数组上操作)

  • sort( ):按照默认顺序排序

  • reverse(): 转置数组 (值的注意的是sort和reverse是在原数组上操作)

  • splice():可以从指定的索引开始删除若干元素,再从该位置添加若干元素

  • concat():用于连接另一个数组,返回新的数组(concat可以接受任意个元素和Array,函数会自动拆分)

  • join(): join方法非常实用,可以将数组的每个元素通过指定的操作符连接成字符串

Date类型

Date在JS中表示日期和时间,获取系统当前时间,我们可以new一个Date。

var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳

时间戳是没有时区差别的。并且JS中用0-11表示月份。

Date常用的函数

  • var d = Date.parse(‘2015-06-24T19:49:22.875+08:00’);
    d; // 1435146562875
  • d.toLocaleString(); // ‘2015/6/24 下午7:49:22’,本地时间(北京时区+8:00),显示的字符串与操作系统设定的格式有关
  • d.toUTCString(); // ‘Wed, 24 Jun 2015 11:49:22 GMT’,UTC时间,与本地时间相差8小时

RegExp类型

ECMAScript是通过RegExp类型来支持正则表达式的,语法类似Perl

var expression = /pattern / flags;

具体的可以看google。

Function类型

JavaScript中函数是计算机科学中的first-class function概念,它本身也是一个对象。每个函数都是Function类型的实例(和其他引用类型一样具有属性和方法)。

JavaScript中是没有重载的,如果声明了两个同名函数,后面的会覆盖掉前面的同名函数。

基本包装类型

为了便于操作基本类型值, ECMAScript 还提供了 3 个特殊的引用类型: Boolean、 Number 和String。这些类型与前面介绍的其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行为。

本文原创发表于CSDN,为BruceYuj最近所学总结,欢迎转载,但请注明出处

你可能感兴趣的:(JavaScript)