前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >javascript入门到进阶 - javascript基础

javascript入门到进阶 - javascript基础

作者头像
公众号---人生代码
发布2020-07-14 11:05:06
6620
发布2020-07-14 11:05:06
举报
文章被收录于专栏:人生代码人生代码

文章参考自MDN:

代码语言:javascript
复制
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#%E5%9F%BA%E7%A1%80

JavaScript 是区分大小写的,并使用 Unicode 字符集。举个例子,可以将单词 Früh (在德语中意思是“早”)用作变量名。

代码语言:javascript
复制
var Früh = "Ken";
var früh = "kennana";
以上是两个不同的变量

「注释」

代码语言:javascript
复制
// 单行注释

/* 这是一个更长的,
   多行注释
*/

/* 然而, 你不能, /* 嵌套注释 */ 语法错误 */

「声明」JavaScript有三种声明方式。

var 声明一个变量,可选初始化一个值。let 声明一个块作用域的局部变量,可选初始化一个值。const 声明一个块作用域的只读常量。

代码语言:javascript
复制
var name = "Ken";
let sex = "男";
const age = 20;

「变量节」在应用程序中,使用变量来作为值的符号名。变量的名字又叫做标识符,其需要遵守一定的规则。

一个 JavaScript 标识符必须以字母、下划线(_)或者美元符号($)开头;后续的字符也可以是数字(0-9)。因为 JavaScript 语言是区分大小写的,所以字母可以是从“A”到“Z”的大写字母和从“a”到“z”的小写字母。

你可以使用大部分 ISO 8859-1 或 Unicode 编码的字符作标识符,例如 å 和 ü(详情可查看这篇博客文章)。你也可以使用 Unicode 转义字符 作标识符。

合法的标识符示例:Number_hits,temp99,$credit 和 _name。

代码语言:javascript
复制
var Number_hits;
let temp99
const $credit;
let _name;

「声明变量」你可以用以下三种方式声明变量:

使用关键词 var 。例如 var x = 42。这个语法可以用来声明「局部变量」「全局变量」「直接赋值」。例如x = 42。在函数外使用这种形式赋值,会产生一个「全局变量」。在「严格模式」下会产生错误。因此你不应该使用这种方式来生命变量。使用「关键词 let」 。例如 let y = 13。这个语法可以用来声明块作用域的局部变量。參考下方变量的作用域(Variable scope) 。

「变量求值」用 var 或 let 语句声明的变量,如果没有赋初始值,则其值为 undefined 。

如果访问一个未声明的变量会导致抛出一个引用错误(ReferenceError)异常:

你可以使用 undefined 来判断一个变量是否已赋值。在以下的代码中,变量input未被赋值,因此 if 条件语句的求值结果是 true 。

undefined 值在布尔类型环境中会被当作 false 。例如,下面的代码将会执行函数 myFunction,因为数组 myArray 中的元素未被赋值:

数值类型环境中 undefined 值会被转换为 NaN。

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

补充一点就是当值为undefined是也是0

当为空数组的时候

当为空对象时

其他情况

「变量的作用域」「在函数之外声明的变量,叫做全局变量」「因为它可被当前文档中的任何其他代码所访问」「在函数内部声明的变量,叫做局部变量,因为它只能在当前函数的内部访问。」

ECMAScript 6 之前的 JavaScript 没有 语句块 作用域;相反,语句块中声明的变量将成为语句块所在函数(或全局作用域)的局部变量。例如,如下的代码将在控制台输出 5,因为 x 的作用域是声明了 x 的那个函数(或全局范围),而不是 if 语句块。

如果使用 ECMAScript 6 中的 let 声明,上述行为将发生变化。

「变量提升」JavaScript 变量的另一个不同寻常的地方是,你可以先使用变量稍后再声明变量而不会引发异常。这一概念称为变量提升;JavaScript 变量感觉上是被“提升”或移到了函数或语句的最前面。但是,提升后的变量将返回 undefined 值。因此在使用或引用某个变量之后进行声明和初始化操作,这个被提升的变量仍将返回 undefined 值。

