【笔记】【MDN】JavaScript指南 > 语法和数据类型

【笔记】JavaScript指南 > 语法和数据类型

这篇笔记主要摘抄自MDN的JavaScript指南,主要是自己作为知识点梳理用。详细还是请看【JavaScript指南】

感谢互联网技术的发达,让这些知识变得触手可得,也感谢文档编辑以及翻译人员们。

声明

JavaScript有三种声明: var,let,const。

变量求值

用var或let声明的且未赋初值的变量,值会被设定为undefined。试图访问一个未声明的变量或者访问一个使用let声明的但未初始化的变量会导致一个ReferenceError异常被抛出。

可以使用undefined来判断变量是否已赋值。

var input;
if(input===undefined){...}else{...}

undefined值在布尔类型环境中会被当作false。数值类型环境中undefined值会被转换为NaN。

var a;
a + 2;//NaN

当对一个null变量求值时,空值null在数值类型环境中会被当做0来对待,而布尔类型环境中会被当做false。

var n = null;
typeof(n);//object
console.log(n * 3);//0

变量的作用域

ES6之前的JS没有语句块作用域,语句块中声明的变量将成为语句块所在代码段的局部变量。

if(true) {
    var x = 5;
}
console.log(x); //5
//因为x的作用域是声明了x的那个函数(或全局范围),而不是if语句块。

if(true){
    let y = 5;
}
console.log(y);//ReferenceError: y is not defined

变量声明提升(Variable hoisting)

可以引用稍后声明的变量而不会引发异常。变量感觉上是被提升到所有函数和语句之前,但提升后变量将返回undefined值。

console.log(x === undefined);//logs "true"
var x = 3;

var myvar = "my value";
(function(){
    console.log(myvar);//undefined
    var myvar = "local value";
})();

也可写作:

var x;
console.log(x === undefined);//logs "true"
x = 3;

var myvar = "my value";
(function(){
    var myvar;
    console.log(myvar);//undefined
    myvar = "local value";
})()

由于存在变量声明提升,一个函数中左右的var语句应该尽可能地放在接近函数顶部的地方,可以大大提升程序代码的清晰度。

ES6中,let与const不会提升到代码块顶部,而是出现暂时性死区,知道这个变量被声明为止。

console.log(x);// ReferenceError
let x = 3;

函数提升(Function hoisting)

只有函数声明会被提升到顶部,不包括函数表达式。

常量(Constants)

可以用关键字const创建一个只读(read-only)的常量。常量不可以通过赋值改变值,也不可以在脚本运行时重新声明,它必须被初始化为某个值。在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。如以下两种情况都会报错:

//1
function f() {};
const f = 5;

//2
function f() {
    const g = 5;
    var g;
}

然而,对象属性是不受保护的,所以可以使用如下语句来执行。

const MY_OBJECT = {"key": "value"};
MY_OBJECT.key = "otherValue";

数据结构和类型

数据类型

JavaScript语言可以识别下边七种不同类型的值:

  • 六种原型数据类型:
    • Boolean. 布尔值,true和false
    • null. 一个表明null值的特殊关键字。JS是大小写敏感的,因此null与Null、NULL或其他变量完全不同
    • undefined. 变量未定义时的属性。
    • Number. 表示数字
    • String. 表示字符串
    • Symbol(ES6中新添加的类型). 一种数据类型,它的实例是唯一且不可改变的。
  • 以及Object对象

Objects 和 functions 是本语言的其他两个基本要素。你可以将对象视为存放值的命名容器,而将函数视为你的应用程序能够执行的过程(procedures)。

数据类型的转换(Data type conversion)

JS是一种动态类型语言(Dynamically typed language)。这意味着声明变量时可以不必指定数据类型,而数据类型会在脚本执行时根据需要自动转换。

//因此,可以这样来定义变量:
var answer = 42;

//然后还可以给这个变量赋予一个字符串值,并不会报错:
answer = "Thanks for all the fish...";

//在涉及加法运算符(+)的数字和字符串表达式中,JS会把数字值转换为字符串:
x = "The answer is " + 42 // "The answer is 42"
y = 42 + " is the answer" // "42 is the answer"

//在涉及其它运算符(如减号-)时,JS语言并不会把数字变为字符串:
"37" - 7 // 30(数学运算)
"37" + 7 //377(字符串运算)

字符串转换为数字

两种方法:

  1. parseInt()和parseFloat():

    parseInt返回整数,丢掉小数部分。使用时最好带上进制参数。

  2. 使用单目加法运算符

"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2 //括号不必须

字面量(Literals)

字面量是常量,其值是固定的,而且在程序脚本运行中不可更改(如false, 3.1415)。在JS中可以使用各种字面量:

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

数组字面量(Array literals)

当使用数组字面量创建一个数组时,该数组将会以指定的值作为其元素进行初始化。若在全局脚本里用字面量创建数组,JS语言将会在每次对包含该数组字面值的表达式求值时解释该数组。在函数中使用的数组,将在每次调用函数时都会被创建一次。

数组字面值同时也是数组对象。

不必列举数组字面值中的所有元素:

var fish = ["Lion", , "Angel"];
console.log(fish.length); // 3

//如果在元素列表尾部添加括号,它将被忽略
var animals = ["cat", "dog",];
console.log(animals.length); // 2

写代码时,显示地将缺失的元素声明为undefined,将大大提高你的代码的清晰度和可维护性。

布尔字面量(Boolean literals)

(逻辑字面量)

布尔类型有两种字面量:true和false。

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

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

组成部分:

  • 一个十进制整数,可带正负号。
  • 小数点
  • 小数部分
  • 指数部分(e/E)
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]

整数(Intergers)

整可以用十进制、十六进制、八进制以及二进制表示。

  • 十进制没有前缀0
  • 八进制以0(0o, 0O开头),只包括数字0-7
  • 十六进制0x(或0X)开头,可以包含数字(0-9)和字母 a~f 或 A~F
  • 二进制以0b(0B开头),只包含0和1

对象字面量(Object literals)

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

对象属性名字可以是任意字符串,包括空串。如果对象属性名字不是合法的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分配,定义方法,加工父函数(super calls),计算属性名(动态)。总之,这些也带来了对象字面值和类声明紧密联系起来,让基于对象的设计得益于一些同样的便利。

var obj = {
    // __proto__
    __proto__: theProtoObj,
    // Shorthand forhandler: 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);  // Error: missing ) after argument list
//console.log(foo[a]); // Error: a is not defined
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two

RegExp literals

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

字符串字面量(String literals)

字符串字面量是由双引号(”)对或单引号(’)括起来的零个或多个字符。

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

在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);

除非有特别需要使用字符串对象,否则,你应当始终使用字符串字面值。

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

Symbol meaning
\0 Null字节
\b 退格符
\f 换页符
\n 换行符
\r 回车符
\t Tab (制表符)
\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."

猜你喜欢

转载自blog.csdn.net/sinat_22014829/article/details/75090196