XuLizhao 's Notes

时光,漫步


  • 首页

  • 技术

  • 文档

  • 关于

  • 搜索
close

JavaScript入门

时间: 2018-10-24   |   分类: Tech     |   阅读: 2877 字 ~6分钟

现在通常所说的JavaScript是制定于2009年的ES5,而经常被提及的ES6/ES2015则泛指5.1之后发布的新一代JavaScript标准。

JavaScript基础

基本语法

语句

  • 语句(statement)是为了完成某任务进行的操作
  • 表达式(expression)是为了得到返回值的计算式, 表达式不需要分号结尾.

变量

  • 变量名区分大小写,只声明不赋值默认为undefined
  • 动态类型语言,变量可以改变值类型

关键字:

  • var

数据类型

  • 基本数据类型:
    • nubmer: 64位浮点数
    • string:
    • boolean: 空数组[] 和空对象{} 对应布尔true
  • 合成类型、
    • 对象(Object):
    • Array
    • function
数值
  • 特殊数值: NaN(Not a Number)
  • parseInt()
字符串
  • 转义反斜杠\ ;
  • length属性;
  • Base64转换: btoa()/atob()/encodeURIComponent() 非ASCII码转换

注:约定JavaScript字符串只使用单引号,HTML属性值使用双引号

对象

键名必须是字符串,每个键名也叫属性(property),属性可以动态创建(后绑定)

对象有两种读取成员的方法:点结构(object.key)和方括号结构(object[key])

检查对象是否包含属性:

  • in
  • hasOwnProperty: 排除继承属性
// 如果要解释为对象,最好在大括号前加上圆括号。
// 因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象
({ foo: 123 }) 

注:

  • 对象使用引用,基本类型值使用值拷贝
  • 建议不要使用with语句,改用临时变量
函数

把函数看成一个可以执行的值.

三种函数声明方式:

  • function 命令
  • 函数表达式:将匿名函数/具名函数赋值给变量(结尾要加分号;)。好处:
    • 可以在函数体内部调用自身
    • 方便调用栈除错
  • Function 构造函数:几乎不使用。最后一个参数是函数体

函数作用域: 全局变量/局部变量(即函数作用域)

参数:

  • 函数体内部可以使用arguments读取/修改参数
  • arguments很像数组,但它是一个对象
// arguments与数组转换
var args = Array.prototype.slice.call(arguments);

// 或者
var args = [];
for (var i = 0; i < arguments.length; i++) {
  args.push(arguments[i]);
}

注:

    1. JavaScript 引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。
    1. 函数执行时所在的作用域,是定义时的作用域,而不是调用时所在的作用域。
    1. 对于复合类型的函数参数,如果函数内部修改的,不是参数对象的某个属性,而是替换掉整个参数,这时不会影响到原始值。因为重新赋值后,变量会指向另一个地址。
数组
  • 本质上,数组属于一种特殊的对象。
  • 数组的特殊性体现在,它的键名是按次序排列的一组整数(0,1,2…)。 (JavaScript 语言规定,对象的键名一律为字符串,所以,数组的键名其实也是字符串)
  • length属性不过滤空位(hole)
  • 生成新数组建议直接使用数组字面量

如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object).

典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串。

// 清空数组的一个有效方法,就是将length属性设为0
var arr = [ 'a', 'b', 'c' ];
arr.length = 0;

// for...in不仅会遍历数组所有的数字键,还会遍历非数字键。不推荐使用for...in遍历数组。
// 数组的遍历可以考虑使用for循环或while循环
// 数组的forEach方法,也可以用来遍历数组


// 方式一: 数组的slice方法可以将“类似数组的对象”变成真正的数组
var arr = Array.prototype.slice.call(arrayLike);

// 方式二: 通过call()把数组的方法放到对象上面,较方式一速度更慢
Array.prototype.forEach.call(arrayLike, print);

JSON对象

约定:

  • 字符串必须使用双引号表示,不能使用单引号
  • 对象的键名必须放在双引号里面
  • 数组或对象最后一个成员的后面,不能加逗号

静态方法:

  • stringify(): 将一个值转为 JSON 字符串
    • 注:对于原始类型的字符串,转换结果会带双引号
  • parse():

运算符

  • 非相等运算符:非字符串的比较
    • 都是原始类型的值,则是先转成数值再比较
    • 对象,会转为原始类型的值,再进行比较
  • 严格相等运算符===: 比较它们是否为“同一个值”
  • 布尔运算符
    • 三元运算符:?:
var x = [2];
x > '11' // true
// 等同于 [2].valueOf().toString() > '11'
// 即 '2' > '11'

常用风格

  • 行末不要省略分号,不用添加分号仅适用下列情况:
    • for 和 while循环(do while有分号)
    • 分支: if, switch, try
    • 函数声明语句
  • 避免使用全局变量
  • 变量声明应放在代码块的头部
  • 不要使用with语句
  • 建议只使用严格相等运算符 ===

高级

待整理: Promise / async function / arrow function / module / Symbol / Class / dynamic import

'use strict'; // 开启严格模式

闭包

闭包即能够读取其他函数内部变量的函数;或者定义在一个函数内部的函数。

用处:

  • 可以读取函数内部的变量
  • 让这些变量始终保持在内存中。可使得内部变量记住上一次调用时的运算结果。
  • 是封装对象的私有属性和私有方法

“链式作用域"结构(chain scope):子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

注:外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。

// 通常情况下,只对匿名函数使用这种“立即执行的函数表达式”/IIFE (Immediately-Invoked Function Expression)
// 它的目的有两个:一是不必为函数命名,避免了污染全局变量;二是 IIFE 内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。
(function () {
  var tmp = newData;
  processData(tmp);
  storeData(tmp);
}());

// 加()会被当作表达式处理,因为 JavaScript 引擎规定,如果function关键字出现在行首,一律解释成语句。

eval

eval的本质是在当前作用域之中,注入代码。由于安全风险和不利于 JavaScript 引擎优化执行速度,所以一般不推荐使用。

通常情况下,eval最常见的场合是解析 JSON 数据的字符串,不过正确的做法应该是使用原生的JSON.parse方法。

事件

推荐使用EventTarget.addEventListener的方式增加监听函数,监听函数内部的this指向触发事件的那个元素节点.

另一种方便使用的是GlobalEventHandlers的onxxxEvent事件(缺点是只能为每个事件指定一个回调函数,并且无法指定事件触发的阶段)

事件的传播阶段:

  • 第一阶段:从window传导到目标节点,捕获阶段(capture phase)

  • 第二阶段:目标节点上触发,目标阶段(target phase)

  • 第三阶段:从目标节点传导会window对象,冒泡阶段(bubbling phase)

  • preventDefault(): 取消事件,比如表单提交

Module

  • ES Modules: import
    • mocha 需要高版本支持: Node.js v12.11+/v13.2+
  • CommonJS: required
import {add} from './add.mjs';
import assert from 'assert';

// 使用.mjs 扩展
// 或在package.json 添加 "type": "module"

Promise

使得异步流程可以写成同步流程

DOM

DOM/Document Object Model:文档对象模型,是操作网页的接口规范.

所有DOM节点对象都继承了Node接口.

常用节点类型:

  • document: 代表整个文档, window.document属性就指向这个对象.
  • element: 各种网页标签/元素节点.
  • attr: 网页元素的属性/键值对 name-value

浏览器模型

XHR/AJAX

XMLHttpRequest

注: AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,如果发出跨域请求,就会报错

同源限制:实际上,同一个网域的不同端口,是可以互相读取 Cookie 的。

CORS/Cross-Origin Resource Sharing/跨源资源分享: W3C 标准,属于跨源 AJAX 请求的根本解决方法。只要服务器实现了 CORS 接口,就可以跨域通信。

Node.JS

  • Template strings

Reference

  • Arrow functions: Lambda表达式: ES6标准, (paramN) => {statements}
  • Promise

学习教程

  • JavaScript 教程
  • 本文作者: xulizhao
  • 本文链接: https://xulizhao.com/blog/javascript/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
#javascript#
读历史
SSL和TLS加密
  • 文章目录
  • 站点概览

xulz

时光,漫步

56 日志
3 分类
28 标签
  • JavaScript基础
    • 基本语法
    • 运算符
    • 常用风格
  • 高级
    • 闭包
    • eval
    • 事件
    • Module
    • Promise
  • DOM
  • 浏览器模型
    • XHR/AJAX
  • Node.JS
  • Reference
    • 学习教程
© 2017 - 2023 XuLizhao 's Notes
Powered by - Hugo/ NexT
津ICP备17010344号-1
0%