上面的例子,也可写作:

代码语言:javascript
复制
/**
 * 例子1
 */


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


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

由于存在变量提升,一个函数中所有的var语句应尽可能地放在接近函数顶部的地方。这个习惯将大大提升代码的清晰度。

在 ECMAScript 6 中,「let(const)将不会提升变量到代码块的顶部」。因此,「在变量声明之前引用这个变量,将抛出引用错误」(ReferenceError)。「这个变量将从代码块一开始的时候就处在一个“暂时性死区”,直到这个变量被声明为止」

「函数提升」对于函数来说,「只有函数声明会被提升到顶部」「而函数表达式不会被提升。」

「全局变量」实际上,「全局变量是全局对象的属性」。在网页中,(译注:缺省的)「全局对象是 window」 ,所以你可以用形如 「window.variable」 的语法来设置和访问全局变量。

因此,你可以「通过指定 window 或 frame 的名字」,在「当前 window 或 frame 访问另一个 window 或 frame 中声明的变量」。例如,在文档里声明一个叫 phoneNumber 的变量,那么你就可以在子框架里使用 parent.phoneNumber 的方式来引用它。「常量(Constants)」你可以用关键字 const 创建一个只读的常量。常量标识符的命名规则和变量相同:必须以字母、下划线(_)或美元符号($)开头并可以包含有字母、数字或下划线。

常量不可以通过重新赋值改变其值,也不可以在代码运行时重新声明。它必须被初始化为某个值。

常量的作用域规则与 let 块级作用域变量相同。若省略const关键字,则该标识符将被视为变量。

在同一作用域中,不能使用与变量名或函数名相同的名字来命名常量。例如:

代码语言:javascript
复制
// 这会造成错误
function f() {};
const f = 5;

// 这也会造成错误
function f() {
  const g = 5;
  var g;

  //语句
}

然而,对象属性被赋值为常量是不受保护的,所以下面的语句执行时不会产生错误。

代码语言:javascript
复制
const MY_OBJECT = {"key": "value"};
MY_OBJECT.key = "otherValue";

同样的,数组的被定义为常量也是不受保护的,所以下面的语句执行时也不会产生错误。

「数据结构和类型节 数据类型节 最新的 ECMAScript 标准定义了7种数据类型」

六种基本数据类型:

  • 「布尔值(Boolean)」,有2个值分别是:true 和 false.「null」 , 一个表明 null 值的特殊关键字。JavaScript 是大小写敏感的,因此 null 与 Null、NULL或变体完全不同。
  • 「undefined」 ,和 null 一样是一个特殊的关键字,undefined 表示变量未定义时的属性。
  • 「数字(Number)」,整数或浮点数,例如:42 或者 3.14159。
  • 「字符串(String)」,字符串是一串表示文本值的字符序列,例如:"Howdy" 。
  • 「代表(Symbol)」 ( 在 ECMAScript 6 中新添加的类型).。一种实例是「唯一且不可改变的数据类型」。以及「对象(Object)」。虽然这些数据类型相对来说比较少,但是通过他们你可以在程序中开发有用的功能。**对象(Objects)和函数(functions)**是这门语言的另外两个基本元素。你可以把对象当作存放值的一个命名容器,然后将函数当作你的程序能够执行的步骤。

「数据类型的转换节」JavaScript是一种「动态类型语言」(dynamically typed language)。这意味着你在声明变量时可以不必指定数据类型,而数据类型会在代码执行时会根据需要自动转换。因此,你可以按照如下方式来定义变量:

代码语言:javascript
复制
var answer = 42;

然后,你还可以给同一个变量赋予一个字符串值,例如:

代码语言:javascript
复制
answer = "Thanks for all the fish...";

因为 JavaScript 是动态类型的,这种赋值方式并不会提示出错。

