JavaScript学习笔记(一)

文章目录

    • 第1章:什么是JavaScript
      • 1. JavaScript实现
      • 2. ECMAScript
      • 3. DOM
      • 4. BOM
    • 第2章:HTML中的JavaScript
      • 1.\元素
      • 2.行内代码于外部文件
      • 3.文档模式
      • 4.\元素
    • 第3章 语言基础
      • 1.语法
      • 2.关键字与保留字
      • 3.变量
      • 4.数据类型
      • 5.操作符
      • 6.语句
      • 7.函数

第1章:什么是JavaScript

1. JavaScript实现

  1. 核心(ECMAScript):由ECMA-262定义并提供核心功能
  2. 文档对象模型(DOM):提供与网页内容交互的方法和接口
  3. 浏览器对象模型(BOM):提供与浏览器交互的方法和接口

2. ECMAScript

  1. ECMA-262定义的一种语言基准,在此基础上构建更稳健的脚本语言
  2. Web浏览器只是ECMAScript实现的一种宿主环境(host environment),Node.js是服务器端JavaScript平台,也是一种宿主环境。
  3. ECMA-262定义了:语法,类型,语句,关键字,保留字,操作符,全局对象

3. DOM

  1. 文档对象模型,Document Object Model,是API。
  2. DOM将页面抽象为一组分层节点,创建表示文档的树。

4. BOM

  1. 浏览器对象模型,也是API。
  2. 通常把任何特定于浏览器的扩展都归在BOM的范畴内。
  3. 没有标准,HTML5之后,BOM实现细节日趋一致。

第2章:HTML中的JavaScript

