03 基本概念

3.1 标识符、严格模式

js从语法上讲也是类c的语言。比较特别的一点是js标识符除了字母、下划线外,还可以以$开头。

要在脚本中开启严格模式,需要在脚本第一行加入"use strict";。这是一个编译指示(pragma),告诉js引擎切换到严格模式。

也可以指定某个函数在严格模式下执行

function doSomethins () {
"use strict";
// body
}

3.3 变量

js是松散类型,变量可以保存任何类型的数据。

在函数中定义一个变量,这个变量会在函数退出后销毁

function test() {
var message = "hi";
}
test();
alert(message); // error

如果不加var,则定义的是一个全局变量

function test() {
message = "hi";
}
test();
alert(message);

3.4 数据类型

typeof操作符

js中typeof是一个操作符,只是也可以像函数那样加括号使用。这个操作符的运算结果是一个字符串,一共有6种可能的结果

  • "undefined"

  • "boolean"

  • "string"

  • "number"

  • "object"

  • "function"

var message = "some string";
alert(typeof message); // string
alert(typeof(message)); // string
alert(typeof 59); // number

Undefined类型

Undefined类型只有一个值,即undefined。用var声明但是没有初始化的变量就是undefined类型。

var message;
alert(message == undefined); // true

但是未初始化和未声明的变量还是不一样的,使用未声明的变量会报错

var message;
// age未声明
// var age
alert(message); // undefined
alert(age); // error

但如果用typeof,则未初始化和未声明的变量都是undefined

var message;
// var age;
alert(typeof message); // undefined
alert(typeof age); // undefined

Null类型

Null类型变量也只有一个值,即null。null变量表示的是一个空对象指针,所以typeof会返回"object"

如果一个变量准备用来保存一个对象,则最好将改变量初始化为null。

Boolean类型

对任何数据类型的值调用Boolean函数,都会返回一个Boolean值。

数据类型

转换为true的值

转换为false的值

String

非空字符串

空字符串

Number

非0, Infinity

0, NaN

Object

任何对象

null

Undefined

Undefined

注意这里和python的区别,js中{},[]是true

Number类型

浮点数

js用IEEE754格式来保存整数和浮点数。浮点数的精度不如整数,永远不要用浮点数进行测试。

数值返回

es能表示的最大和最小的数分别是Number.MIN_VALUENumber.MAX_VALUE。超过这个范围会被自动转化为正负Infinity

函数isFinite()对于Number.MIN_VALUENumber.MAX_VALUE之间的数会返回true。

NaN

js中数值和非数值运算不能得到数值的,便会得到NaN(其他语言一般是报错)。NaN和任何值都不相等,包括自身。

数值转换

  • Number()

  • parseInt()

  • parseFloat()

Number能以任意数据类型作为参数,但是比较复杂,一般用后两个。parseInt的第二个参数能指定转换的基数。parseFloat则不能指定转换的基数。

String类型

转义字符中,\xnn以16进制代码表示一个字符,\unnnn以16进制代码表示一个Unicode字符。

字符串是不可变的。要改变某个变量中保存的字符串,会先销毁原来的字符串。

除null和undefined外的类型都有toString()方法。如果要转换的变量可能是null或undefined,则用String(变量)。另外对数值类型的变量用toString还可以指定基数。

var num = 2;
num.toString(2); // "10"

Object类型

Object类型是所有实例的基础。Object的每个实例都有以下属性和方法:

  • constructor:保存用于创建当前对象的函数。

  • hasOwnProperty(propertyName):用于检查给对的属性是否在当前对象实例中(不是在实例原型中),参数是字符串。

  • propertyIsEnumerable(propertyName):检查属性是否能用于for-in

  • isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型。

  • toString()

  • valueOf():在需要的时候被调用转换成对象对应的值,如用于操作符时。

function Foo() {}
function Bar() {}
function Baz() {}
Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);
var baz = new Baz();
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

3.6 语句

with语句能将代码的作用域设置到一个特定的对象中

var qs = location.search.substring(1);
var hostname = location.hostname;
var url = location.href;

上面的代码用with语句能被写成

with (location) {
var qs = search.substring(1);
var hostname = hostname;
var url = href;
}

with语句的性能可可读性都不好,不建议使用。

3.7 函数

概述

ECMA函数用function关键字声明,不必指定是否有返回。下面是一个例子

function sayHi (name, message) {
alert("Hello " + name + ", " + message);
}

理解参数

ECMA函数的参数在类型和数量上都是不固定的。ECMA函数的参数在内部是用一个数组来表示,函数接受到的永远是一个数组。在函数体内部可以通过arguments访问到这个数组。

arguments能通过索引取值,也有length属性,但不是Array类的实例。

function howManyArgs () {
alert(arguments.length);
}
howManyArgs("string", 54); // 2
howManyArgs(); // 0
howManyArgs(12); // 1

另外arguments的值永远与命名参数保持同步。它们的内存空间是独立的,但是值会同步。

function doAdd (num1, num2) {
arguments[1] = 10;
alert(arguments[0] + num2);
}
doAdd(1, 1); // 11

没有重载

其他语言靠参数的类型和数量不同来实现函数的重载。js由于上述性质,没有重载。