在包含的数字和字符串的表达式中使用加法运算符(+),JavaScript 会把数字转换成字符串。例如,观察以下语句:

代码语言:javascript
复制
x = "The answer is " + 42 // "The answer is 42"
y = 42 + " is the answer" // "42 is the answer"

在涉及其它运算符(译注:如下面的减号'-')时,JavaScript语言不会把数字变为字符串。例如(译注:第一例是数学运算,第二例是字符串运算):

代码语言:javascript
复制
"37" - 7 // 30
"37" + 7 // "377"

在这里插入图片描述

  • 「字符串转换为数字节」有一些方法可以将内存中表示一个数字的字符串转换为对应的数字。
  • 「parseInt()和parseFloat()」参见:parseInt()和parseFloat()的相关页面。

parseInt 方法只能返回整数,所以使用它会丢失小数部分。另外,调用 parseInt 时最好总是带上进制(radix) 参数,这个参数用于指定使用哪一种进制。

将字符串转换为数字的另一种方法是使用一元加法运算符。

代码语言:javascript
复制
"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2   
// 注意:加入括号为清楚起见,不是必需的。
  • 「字面量 (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。

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

数组字面值同时也是数组对象。有关数组对象的详情请参见数组对象一文。

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

代码语言:javascript
复制
var fish = ["Lion", , "Angel"];

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

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

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

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

代码语言:javascript
复制
var myList = ['home', , 'school', ];

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

代码语言:javascript
复制
var myList = [ , 'home', , 'school'];

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

代码语言:javascript
复制
var myList = ['home', , 'school', , ];

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

「布尔字面量 (Boolean literals)节」(译注:即逻辑字面量)

代码语言:javascript
复制
布尔类型有两种字面量:true和false。

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

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

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

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

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

整数字面量举例:

代码语言:javascript
复制
    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”也可)。

简言之,其语法是:

代码语言:javascript
复制
    [(+|-)][digits][.digits][(E|e)[(+|-)]digits]
    例如:
    
    3.14      
    -.2345789 // -0.23456789
    -3.12e+12  // -3.12*1012
    .1e-23    // 0.1*10-23=10-24=1e-24

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

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

代码语言:javascript
复制
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

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

代码语言:javascript
复制
    var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
    
    console.log(car.manyCars.b); // Jeep
    console.log(car[7]); // Mazda

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

代码语言: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 形式的属性赋值,方法定义,支持父方法调用,以及使用表达式动态计算属性名。总之,这些也使对象字面值和类声明更加紧密地联系起来,让基于对象的设计从这些便利中更加受益。

代码语言:javascript
复制
    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
    };

请注意:

代码语言:javascript
复制
    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 字面值节」一个正则表达式是字符被斜线(译注:正斜杠“/”)围成的表达式。下面是一个正则表达式文字的一个例子。

代码语言:javascript
复制
    var re = /ab+c/;

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

代码语言:javascript
复制
    "foo"
    'bar'
    "1234"
    "one line \n another line"
    "John's cat"

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

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

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

代码语言:javascript
复制
> // 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);

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

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

代码语言:javascript
复制
"one line \n another line"

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

表 2.1 JavaScript 特殊字符 字符 意思「\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中的字符,其所带的前导反斜线''将被忽略。但是,这一用法已被废弃,应当避免使用。

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

代码语言:javascript
复制
    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 赋值给一个字符串,可以采用如下方式:

代码语言:javascript
复制
var home = "c:\\temp";

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

代码语言:javascript
复制
    var str = "this string \
    is broken \
    across multiple\
    lines."
    console.log(str);   // this string is broken across multiplelines.

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

代码语言:javascript
复制
    var poem = 
    "Roses are red,\n\
    Violets are blue.\n\
    Sugar is sweet,\n\
    and so is foo."

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

代码语言:javascript
复制
    var poem =
    `Roses are red,
    Violets are blue.
    Sugar is sweet,
    and so is foo.`
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章参考自MDN:
  • 六种基本数据类型:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档