JavaScript之字面量 (Literals)

字面量是由语法表达式定义的常量;或,通过由一定字词组成的语词表达式定义的常量

JavaScript中,你可以使用各种字面量。这些字面量是脚本中按字面意思给出的固定的值,而不是变量。(译注:字面量是常量,其值是固定的,而且在程序脚本运行中不可更改,比如false,3.1415,thisIsStringOfHelloworld ,invokedFunction: myFunction("myArgument")。本节将介绍以下类型的字面量:

  • 数组字面量(Array literals)
  • 布尔字面量(Boolean literals)
  • 浮点数字面量(Floating-point literals)
  • 整数(Integers)
  • 对象字面量(Object literals)
  • RegExp literals
  • 字符串字面量(String literals)

数组字面量 (Array literals)

数组字面值是一个封闭在方括号对([])中的包含有零个或多个表达式的列表,其中每个表达式代表数组的一个元素。当你使用数组字面值创建一个数组时,该数组将会以指定的值作为其元素进行初始化,而其长度被设定为元素的个数。

下面的示例用3个元素生成数组coffees,它的长度是3。

var coffees = ["French Roast", "Colombian", "Kona"];
​
var a=[3];
​
console.log(a.length); // 1
​
console.log(a[0]); // 3

若在顶层(全局)脚本里用字面值创建数组,JavaScript语言将会在每次对包含该数组字面值的表达式求值时解释该数组。另一方面,在函数中使用的数组,将在每次调用函数时都会被创建一次。数组字面值同时也是数组对象。

数组字面值中的多余逗号

声明时你不必列举数组字面值中的所有元素。若你在同一行中连写两个逗号(,),数组中就会产生一个没有被指定的元素,其初始值是undefined。以下示例创建了一个名为fish的数组:

var fish = ["Lion", , "Angel"];

在这个数组中,有两个已被赋值的元素,和一个空元素(fish[0]是"Lion",fish[1]是undefined,而fish[2]是"Angel";译注:此时数组的长度属性fish.length是3)。

如果你在元素列表的尾部添加了一个逗号,它将会被忽略。在下面的例子中,数组的长度是3,并不存在myList[3]这个元素(译注:这是指数组的第4个元素噢,作者是在帮大家复习数组元素的排序命名方法)。元素列表中其它所有的逗号都表示一个新元素(的开始)。

注意:尾部的逗号在早期版本的浏览器中会产生错误,因而编程时的最佳实践方式就是移除它们。

(译注:而“现代”的浏览器似乎鼓励这种方式,这也很好解释原因。尾部逗号可以减少向数组的最后添加元素时,因为忘记为这最后一个元素加逗号 所造成的错误。)

var myList = ['home', , 'school', ];

在下面的例子中,数组的长度是4,元素myList[0]myList[2]缺失(译注:没被赋值,因而是undefined)。

var myList = [ , 'home', , 'school'];

再看一个例子。在这里,该数组的长度是4,元素myList[1]myList[3]被漏掉了。(但是)只有最后的那个逗号被忽略。

var myList = ['home', , 'school', , ];

理解多余的逗号(在脚本运行时会被如何处理)的含义,对于从语言层面理解JavaScript是十分重要的。但是,在你自己写代码时:显式地将缺失的元素声明为undefined,将大大提高你的代码的清晰度和可维护性

布尔字面量 (Boolean literals)

(译注:即逻辑字面量)

布尔类型有两种字面量:truefalse

不要混淆作为布尔对象的真和假与布尔类型的原始值true和false。布尔对象是原始布尔数据类型的一个包装器。参见 布尔对象。

整数 (Integers)

(译注:原文如此,没写成“整数字面量”,这里指的是整数字面量。)

整数可以用十进制(基数为10)、十六进制(基数为16)、八进制(基数为8)以及二进制(基数为2)表示。

  • 十进制整数字面量由一串数字序列组成,且没有前缀0。
  • 八进制的整数以 0(或0O、0o)开头,只能包括数字0-7。
  • 十六进制整数以0x(或0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F。
  • 二进制整数以0b(或0B)开头,只能包含数字0和1。

严格模式下,八进制整数字面量必须以0o或0O开头,而不能以0开头。

整数字面量举例:

0, 117 and -345 (十进制, 基数为10)
015, 0001 and -0o77 (八进制, 基数为8)
0x1123, 0x00111 and -0xF1A7 (十六进制, 基数为16或"hex")
0b11, 0b0011 and -0b11 (二进制, 基数为2)

浮点数字面量 (Floating-point literals)

浮点数字面值可以有以下的组成部分:

  • 一个十进制整数,可以带正负号(即前缀“+”或“ - ”),
  • 小数点(“.”),
  • 小数部分(由一串十进制数表示),
  • 指数部分。

指数部分以“e”或“E”开头,后面跟着一个整数,可以有正负号(即前缀“+”或“-”)。浮点数字面量至少有一位数字,而且必须带小数点或者“e”(大写“E”也可)。

简言之,其语法是:

[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

例如:

3.14
-.2345789 // -0.23456789
-3.12e+12  // -3.12*10^12
.1e-23    // 0.1*10^(-23)=10^(-24)=1e-24

对象字面量 (Object literals)

对象字面值是封闭在花括号对({})中的一个对象的零个或多个"属性名-值"对的(元素)列表。你不能在一条语句的开头就使用对象字面值,这将导致错误或产生超出预料的行为, 因为此时左花括号({)会被认为是一个语句块的起始符号。(译者:这 里需要对语句statement、块block等基本名词的解释)

以下是一个对象字面值的例子。对象car的第一个元素(译注:即一个属性/值对)定义了属性myCar;第二个元素,属性getCar,引用了一个函数(即CarTypes("Honda"));第三个元素,属性special,使用了一个已有的变量(即Sales)。

var Sales = "Toyota";
​
function CarTypes(name) {
  return (name === "Honda") ?
    name :
    "Sorry, we don't sell " + name + "." ;
}
​
var car = { myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales };
​
console.log(car.myCar);   // Saturn
console.log(car.getCar);  // Honda
console.log(car.special); // Toyota

更进一步的,你可以使用数字或字符串字面值作为属性的名字,或者在另一个字面值内嵌套上一个字面值。如下的示例中使用了这些可选项。

var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
​
console.log(car.manyCars.b); // Jeep
console.log(car[7]); // Mazda

对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的javascript标识符,它必须用""包裹。属性的名字不合法,那么便不能用.访问属性值,而是通过类数组标记("[]")访问和赋值。

var unusualPropertyNames = {
  "": "An empty string",
  "!": "Bang!"
}
console.log(unusualPropertyNames."");   // 语法错误: Unexpected string
console.log(unusualPropertyNames[""]);  // An empty string
console.log(unusualPropertyNames.!);    // 语法错误: Unexpected token !
console.log(unusualPropertyNames["!"]); // Bang!

增强的对象字面量 (Enhanced Object literals)

在ES2015,对象字面值扩展支持在创建时设置原型,简写了 foo: foo 形式的属性赋值,方法定义,支持父方法调用,以及使用表达式动态计算属性名。总之,这些也使对象字面值和类声明更加紧密地联系起来,让基于对象的设计从这些便利中更加受益。

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand for ‘handler: handler’
    handler,
    // Methods
    toString() {
     // Super calls
     return "d " + super.toString();
    },
    // Computed (dynamic) property names
    [ 'prop_' + (() => 42)() ]: 42
};

请注意:

var foo = {a: "alpha", 2: "two"};
console.log(foo.a);    // alpha
console.log(foo[2]);   // two
//console.log(foo.2);  // SyntaxError: missing ) after argument list
//console.log(foo[a]); // ReferenceError: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two

RegExp 字面值

一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式。下面是一个正则表达式文字的一个例子。

var re = /ab+c/;

字符串字面量 (String literals)

字符串字面量是由双引号(")对或单引号(')括起来的零个或多个字符。字符串被限定在同种引号之间;也即,必须是成对单引号或成对双引号。下面的例子都是字符串字面值:

"foo"
'bar'
"1234"
"one line \n another line"
"John's cat"

你可以在字符串字面值上使用字符串对象的所有方法——JavaScript会自动将字符串字面值转换为一个临时字符串对象,调用该方法,然后废弃掉那个临时的字符串对象。你也能用对字符串字面值使用类似String.length的属性:

console.log("John's cat".length)
// 将打印字符串中的字符个数(包括空格)
// 结果为:10

在ES2015中,还提供了一种模板字面量(template literals),模板字符串提供了一些语法糖来帮你构造字符串。这与Perl、Python还有其他语言中的字符串插值(string interpolation)的特性非常相似。除此之外,你可以在通过模板字符串前添加一个tag来自定义模板字符串的解析过程,这可以用来防止注入攻击,或者用来建立基于字符串的高级数据抽象。

// Basic literal string creation
`In JavaScript '\n' is a line-feed.`
​
// Multiline strings
`In JavaScript this is
 not legal.`
​
// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
​
// Construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);

除非有特别需要使用字符串对象,否则,你应当始终使用字符串字面值。要查看字符串对象的有关细节,请参见字符串对象。

在字符串中使用的特殊字符

作为一般字符的扩展,你可以在字符串中使用特殊字符,如下例所示。

"one line \n another line"

Copy to Clipboard

以下表格列举了你能在JavaScript的字符串中使用的特殊字符。

字符意思
\0Null字节
\b退格符
\f换页符
\n换行符
\r回车符
\tTab (制表符)
\v垂直制表符
'单引号
"双引号
\反斜杠字符(\)
\XXX由从0到377最多三位八进制数XXX表示的 Latin-1 字符。例如,\251是版权符号的八进制序列。
\xXX由从00和FF的两位十六进制数字XX表示的Latin-1字符。例如,\ xA9是版权符号的十六进制序列。
\uXXXX由四位十六进制数字XXXX表示的Unicode字符。例如,\ u00A9是版权符号的Unicode序列。见Unicode escape sequences (Unicode 转义字符).
\u{XXXXX}Unicode代码点 (code point) 转义字符。例如,\u{2F804} 相当于Unicode转义字符 \uD87E\uDC04的简写。

译注:严格模式下,不能使用八进制转义字符。

转义字符

对于那些未出现在表2.1中的字符,其所带的前导反斜线''将被忽略。但是,这一用法已被废弃,应当避免使用。

通过在引号前加上反斜线'',可以在字符串中插入引号,这就是引号转义。例如:

var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
console.log(quote);

代码的运行结果为:

He read "The Cremation of Sam McGee" by R.W. Service.

要在字符串中插入''字面值,必须转义反斜线。例如,要把文件路径 c:\temp 赋值给一个字符串,可以采用如下方式:

var home = "c:\\temp";

也可以在换行之前加上反斜线以转义换行(译注:实际上就是一条语句拆成多行书写),这样反斜线和换行都不会出现在字符串的值中。

var str = "this string \
is broken \
across multiple\
lines."
console.log(str);   // this string is broken across multiplelines.

Javascript没有“heredoc”语法,但可以用行末的换行符转义和转义的换行来近似实现

var poem =
"Roses are red,\n\
Violets are blue.\n\
Sugar is sweet,\n\
and so is foo."

ECMAScript 2015 增加了一种新的字面量,叫做模板字面量 template literals。它包含一些新特征,包括了多行字符串!

var poem =
`Roses are red,
Violets are blue.
Sugar is sweet,
and so is foo.`

© 版权声明
THE END
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容