Web Components
Web Components用于创建可复用的自定义元素——将它们的功能封装在其他代码之外,便于在web app里使用。
为了解决编写复杂的 HTML(以及相关的样式和脚本)来呈现自定义 UI 控件,Web Components提供了3种技术:Custom elements、Shadow DOM、HTML templates。
本文涉及ES6 classes(也称ES2015),当前 global 支持情况达 96.54%
jQuery Tips
在维护jQuery技术栈项目时可能用到的一些方法。
设置 ajax POST request 参数为 JSON 格式。一个是设置请求头的 content-type,一个是 data 的值转为 JSON 的字符串。
$.ajax({
contentType: "application/json; charset=UTF-8",
dataType: "json",
type: "POST",
data: JSON.stringify({pageNo: 1, pageSize: 100})
})
取出与 jQuery 对象匹配的 DOM 元素
$("li").get(0);
$("li")[0]; // also
JavaScript模块化
ES Modules
ES6 模块是一种在JavaScript中定义和导出可重用代码的标准化方法。
- 使用
import
和export
关键字来定义和导出代码。 - 可以在应用程序中按需加载。
- 提供了一种在应用程序中管理依赖项的方式,使代码更易维护和扩展。
SSR实践
与网络上一般的纯SSR方案不同,我们实现的是一套兼容现有项目代码,PC/H5项目均采用同构(即server、client端均采用同一套代码渲染组件)的模式来构建SSR应用。
同构模式下,开发者仅需关注业务本身。
但这套方案最终由于原开发者离职,页面性能提升有限,项目维护和迁移困难,存在bug隐患等诸多因素被放弃。
一些注意事项:
- 浏览器里才可用的常量:window、document等
- http数据请求同时支持server、client端
- React 组件生命周期
- 通过注入环境变量区分当前运行时环境
server:renderToString 一定程度上是 CPU 密集型操作,提高单机 QPS?服务的运维、扩容? client:利用PWA做离线缓存
静态数据:不常变更的数据,如:商品标题、描述等 动态数据:与用户登录状态有关的数据,如:是否收藏过
使用 concurrently
同时启动多个命令。
concurrently "command1 arg" "command2 arg"
使用 ctrl + c 停止所有进程
ReactDOM.hydrate
有时在浏览器 console 可看到报错提示说某某组件的文本内容在 server 是什么,在 client 是什么,总之不一致。
原因:React 希望服务端与客户端渲染的内容完全一致。React 可以弥补文本内容的差异,但是你需要将不匹配的地方作为 bug 进行修复。在开发者模式下,React 会对 hydration 操作过程中的不匹配进行警告。
React Native开发
一些开发经验: 1.代码修改完,在simulator模拟器中 cmd + R 刷新,才能看到代码生效 2.模拟器里开启 Remote JS Debugging,在默认浏览器里新开tab(React Native Debugger),在开发者工具里就可以看到 console 输出了 3.使用 xcode 打开 ios 项目,等待扫描项目文件结束(时间长短与项目代码量有关)选择一个模拟器。在 RN 项目根目录下,新建 ios 文件夹,将 ios 项目代码移动到此文件夹中。启动 RN 项目,xcode 中点运行,将自动打开模拟器中的 app 4.使用 simulator 打包编译过一次 app 后,下次可直接打开 simulator。注意:记住打包时所选的系统版本和机型,再次打开 simulator -》File -》Open Simulator-》iOS 14.2 -》iPhone 8
React.js 入门(四)
Thinking in React
当你在创建app时, React是如何使你思考的。
- Break The UI Into A Component Hierarchy,根据设计图,用方框画划分出组件层级。以“single responsibility principle”单一责任原则,划分组件。UI和数据模型倾向于遵循相同的信息体系结构。
- Build A Static Version in React,用 React 构建一个静态版。(用已有的数据模型渲染一个不包含交互功能的 UI)通过 props 传递数据,完全不使用 state(state 仅保留用于交互)。简单例子,自上而下写组件;大型项目,自下而上写,顺便写下test case。
- Identify The Minimal (but complete) Representation Of UI State,确定 UI 所需最少的可变状态。以Don’t Repeat Yourself原则。以下情况可以排除使用 state:
- 通过 props 从父组件传进来
- 不随时间改变
- 可以基于当前组件其他 state 或 props 计算得到
- Identify Where Your State Should Live,鉴定哪个组件应该拥有这个状态,铭记 React 是单向数据流。对于应用中每一个 state,看看哪些组件需要基于它来渲染,找到公共 owner(在所有需要这个 state 的组件层级树之上)组件,如果没找到合适的组件,单独创建一个新的来 hold 这个状态
- Add Inverse Data Flow,最后通过
setState()
方法,支持反向的数据流动
Chrome Extension开发
扩展程序/插件可以改变用户看到的网页内容,扩展、交互或者改变浏览器自身的行为。
插件的组件就是由web技术开发的:html、css、js。组件可以包含:
- background 脚本,包含对于插件重要的浏览器 event handler
- UI元素,应该目的明确、小巧
- content 脚本,读写当前已加载的页面内容
- options 页面,允许用户自定义插件(如选择需要的功能)
- 各种 logic 业务逻辑文件
除了可以直接使用同网页一样的 api,扩展程序也有专门的 api。大部分 Chrome 插件 api 都是异步的。
页面直接通信:页面通过 chrome.extension
方法获取其他页面的 reference,就可以调其他页面的方法,操作DOM。此外还可以通过 message passing 通信。
MobX Learning
State 状态
驱动应用的数据。
Observable state:可观察的状态,为现有的数据结构(如对象,数组和类实例)添加了可观察的功能。
Derivations 衍生
源自状态,并且不会再有任何进一步的相互作用。
Computed values:计算值,可以使用纯函数(pure function)从当前可观察状态中衍生出的值。 通过@computed 装饰器,调用 的getter / setter 函数来进行使用。
Reactions:反应,不产生新的值,当状态改变时需要自动发生的副作用,最终都需要实现I/O操作,如:打印到控制台、网络请求、递增地更新 React 组件树以修补DOM等。
MobX 会对在执行跟踪函数(autorun
、reaction
、when
)期间读取的任何现有的可观察状态做出反应。
Actions
任何一段可以改变state的代码。
Actions:动作,是可选的内置概念。类似用户在excel单元格输入一个值,所有用户事件、后端数据推送、预定事件等。
严格模式下,MobX 会强制只有在动作之中才可以修改状态。
Hybrid APP 开发实践
状态栏
背景为透明,字体默认黑色。可通过传参数,让native设置字体颜色。
H5页面如果设置全屏,则需要让头部组件预留出状态栏高度的空隙,
页面跳转
浏览器里通过链接打开app或跳转至应用商店app下载页。直接打开deeplink已安装app的打开app,未安装的会报错。
如果是打开 Adjust 链接,则会通过跳转到 Adjust 页面唤起app或跳转至应用商店。Adjust 会收集数据,一般产品想统计多少未安装app的打开链接。
React H5开发实践
最近响应公司大前端统一技术栈的号召,新项目都是基于 React 开发。时隔几年很庆幸框架引入了 Hooks,在掌握了基本概念后,使用 Hooks 开发敲代码飞起。
HOOK
动机:React 需要为共享状态逻辑提供更好的原生途径。
使用 Hook 从组件中提取状态逻辑,使得这些逻辑可以单独测试并复用。将组件中相互关联的部分拆分成更小的函数(比如设置订阅或请求数据)。
问题表现: class 中生命周期函数经常包含不相关的逻辑。如:获取数据,事件侦听、消除。相互关联且需要对照修改的代码被拆分在不同的钩子函数里,而完全不相关的代码却在同一个方法中组合在一起。如此很容易产生 bug,并且导致逻辑不一致。
在多数情况下,不可能将组件拆分为更小的粒度,因为状态逻辑无处不在。这也是很多人将 React 与状态管理库结合使用的原因之一。
Class的问题: 事件处理绑定 this
,代码冗余繁琐。使用 class 组件会无意中鼓励开发者使用一些让打包工具的优化措施无效的方案,不好压缩,让热重载不可信。
为了解决这些问题,Hook 使你在函数组件里,也可以使用更多的 React 特性。
建议:先在新的不复杂的组件中尝试使用 Hook,并确保团队中的每一位成员都能适应。
Create React App Tips
根据官网所介绍,这是一个用于学习 React 的舒服的环境,是创建一个新的单页 React 应用最好的方式。
本地调试 PWA
使用 Create React App 创建的项目,根据 create react app 官方文档:
- 只有 production 环境开启了 serviceWorker
- 如果需要本地测试离线服务,先用
npm run build
构建,然后从构建好的目录下使用标准的 http server 启动页面
实际上,构建之后在终端里可以看到下文:
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
ES新特性合集
异步函数
使用 async
关键字声明的函数称为异步函数。
async
与 await
关键字可以使用更简洁的方式写出基于 Promise 的异步行为,而无需刻意地链式调用 promise。
举例:
const fetchUser = async (id) => {
try {
const user = await fetchData(id);
console.log('User:', user);
} catch (error) {
console.error('Error:', error);
}
};
fetchUser(123);
async 语法
特征是在 function 名字前加 async
关键字。
1、Async 函数返回一个 Promise 对象,可以使用 then
方法添加回调函数。
async function helloAsync() {
return 'Hello, async!';
}
console.log(helloAsync()); // Promise { <state>: "pending" }
helloAsync().then(result => {
console.log(result)
});
// Hello, async!
2、async 函数执行时遇到 await
关键字就先暂停执行,等到触发的异步操作完成,再恢复 async 函数的执行并返回解析值。
await
关键字仅在 async 函数中有效。
function testAwait() {
return new Promise(resolve => {
setTimeout(() => {
console.log('testAwait');
resolve();
}, 1000);
});
}
async function helloAsync() {
await testAwait();
console.log('helloAsync');
}
helloAsync();
// testAwait
// helloAsync
computed property name
对象的键名可以使用变量定义,在创建对象时使用 bracket notation 方括号圈起来,如 {[phoneType]: 12345}
All About Cookies
本文内容基于这篇英文博客 All about cookies。
HTTP Cookie也简称为“Cookie”,根据wikipedia记载,最早是在1994年由Netscape网络浏览器开发者 Lou Montulli 提出并用于网络通信。服务端借助 cookie 实现用户与服务端之间的状态。
Safari 滚动及相关兼容性问题
fixed定位在 Safari 中滚动穿透问题
Element.scrollTop
属性可以获取或设置一个元素的内容垂直滚动的像素数。
https://segmentfault.com/a/1190000012313337
pc端通常用方案一:在body元素上toggle overflow:hidden 即可。手机端在iPhone Safari上无效。
亲测方法三有效。
let bodyEl = document.body
let top = 0 // 记录蒙版出现时页面scroll的y值
function stopBodyScroll (isFixed) {
if (isFixed) {
top = window.scrollY
bodyEl.style.position = 'fixed'
bodyEl.style.top = -top + 'px'
} else {
bodyEl.style.position = ''
bodyEl.style.top = ''
window.scrollTo(0, top)
// 滚动回到蒙版出现时页面的位置
// 否则,当蒙版消失,body的position改变,页面回到top为0的位置
}
}
NPM实践
npm源问题:
package-lock.json文件中因他人本地 npm source 设置不同,导致官方源 https://registry.npmjs.org
,混入了 taobao 源。Jenkins 发布不稳定、个别依赖包最新版本没有被 taobao 源支持,等等,都会导致导致 npm 构建失败。统一包来源的方法:
- 删除 package-lock.json
- 删除 node_modules 目录(即已安装的文件)
- 运行 npm install
查看当前npm源
npm config get registry
Node.js相关
JS 是客户端编程语言,通过 Node.js,JS也可以服务端语言被使用。
使用 npm 初始化新项目,命令行工具运行: npm init
根据提示输入 package name、version number、description。通过 enter 键跳过,最终生成 package.json 文件。
Multiple packages' JS project
本文记录如果实现搭建/管理含多个packages的js项目。
最初的需求是在一个项目里集中管理团队中成员单独写的 Vue.js 插件。了解到 scoped packages 的概念。
受到 Vue CLI 3 的启发,发现了 Lerna 这个工具。
有作用域的包
命名:@somescope/somepackagename
,不能以 .
或 _
开头。
作用:将相关的包集中管理。每一个npm的用户或organization都有自己的 scope。
安装:npm install @myorg/mypackage
有作用域的包实际上被安装在了与作用域同名的文件目录下,因此代码中引用如 require('@myorg/mypackage')
。
- 发布public的作用域包,只需在初始发布时指定
--access public
- scope 和 registry 是 many-to-one 多对一的关系。
Vue CLI 使用tips
@vue/cli是全局安装的 npm 包,未终端命令行工具提供 vue 指令。
@vue/cli-service 是局部安装的 npm 包,作为(由 @vue/cli 创建的)项目开发的 devDependencies。
CLI Service主要基于 webpack
和 webpack-dev-server
两个工具。
使用 vue ui
创建的vue项目可以通过 GUI 执行 npm scripts 的 serve 和 build 指令,呈现 webpack Analyzer 的图形化结果。
JS实现文件下载和上传
下载后台返回的文件
用 blob 形式读取响应数据,然后转译成 url 形式并赋值给 a 标签的 href 属性,模拟点击动作,触发浏览器下载。
axios({
method: 'get',
url: url,
params: data,
responseType: 'blob'
})
.then(response => {
if (response.status === 200) {
let blob = new Blob([response.data]);
let filename = response.headers['content-disposition']
// 转译以URL形式编码的文件名
filename = decodeURI(filename.split('"')[1])
let a = document.createElement("A")
a.href = window.URL.createObjectURL(blob)
a.download = filename
a.click()
}
})
.catch(error => {
// error handler
})
Vue开发tips
Vue.js 可以把数据绑定到 DOM 文本或特性,还可以绑定到 DOM 结构。通过添加事件监听器,处理用户输入。
通过所有的 DOM 操作都由 Vue 来处理,开发者只需编写处理逻辑层的代码。
Vue 组件类似于自定义元素——它是 Web 组件规范的一部分,因为 Vue 的组件语法部分参考了该规范。
Webpack从入门到放弃
Webpack 是目前流行的前端资源模块化管理和构建工具。
- 可以将模块按照依赖和规则打包成符合不同环境部署的前端资源
- 可以对按需加载的模块进行代码分割,实现异步加载
- 通过指定的 loader 对模块的源代码进行转换,即引用/加载时预处理 pre-compile 文件
- 由于 loader 仅对单个文件进行操作,使用 plugins 可在编译、chunk 生命周期执行自定义操作
核心概念
Entry
用来指明webpack应该使用哪个模块开始构建内部的依赖图。webpack 将整理出 entry point 直接或间接依赖的其他模块和库。单页应用值为string或string数组,多页应用值为对象。
Output
该属性告诉webpack生成的 bundle 文件放到哪里,如何命名。
Loaders
默认地 webpack 只认识 JavaScript 和 JSON 文件,通过 Loaders,webpack 可以处理其他类型的文件,并把他们转成可以被你应用消费的有效的模块,并添加到依赖图里。
Plugins
插件可以实现更多的任务,比如优化 bundle,资源管理,插入环境变量。你可以在配置中多次使用同一个插件以实现不同目的,因此需要使用 new
操作符来创建该插件的实例。
Mode
默认值是 production,可以设置为 development。通过该参数可以根据不同环境使用 webpack 内置的优化策略。
HTML5应用开发实践指南
JavaScript的力量
推荐阅读《JavaScript语言精粹》(JavaScript, The Good Parts, Douglas Crockford),《JavaScript权威指南》(Javascript: The Definitive Guide, David Flanagan),《高性能JavaScript编程》(High Performance JavaScript, Nicholas C.Zakas),《JavaScript模式》(JavaScript Patterns, Stoyan Stefanov)
因为JS是单线程的,如果函数被阻塞,用户界面就冻结了。 所以JS要采用不同于传统语言处理 I/O
事件驱动编程。操作异步,先在某个地方创建操作,当外部事件发生后再执行。JS中所有外部的 I/O(数据库,调用服务器)都应该是非阻塞的,学习使用闭包和回调至关重要。
React.js 入门(三)
Forms 表单
HTML 表单元素(如 <input>
、<textarea>
、<select>
)通常维护自己的状态并根据用户输入进行更新。表单提交默认行为的刷新页面,但大多数情况下我们希望通过JS处理数据提交。在 React 里通过受控组件实现。
当一个表单输入元素的 value 由 React state 控制,称之为 controlled component。
以下受控组件的使用非常相似:
<input type="text" value={this.state.value} onChange={this.handleChange} />
<textarea value={this.state.value} onChange={this.handleChange} />
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
React.js 入门(二)
本章主要写 React 的数据操作。
state 状态
状态就像是组件自己的数据存储,用于处理随时间改变的数据和用户互动产生的数据。
state 对于拥有和设置它的 React 组件是 private 的(任何其他组件都不接近)。组件可以向下传递 state 及其派生的状态给子组件。
当数据变化时,通过调用 this.setState(data, callback)
把数据合并到组件私有属性 this.state
中,驱动组件重新 render 自己。其中 callback 是可选的。
- constructor 是唯一可以给 this.state 赋值的地方
- 直接修改 state 的值不会重新渲染组件,必须使用
setState()
- 出于性能考虑,React 可能会把多个 setState() 调用合并成一个更新。因为 this.props 和 this.state 可能会异步更新,所以不要依赖他们的值来更新下一个状态
React.js 入门(一)
React 是由 Facebook 创建的一个声明式的用于构建 UI 的 JS 库。
借助 React 通过小的、相互独立的代码片段(component,即组件)可以构建复杂的用户界面。
对已有网页添加 React 最简单的方式是,以 <script>
标签引入 React(顶层API)、React DOM(DOM相关方法)、Babel(在旧浏览器里使用ES6+)外部js文件。
但随着应用不断增长变复杂,为了处理一些如:大量的文件、组件,使用 npm 上的第三方库,提前检测语法/代码错误,热更新CSS/JS,优化打包文件等,我们引入官方建议的 toolchain。
JavaScript Scope
Scope is the set of variables, objects, and functions you have access to. 你可以获取的变量、对象和函数的集合称为 scope 作用域。
JS 的 block 没有作用域,只有 functions 有作用域。
Global Scope
通过全局作用域创建 Modules/APIs 实现功能复用。
jQuery('.myClass');
上面的代码表示在全局作用域里使用 jQuery,并作为 jQuery 函数库的命名空间 namespace(通常指最高一层作用域)。
Local Scope
每个定义的函数都有自己的局部作用域,local scope 可以层层嵌套。
无论何时执行一个函数,就有一个 scope 对象被创建,用于保存那个函数内部创建的局部变量。
ECMAScript 6 入门读书笔记
let 命令
声明块级变量。
let
命令只在其所在的代码块(由一对大括号限制起来的区域)内有效。- 如果有代码块嵌套,外层代码块使用
let
声明的变量,不受内层代码块的影响。 - 不像
var
,该命令不引起变量提升(Hoisting)。提前使用未声明的变量,报错。 - 不允许使用
let
在同一个代码块内重复声明同一个变量,会报错 duplicate declaration。 -
那如果使用
var
和let
重复声明同一个变量呢?{ let a = 10; // a = 10 var a = 1; // a = 10 } { var a = 1; // a = undefined let a = 10; // a = 10 }
JavaScript HTML DOM
DOM stands for Document Object Model, 是一个独立于平台和语言的接口,允许程序和脚本动态获取和更新一个文档的内容、结构和样式。
W3C DOM 标注分为3种不同的部分:Core DOM,XML DOM 和 HTML DOM。
HTML DOM
HTML DOM 规定了如何获取、改变、添加或删除 HTML 元素。
在 DOM 中,所有 HTML 元素被定义为对象。编程接口就是每个对象的属性(你可以获取和设定的值,比如 innnerHTML,该属性可以用来获取、改变任何HTML元素)和方法(可执行的操作,如 getElementById()
)。
JavaScript Browser BOM
Browser Object Model, 浏览器对象模型使得JS可以与浏览器对话。
Window object
所有浏览器都支持窗口对象。全局变量是 window 对象的属性,而全局函数是 window 对象的方法。
甚至 HTML DOM 的 document 对象也是窗口对象的属性,可以由 window.document
来获取。
Window Size
window.innerHeight 和 window.innerWidth 这两个属性可用来测量浏览器窗口的尺寸(以 pixel 为单位)。
浏览器窗口(browser viewport)不包括工具条和滚动条.
JavaScript Functions
The typeof
operator in JavaScript returns “function” for functions. But, JS函数最好被描述为对象。
使用 arguments.length
property 可以返回函数调用时,接收到的实际参数个数。
函数语句 Syntax
使用关键字 function 后面跟函数名,括号,由逗号分隔开的参数(参数不是必须的),再跟一个大括号。
function name(parameter1, parameter2, parameter3) {
code to be executed
}
Function names can contain letters 字母, digits 数字, underscores 下划线, and dollar signs 美元符号(same rules as variables)。
JavaScript Objects
JS 对象是可以包含多个值的变量。这些值以 name: value
对的形式、逗号为分隔符。
在JS中,all data types have a valueOf()
和 toString()
方法.
创建新对象
1.Using an Object Literal
同数组一样,空格和换行不重要。
var person = {firstName:"John", lastName:"Doe", age:50};
var person = {
firstName:"John",
lastName:"Doe",
age:50
};
JavaScript JSON, JSONP
JSON 是指 JavaScript Object Notation, 是一种轻量级的数据存储和传输格式,独立于语言(text only,可用任何编程语言来读取和生产 JSON 数据),常用于跨平台的数据交换。
JSON 可以“自描述”(human readable),容易理解。
JSON 文件的后缀名为 .json
Syntax
数据以 name/value 成对出现,由逗号分隔,大括号里放对象,对象可以包含多个 name/value 对;方括号里放数组,数组可以包含多个对象。
JavaScript Strict Mode and Best Practices
“use strict”;
这不是一条语句,而是一个 literal 表达式,被 ECMAScript 5 之前版本的 JS 忽略。其作用是指令代码需要在严格模式下执行。
使用 strict mode,使得原先可以接受的 “bad syntax” 变成了真正的 error。
声明
- 在 JS 文件最开始的地方声明,则表示所有代码将在严格模式下被执行。
- 在 function 内部最开始的地方声明,则只有该函数内的代码需要在严格模式下被执行。
JavaScript Conditions and Loop
JS conditional statements 条件语句,根据不同决定执行不同操作。
if … else 语句
if
Statements
条件为 true 时,执行一段代码。
else
Statements
条件为 false 时,执行一段代码。
else if
Statements
如果第一个条件为 false 时,检查新的条件。if (condition1) {…} else if (condition2) {…} else {…}
JavaScript Arrays
JS数组用于在一个变量名下存储多个具有共性的数值。
var cars = ["Saab", "Volvo", "BMW"];
- 数组中空格和换行不重要
- 最后一个数组项目后没有逗号!
- 操作数组项目通过 index number, Array 索引 start with 0
JavaScript Dates
Date 对象是用来与年月日时分秒毫秒打交道的。
创建 Date 对象
有4种初始化日期对象的方式:
new Date()
,以current date and time创建一个新的日期对象,输出为本地时间,取决于系统设定。
new Date(milliseconds)
,按照 zero time(01 January 1970 00:00:00 UTC)加上参数值,创建新的日期对象。
new Date(dateString)
,按指定的日期字符串创建一个新的日期对象,dateString 格式参考下面讲的 Date formats
new Date(year, month, date, hours, minutes, seconds, milliseconds)
,至少指定 year 和 month。其他参数缺省时 date 置 1,剩下都置 0。
JavaScript Numbers
JS只有一种 Number 类型的数,可以带小数写,也可以不用。
特别大或特别小大数可以用 scientific (exponent) notation 写。
var x = 123e5; // 12300000
var y = 123e-5; // 0.00123
精度
JS的数字是双精度 64-bit IEEE 754 浮点数。整数可以保证是精确的最多位数是15位**。最大安全整数 9007199254740991,超过最大安全整数的运算是不安全的。
小数最多位数是 17。
var x = 0.2 + 0.1; // x will be 0.30000000000000004
var x = (0.2 * 10 + 0.1 * 10) / 10; // x will be 0.3
JavaScript Math and Boolean
Math Object
Math
是JS内置对象,提供高级数学函数和常量。 Math对象不是一个 constructor,不可以/不需要使用 new 关键字来创建。
Math functions
Math.random()
,返回一个[0,1)之间的随机数,always lower than 1Math.min(n1, n2, n3, ..., nX)
,返回参数中的最小值。缺省参数返回Infinity
。如果有一个或多个参数不是 number,则返回 NaNMath.max(n1, n2, n3, ..., nX)
,返回参数中的最大值。缺省参数返回-Infinity
。如果有一个或多个参数不是 number,则返回 NaNMath.round(x)
,四舍五入,返回最接近参数 x 的整数Math.ceil(x)
,四舍五入,返回向上最接近参数 x 的整数Math.floor(x)
,四舍五入,返回向下最接近参数 x 的整数Math.pow(x, n)
,返回 x 的 n 次幂Math.abs(x)
,返回数字 x 的绝对值Math.trunc(x)
,返回数字 x 的整数部分
JavaScript Strings
JS String 是一系列 Unicode 字符,用单引号或双引号限制起来的 immutable UTF-16 code units。
每一个代码单元由一个 16-bit 数字表示。每一个 Unicode 字符由1到2个代码单元表示。
反斜杠
使用反斜杠输出特殊字符 backslash escape character turns special characters into string characters。
Strings Can be Objects
创建 String 变量的方法有:
var x = "John";
var y = new String("John");
最好不要用后者,减缓执行速度。且 x === y
是 false 的,因为后者的 type 是 object。 JavaScript objects cannot be compared。两者无法比较。
前者创建的是 primitive values,但是 in JavaScript, methods and properties are also available to primitive values.
JavaScript Regular Expressions
一个 Regular Expression (正则表达式)是组成一个 search pattern (搜索模式/规则)的一系列字符,它是一个对象,可用于文本的查找和替换操作。
语法
由 pattern 和 modifier(s) 组成。
/pattern/modifiers;
经常使用到正则表达式的就是字符串方法 search()
和 replace()
。
JavaScript Data Types and Type Conversion
JS 是一种 weakly-typed 语言。
- 基本类型: String(”John Doe”),Numbers(3.14),Boolean(true/false),Symbol 和 Object。
- Function、Array、Date、RegExp 都是 objects
- 有2种不含 value 的类型:undefined,null
HTML Web Storage
浅谈 Web 前端 Client side storage。更新参考这篇An Overview of Client-Side Storage。
目前有四种 active 的方式:Cookies,Local Storage,Session Storage,IndexedDB。
Cookies
Cookies 是一种经典地存储简单 string 数据的方式。可以由 server 发给 client,然后 client 保存在本地,下次请求再传回 server。这样 server 可以管理帐户 session,追踪用户信息。它可以由 client 本地设置,传给 server。
JavaScript Forms Validation API
Data Validation
数据验证是为了保证输入是 clean、correct and useful,分为服务器端验证和客户端(浏览器)的验证。H5引入了新的验证原则叫做 constraint validation。
基于 HTML Input Attributes,CSS Pseudo Selectors,DOM Properties and Methods。前两者内容参考 HTML 和 CSS 部分文章,本章围绕 DOM 属性和方法。
JavaScript Event order
常见的事件注册方法可以参看《HTML Forms and Form Elements》章节表单提交事件的例子。
事件流:当触发某个元素的事件时,事件会按照DOM树的结构进行传播,传播过程分为捕获阶段和冒泡阶段。
捕获阶段:从最外层的 document 节点开始,逐层向内/下传播,直到目标元素。
冒泡阶段:从目标元素开始,逐层向外/上传播,直到最外层的 document 节点。
JavaScript Errors and Debugging
JS中的错误可能是程序员代码的错误,也可能使错误的输入或其他不可预见的原因导致的。
JavaScript try and catch
The try statement 用于检查这块代码执行时是否有错误出现。
The catch statement 在 try 部分有错误出现时,执行此处的代码。
The finally statement 定义了不论 try 和 catch 的结果如何,在他们之后要执行的代码。
JavaScript Syntax
Statements
在编程语言中,被计算机执行的语句称为 statements。语句按照它们书写的顺序,一条接一条地被执行。
空格
JS忽略掉多个空格,所以我们可以在代码里添加空格方便阅读。
一个好的实践是:在 operator 操作符 周围加一个空格:
var x = y + z;
换行
避免一行代码过长,w3Schools 建议不超过 80 个字符。语句换行,最好是在一个 operator 操作符之后;
document.getElementById("demo").innerHTML =
"Hello world, this is my first js code."
JavaScript Basic
JavaScript旨在作为脚本语言运行在主机环境(除了广为人知的浏览器,JavaScript interpreters 解释器还存在于 Adobe Photoshop、SVG image、服务端环境Node.js、NoSQL数据库、GNOME等)。
JavaScript 是web开发人员必学的三大基本语言之一。It makes HTML pages more dynamic and interactive.
Where To
JavaScript 代码可以放在 HTML 页面的 <head>
和/或 <body>
部分。
- HTML 页面里的 JS 代码必须写在
<script>
和</script>
标签之间 - 在 HTML 文档里可以放置任意数量的 scripts
- keep all codes in one place is always a good practice
- 把脚本放在
<body>
元素的底部可以提高页面加载速度,因为脚本编译会减缓页面显示 - 如果有无法加载的JS文件,浏览器会在N秒后才放弃,如果文件是在内容中间,这个会让流畅加载的页面突然中断N秒
注意:在老的JS代码里会看到,<script type="text/javascript">
,现在该标签的 type 特性不是必须的,JavaScript 是 HTML 的默认脚本语言。
HTML5 Style Guide and Coding Conventions
Programming style guidelines
Coding convention 代码公约,通常包含:
- 变量和函数的命名、声明规则
- 空格、缩进、注释的使用规则
- 编程实践和原理
使用代码公约能够提高代码的可读性,使得代码更容易维护。