1.标签中再包含其他JavaScript代码。如果两者都提供的话,浏览器只会下载并执行脚本文件,忽略行内代码。
  • 建议将JavaScript引用放在元素中的页面内容后面,因为页面在浏览器解析到的起始标签时开始渲染,放在前面会导致页面渲染的明显延迟。
  • 推迟执行脚本:defer属性。该属性只对外部脚本文件有效。HTML5规范要求脚本应该按照出现顺序执行,所以第一个defer的脚本会在第二个defer的脚本之前执行。但实际上不一定,so最好只包含一个defer脚本。因为有的浏览器会忽略这个属性,所以还是把要推迟执行的脚本放在页面底部比较好。
  • 异步执行脚本:async属性。也只适用于外部脚本。但是标记为async的脚本不能保证按照出现次序执行,因为它们之间没有依赖关系。
  • 动态加在脚本:使用DOM API,通过向DOM中动态添加script元素加载指定的脚本。只要创建一个script元素并将其添加到DOM即可。这种方式以异步加载,相当于添加了async属性,但是不是所有的浏览器都支持这个属性,所以可以将其设置为同步加载。
    let script =document.createElemnet('script')`` script.src='gibberish.js' script.async = false; // 设置为同步加载 document.head.apendChild(script)
    这种方式获取的资源对浏览器的预加载器不可见,严重影响性能。要想让预加载器知道动态请求文件的存在,可以在文档头部显式声明它们:
  • XHTML中的变化:XHTML中使用JavaScript必须指定type属性且值为text/javascript。XHTML模式会在页面的MIME类型被指定为"application/xhtml+xml"时触发。
  • 2.行内代码于外部文件

    1. 推荐使用外部文件,理由如下
      • 可维护性。用一个目录保存所有的js文件,更容易维护,开发者可以独立于使用它们的HTML页面来编辑代码。
      • 缓存。浏览器会根据特定的设置缓存所有外部链接的js文件,所以如果两个页面都用到同一个文件,只需要下载一次,从而使页面加载更快。
      • 适应未来。包含外部js文件的语法在HTML和XHTML中一样。

    3.文档模式

    1. 使用doctype切换文档模式
      • 混杂模式(quirks mode):省略文档开头的doctype声明
      • 标准模式(standards mode)
      • 准标准模式(almost standards mode)

    4.

    1. 用于给不支持js的浏览器提供替代内容。
    2. 如今的浏览器已经100%支持js
    3. 对于禁用js的浏览器来说,这个元素有用

    第3章 语言基础

    1.语法

    1. 区分大小写
    2. 标识符:
      • 可以由一个或多个字符组成,第一个字符必须是一个字母,下划线(_)或美元符号($),剩下的其他字符可以是字母、下划线、美元符号或数字。
      • 按照惯例使用驼峰大小写形式,不是强制性的。
      • 关键字、保留字、true、false和null不能作为标识符。
    3. 注释:
      • 单行注释:// 注释内容
      • 多行注释:/* 注释内容 */
    4. 严格模式(strict mode):
      • "use strict"启用严格模式,可以对整个脚本启用,也可以对指定函数启用,这是一个预处理指令。
      • 所有现代浏览器都支持严格模式。
    5. 语句
      • 以分号结尾,没有分号意味着由解析器确定语句在哪结尾,也有效,但不推荐。
      • 多条语句可以合并到一个代码块中,代码块由 ‘{’ 标识开始,'}'标识结束。
      • if之类的控制语句只在执行多条语句时要求必须有代码块,但推荐加代码块,减少出错。

    2.关键字与保留字

    1. 关键字
      JavaScript学习笔记(一)_第1张图片
    2. 保留字
      JavaScript学习笔记(一)_第2张图片

    3.变量

    1. var关键字
      • 可以保存任何类型的值,没有初始化的情况下保存一个特殊值undefined
      • 可以同时定义变量并设置它的值
      • 可以改变保存的值,也可以改变值的类型
      • var声明作用域:在函数内部定义的变量只在函数内部有效,在函数内定义变量时省略var操作符,可以创建一个全局变量,但不推荐这么做。
      • 定义多个变量可以在一条语句中用逗号分隔
      • var声明提升:var声明的变量会自动提升到函数作用域顶部
      • 反复使用var声明同一个变量也没有问题
    2. let声明
      • let声明的范围是块作用域,而var声明的范围是函数作用域,块作用域是函数作用域的子集
      • let不允许同一个块作用域中出现冗余声明
      • 暂时性死区:let与var的一个重要区别是,let声明的变量不会在作用域中被提升。let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面才声明的变量都会抛出ReferenceError。
      • 全局声明:let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量会)。
      • 条件声明:不能使用let进行条件式声明(条件声明是一种反模式)
      • for循环中的let声明:使用let声明for循环中的迭代变量,则变量的作用域仅限于for循环块内部,不会出现渗透到循环体外部的情况。
    3. const声明
      • 声明变量时必须同时初始化变量。
      • 尝试修改const声明的变量会导致运行时错误。不能声明迭代变量。
      • 不允许重复声明。
      • 声明的作用域也是块。
      • const声明的限制只适用于它指向的变量的引用,可以修改这个对象内部的属性。
    4. 声明风格及最佳实践
      • 不使用var
      • const优先,let次之

    4.数据类型

    1. 简单数据类型:Undefined、Null、Boolean、Number、String和Symbol。
    2. 复杂数据类型:Object
    3. typeof操作符:用来确定变量的数据类型,只是一个操作符,不是函数,不需要参数(当然也可以使用参数)
    4. Undefined类型:
      • 只有一个值,就是特殊值undefined。
      • 当var和let声明了变量但是没有初始化时,默认给变量赋值undefined。
      • 不必显式地将变量值设置为undefined。
    5. 注意:无论是声明后未赋值还是未声明,typeof返回的都是"undefined",逻辑上是对的。建议在声明变量的同时初始化,这样当typeof返回"undefined"的时候就知道是未声明而不是声明了但未初始化。
    6. Null类型:
      • 只有一个值,特殊值null。表示一个空对象指针。
      • 当一个变量要保存对象而又没有对象可保存时,将变量显式的赋值为null。
    7. 注意:用比较操作符(==)比较null和undefined始终返回true。
    8. Boolean类型:
      • 有两个字面值:true,false
      • Boolean()转型函数:将其他类型的值转换为布尔值
        JavaScript学习笔记(一)_第3张图片
    9. Number类型
      • 八进制:第一位必须为0,严格模式下无效。应该使用前缀0o
      • 十六进制:前缀0x。
      • 浮点值:
        • 数值中必须包含小数点,小数点后面必须至少有一个数字。小数点前不是必须有整数,但推荐加上。
        • 科学计数法表示:一个数值(整数或浮点数)后跟一个大写或小写的字母e,再加上一个要乘的10的多少次幂。例:3.125e7,3e-17。
      • 值的范围:
        • 最小值:Number.MIN_VALUE,大概是5e-324。
        • 最大值:Number.MAX_VALUE,大概是1.797 693 134 862 315 7e+308。
        • 任何无法表示的负数:-Infinity(负无穷大),Number.NEGATIVE_INFINITY
        • 任何无法表示的正数:Infinity(正无穷大),Number.POSITIVE_INFINITY
        • 如果计算返回正 Infinity 或负 Infinity,则该值将不能再进一步用于任何计算。
        • isFinite()函数:用于确定一个数是不是有限大。
      • NaN
        • 不是数值,not a number。用于表示本来要返回数值的操作失败了。
        • 任何涉及NaN的操作始终返回NaN。
        • NaN不等于包括NaN在内的任何值。
        • isNaN()函数:接受一个参数,判断该参数是否“不是数值”。
      • 数值转换:有三个函数可以将非数值转换为数值
        • Number():可用于任何数据类型。
        • parseInt():主要用于将字符串转换为数值。可以接收两个参数,第二个参数表示底数(进制数)。建议给第二个参数。
        • parseFloat():主要用于将字符串转换为数值。
    10. String类型
      • 0个或多个16位Unicode字符序列
      • 可以用双引号(")、单引号(')或反引号(`)标示
      • 字符串的长度通过length属性过去,例:text.length
      • toString()方法:把一个值转换为字符串。对数值调用这个方法时,可以接受一个底数参数。null和undefined值没有这个方法。
      • String():当不确定一个值是不是null或undefined时用。
      • 用加号操作符给一个值加上一个空字符串""也可以将其转换为字符串。
      • 字符串差值:通过在${}中使用一个JavaScript表达式实现。嵌套的模板字符串无须转义,在插值表达式中可以调用函数和方法。模板也可以插入自己之前的值。
      • 模板字面量标签函数(没看懂!,到底什么是标签函数啊?)第67页
      • 原始字符串:String.raw标签函数,也可以通过标签函数的raw属性获得每个字符串的原始内容
    11. Symbol类型:(这里面蛮多不懂的地方,用到的时候再回来看)
      • 符号类型,确保对象属性使用唯一标识符。
      • 基本用法:
        • 使用Symbol()函数初始化。let sym = Symbol();
        • 调用Symbol()函数时,可以传入一个字符串参数作为对符号的描述,let othersym = Symbol(‘foo’);这个字符串参数可以用来调试代码,但是与符号定义或标识完全无关。
        • 符号没有字面量语法
        • Symbol()函数不能与new关键字一起作为构造函数使用
          let mySymbol = new Symbol(); // TypeError: Symbol is not a constructor
      • 使用全局符号注册表
        • 使用Symbol.for()方法:let fooGlobalSymbol = Symbol.for('foo');
        • 在全局注册表中定义的符号跟使用Symbol()定义的符号并不等同。
        • 全局注册表中的符号必须使用字符串来创建,因此作为参数传给Symbol.for()的任何值都会被转换为字符串。注册表中使用的键同时也会被用作符号描述。
          let emptyGlobalSymbol = Symbol.for();
          console.log(emptyGlobalSymbol); // Symbol(undefined)
        • 使用Symbol.keyFor()来查询全局注册表,返回该全局符号对应的字符串键。
          // 创建全局符号
          let s = Symbol.for('foo');
          console.log(Symbol.keyFor(s)); // foo
      • 使用符号作为属性(从这里开始往下的符号部分的内容没看懂,用到的时候再回来看)
      • 常用内置符号
    12. Object类型:
      • 对象实际就是一组数据和功能的集合。通过new操作符后跟对象类型的名称来创建(同Java)。例:let o = new Object();
      • 如果构造函数没有参数,可以省略括号,合法但不推荐。
      • 每个Object实例都有以下属性和方法:
        • constructor:用于创建当前对象的函数。
        • hasOwnProperty(propertyName):用于判断当前对象实例上是否存在给定的属性。
        • isPrototypeOf(Object):用于判断当前对象是否为另一个对象的原型。
        • propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用for-in语句枚举。
        • toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境。
        • toString():返回对象的字符串表示。
        • valueOf():返回对象对应的字符串、数值或布尔值表示。
      • Object是所有对象的基类,所以任何对象都有这些属性和方法。

    5.操作符

    1. 一元操作符
      • 递增/递减操作符
        • 同C语言
        • 可以作用于任何值,整数,字符串,布尔值,浮点值甚至对象都可以。
      • 一元加和减
        • 同高中数学
        • 应用到非数值时会执行于使用Number()转型函数一样的类型转换。
        • 一元加(+)放到变量前头,对数值没有任何影响。
        • 一元减(-)放在变量前头,主要用于把数值变成负值。
        • 主要用于基本算数,也可用于数据类型转换。
    2. 位操作符
      • 在应用位操作时,在后台64位数值会转换为32位数值,然后执行位操作,最后再把结果从32位转换为64位存储起来。副作用是:特殊值NaN和Infinity在位操作中都会被当成0处理。
      • 应用到非数值,首先会使用Number()函数将该值转换为数值。
      • 按位非(~):返回数值的补数。
      • 按位与(&)
      • 按位或(|)
      • 按位异或(^)
      • 左移(<<):保留符号。
      • 有符号右移(>>):保留符号
      • 无符号右移(>>>)
    3. 布尔操作符
      • 逻辑非(!)
        • 返回值一定是布尔值。
        • 首先将操作符转换为布尔值,然后对其取反。
        • 同时使用两个叹号(!!),相当于调用了转型函数Boolean()。
        • 规则:
          如果操作数是对象,则返回false。
          如果操作数是空字符串,则返回true。
          如果操作数是非空字符串,则返回false。
          如果操作数是数值0,则返回true。
          如果操作数是非0 数值(包括Infinity),则返回false。
          如果操作数是null,则返回true。
          如果操作数是NaN,则返回true。
          如果操作数是undefined,则返回true。
      • 逻辑与(&&)
        • 如果有操作数不是布尔值,返回值不一定是布尔值。
        • 规则:
          如果第一个操作数是对象,则返回第二个操作数。
          如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象。
          如果两个操作数都是对象,则返回第二个操作数。
          如果有一个操作数是null,则返回null。
          如果有一个操作数是NaN,则返回NaN。
          如果有一个操作数是undefined,则返回NaN。
      • 逻辑或(||)
        • 如果有操作数不是布尔值,返回值不一定是布尔值。
        • 规则
          如果第一个操作数是对象,则返回第一个操作数。
          如果第一个操作数求值为false,则返回第二个操作数。
          如果两个操作数都是对象,则返回第一个操作数。
          如果两个操作数都是null,则返回null。
          如果两个操作数都是NaN,则返回NaN。
          如果两个操作数都是undefined,则返回undefined。
    4. 乘性操作符:乘法、除法和取模。作用同Java,C语言。当操作数不是数值时,会在后台使用Number()转型函数转换为数值。
      • 乘法(*)
        • 操作符都是数值,执行常规乘法运算。如果不能表示乘积,则返回Infinity或-Infinity。
        • 如果有任一操作数是NaN,则返回NaN。
        • 如果是Infinity乘以0,则返回NaN。
        • 如果是Infinity乘以非0的有限数值,则根据第二个操作数的符号返回Infinity或-Infinity。
        • 如果是Infinity乘以Infinity,则返回Infinity。
        • 如果不是数值的操作数,则先在后台用Number()将其转换为数值,然后再应用上述规则。
      • 除法(/)
        • 操作符都是数值,执行常规除法运算。如果不能表示商,则返回Infinity或-Infinity。
        • 如果有任一操作数是NaN,则返回NaN。
        • 如果是Infinity除以Infinity,则返回NaN。
        • 如果是0除以0,则返回NaN。
        • 如果是非0的有限值除以0,则根据第一个操作数的符号返回Infinity或-Infinity。
        • 如果是Infinity除以任何值,则根据第二个操作数的符号返回Infinity或-Infinity。
        • 如果不是数值的操作数,则先在后台用Number()将其转换为数值,然后再应用上述规则。
      • 取模(%)
        • 如果操作数是数值,则执行常规除法运算,返回余数。
        • 如果被除数是无限值,除数是有限值,则返回NaN。
        • 如果被除数是有限值,除数是0,则返回NaN。
        • 如果是Infinity除以Infinity,则返回NaN。
        • 如果被除数是有限值,除数是无限值,则返回被除数。
        • 如果被除数是0,除数不是0,则返回0。
        • 如果不是数值的操作数,则先在后台用Number()将其转换为数值,然后再应用上述规则。
    5. 指数操作符:**
      • 等价于Math.pow()
      • 指数操作符也有自己的指数赋值操作符**=
    6. 加性操作符
      • 加法操作符(+)
      • 减法操作符(-)
    7. 关系操作符:都返回布尔值
      • 小于(<)
      • 大于(>)
      • 小于等于(<=)
      • 大于等于(>=)
    8. 相等操作符
      • 等于(==)和不等于(!=):先进行类型转换,再确定操作数是否相等。
      • 全等(===)和不全等(!==):比较相等时不转换操作数。
    9. 条件操作符:同Java中的三目运算符
      • variable = boolean_expression ? true_value : false_value;
    10. 赋值操作符
      • 简单赋值(=)
      • 复合赋值:使用乘性、加性或位操作符后跟等于号(=)表示
    11. 逗号操作符(,):可以用来在一条语句中执行多个操作

    6.语句

    1. if语句:
      • if(condition) statement1 else statement2;
      • if(condition1) statement1 else if(condition2) statement2 else statement3;
    2. do-while语句
    3. while语句
    4. for语句:建议使用let声明迭代器变量
    5. for-in语句
      • 建议使用const声明变量
      • for(const property in expression) statement;
      • ECMAScript中对象的属性是无序的。因此for-in语句不能保证返回对象属性的顺序。
    6. for-of语句
      • 一种严格的迭代语句,用于遍历可迭代对象的元素
      • for(property of expression) statement;
      • 建议使用const声明迭代变量
      • 会按照可迭代对象的next()方法产生值的顺序迭代元素
    7. 标签语句
      • 用于给语句加标签,语法:label: statement
      • 标签可以通过break或continue语句引用。(不太明白)
    8. break和continue语句
      • break:立即退出循环,强制执行循环后的下一条语句。
      • continue:立即退出循环,再次从循环顶部开始执行。
      • 可以与标签语句一起使用,返回代码中特定的位置。(明白了)
    9. with语句
      • 用途是将作用域设置为特定的对象,语法:with(expression) statement;
      • 主要场景是针对一个对象反复操作
      • 严格模式不允许使用with语句,会抛出错误。
      • 影响性能难调试,不推荐使用!
    10. switch语句(同Java)

    7.函数

    1. 使用function关键字声明,后跟一组参数,然后是函数体。
      function functionName(arg0,arg1,…,argN){
      statements
      }
    2. 使用函数名调用函数
    3. 不需要指定是否返回值,任何函数在任何时间都可以使用return语句来返回函数的值
    4. 不指定返回值的函数实际上会返回特殊值undefined

    你可能感兴趣的:(学习笔记,javascript,node.js)