Javascript零散笔记

JavaScript 中包含以下 7 个全局函数

escape( )、eval( )、isFinite( )、isNaN( )、parseFloat( )、parseInt( )、unescape( )。

JavaScript为指定元素绑定一个事件处理器函数

Javascript块内声明函数

不要在块内声明一个函数(严格模式会报语法错误)。如果确实需要在块中定义函数,可以使用函数表达式来声明函数。

1
2
3
4
5
6
7
8
9
10
/* Recommended */
if (x) {
var foo = function() {};
}


/* Wrong */
if (x) {
function foo() {}
}

Jquery获取宽高

1
2
3
4
5
6
7
8
alert($(window).height()); //浏览器当前窗口可视区域高度 
alert($(document).height()); //浏览器当前窗口文档的高度
alert($(document.body).height());//浏览器当前窗口文档body的高度
alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin
alert($(window).width()); //浏览器当前窗口可视区域宽度
alert($(document).width());//浏览器当前窗口文档对象宽度
alert($(document.body).width());//浏览器当前窗口文档body的高度
alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin

浏览器兼容性问题

  • SD9017: Firefox 不支持 DOM 对象的 outerHTML、innerText、outerText 属性(参见http://w3help.org/zh-cn/causes/SD9017)
  • SD9010: 仅 IE 中的 createElement 方法支持传入 HTML String 做参数
  • SD9006: IE 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现

2017.08.15更新


parseInt()

parseInt() 函数解析一个字符串参数,并返回一个指定基数的整数 (数学系统的基础)。

语法

1
parseInt(string, radix);

参数

string
要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用ToString抽象操作)。字符串开头的空白符将会被忽略。
radix
一个介于2和36之间的整数(数学系统的基础),表示上述字符串的基数。比如参数”10”表示使用我们通常使用的十进制数值系统。始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常将值默认为10。

返回值

返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN

描述

parseInt函数将其第一个参数转换为字符串,解析它,并返回一个整数或NaN。如果不是NaN,返回的值将是作为指定基数(基数)中的数字的第一个参数的整数。
例如:radix参数为10将会把第一个参数看作是一个数的十进制表示,8对应八进制,16对应十六进制,等等。基数大于10时,用字母表中的字母来表示大于9的数字。例如十六进制中,使用A到F。
如果parseInt遇到了不属于radix参数所指定的基数中的字符那么该字符和其后的字符都将被忽略。接着返回已经解析的整数部分。parseInt将截取整数部分。开头和结尾的空白符允许存在,会被忽略。
在没有指定基数,或者基数为0的情况下,JavaScript作如下处理:

  1. 如果字符串string以”0x”或者”0X”开头,则基数是16(16进制).
  2. 如果字符串string以”0”开头,基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript5规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
  3. 如果字符串string以其它任何值开头,则基数是10(十进制)。
  4. 如果第一个字符不能被转换成数字,parseInt返回NaN

算术上,NaN不是任何一个进制下的数。你可以调用isNaN来判断parseInt是否返回NaNNaN参与的数学运算其结果总是NaN
将整型数值以特定基数转换成它的字符串值可以使用intValue.toString(radix).

null与undefined

null是一个 JavaScript 字面量,表示空值(null or an “empty” value),即没有对象被呈现(no object value is present)。它是JavaScript原始数据类型之一。

全局属性undefined表示原始值undefined。它是一个JavaScript的原始数据类型 。
JavaScript的原始数据类型:String,Number,Bollean,null,undefined,symbol(ES2015新增)

nullundefined的不同点:

1
2
3
4
5
6
7
8
9
typeof null        // object (因为一些以前的原因而不是'null')
typeof undefined // undefined
null === undefined // false
null == undefined // true
null === null // true
null == null // true
!null //true
isNaN(1 + null) // false
isNaN(1 + undefined) // true

js精度丢失

计算机的二进制实现和位数限制有些数无法有限表示。就像一些无理数不能有限表示,如 圆周率 3.1415926…,1.3333… 等。JS 遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit。
解决方案:

  • 对于整数,前端出现问题的几率可能比较低,毕竟很少有业务需要需要用到超大整数,只要运算结果不超过 Math.pow(2, 53) 就不会丢失精度。
  • 对于小数,前端出现问题的几率还是很多的,尤其在一些电商网站涉及到金额等数据。解决方式:把小数放到位整数(乘倍数),再缩小回原来倍数(除倍数)

switch

switch()使用===判断相等


2017.08.19更新


Number.prototype.toString()使用注意

Number对象使用toString方法,Number对象必须加上(),否则表示小数。不加括号会报错。


2017.08.20更新


RegExp.prototype.exec()

RegExp.prototype.test()

Date对象

构造函数

1
2
3
4
new Date();//访问当前时间
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

参数

value
代表自1970年1月1日00:00:00 (世界标准时间) 起经过的毫秒数。
dateString`
表示日期的字符串值。该字符串应该能被Date.parse()方法识别(符合IETF-compliant RFC 2822 timestampsversion of ISO8601)。
year
代表年份的整数值。为了避免2000年问题最好指定4位数的年份; 使用 1998, 而不要用 98.
month
代表月份的整数值从0(1月)到11(12月)。
day
代表一个月中的第几天的整数值,从1开始。
hour
代表一天中的小时数的整数值 (24小时制)。
minute
分钟数。
second
秒数。
millisecond
表示时间的毫秒部分的整数值。

注意

Note 1: 需要注意的是只能通过调用Date构造函数来实例化日期对象:以常规函数调用它(即不加new操作符)将会返回>一个字符串,而不是一个日期对象。另外,不像其他JavaScript 类型,Date对象没有字面量格式。

Note2 : 当Date作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为13或者分钟数为70),相邻的数值会被调整。比如new Date(2013, 13, 1)等于new Date(2014, 1, 1),它们都表示日期2014-02-01(注意月份是从0开始的)。其他数值也是类似,new Date(2013, 2, 1, 0, 70)等于new Date(2013, 2, 1, 1, 10),都表示时间2013-03-01T01:10:00。

Date.parse()

Date.parse()方法解析一个表示某个日期的字符串,并返回从1970-1-1 00:00:00 UTC 到该日期对象(该日期对象的UTC时间)的毫秒数,如果该字符串无法识别,或者一些情况下,包含了不合法的日期数值(如:2015-02-31),则返回值为NaN

语法

显示调用:

1
Date.parse(dateString)

隐式调用:

1
new Date(dateString)

参数

dateString
一个符合IETF-compliant RFC 2822 timestampsversion of ISO8601日期格式的字符串(其他格式也许也支持,但结果可能与预期不符)。

返回值

一个表示从1970-1-1 00:00:00 UTC到给定日期字符串所表示时间的毫秒数的数值。如果参数不能解析为一个有效的日期,则返回NaN。
描述

Date.prototype.getDay()

语法

1
dateObj.getDay()

参数

返回值

getDay()返回一个整数值:0代表星期日,1代表星期一,2代表星期二,依次类推。

Date.prototype.getDate()

语法

1
dateObj.getDate()

参数

返回值

getDate()返回一个1到31的整数值。

##

语法

1
dateObj.getMonth()

参数

返回值

getMonth返回一个0到11的整数值:0代表一月份,1代表二月分,2 代表三月份,依次类推。

正则表达式

RegExp

g
全局匹配;找到所有匹配,而不是在第一个匹配后停止

浏览器内核

chrome: Webkit –> Blink
Safari: Webkit
Mozilla: Gecko
IE: Trident
Opear: Presto –> Blink

浏览器解析方式

  1. 非怪异(标准)模式
  2. 怪异模式(一个不含任何DOCTYPE的网页将会以 怪异(quirks) 模式渲染。)
  3. 部分怪异(近乎标准)模式(实施了一种表单元格尺寸的怪异行为,除此之外符合标准定义。)

HTML5提供的<DOCTYPE html>是标准模式,向后兼容的, 等同于开启了标准模式,那么浏览器就得老老实实的按照W3C的 标准解析渲染页面,这样一来,你的页面在所有的浏览器里显示的就都是一个样子了。

DOM结构

DOM节点

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:

  1. 整个文档是一个文档节点
  2. 每个 HTML 元素是元素节点
  3. HTML 元素内的文本是文本节点
  4. 每个 HTML 属性是属性节点
  5. 注释是注释节点

节点的关系

父(parent)、子(child)和同胞(sibling)等术语用于描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹):

  1. 在节点树中,顶端节点被称为根(root)
  2. 每个节点都有父节点、除了根(它没有父节点)
  3. 一个节点可拥有任意数量的子
  4. 同胞是拥有相同父节点的节点

HTML5新增

与HTML4不同之处

  • 文件类型声明(<!DOCTYPE>)仅有一型:<!DOCTYPE HTML>。
  • 新的解析顺序:不再基于SGML。
  • 新的元素:section, video, progress, nav, meter, time, aside, canvas, command, datalist, details, embed, figcaption, figure, footer, header, hgroup, keygen, mark, output, rp, rt, ruby, source, summary, wbr。
  • input元素的新类型:date, email, url等等。
  • 新的属性:ping(用于a与area), charset(用于meta), async(用于script)。
  • 全域属性:id, tabindex, repeat。
  • 新的全域属性:contenteditable, contextmenu, draggable, dropzone, hidden, spellcheck。
  • 移除元素:acronym, applet, basefont, big, center, dir, font, frame, frameset, isindex, noframes, strike, tt。

新应用程序接口(API)

除了原先的DOM接口,HTML5增加了更多样化的API:-

  • HTML Geolocation
  • HTML Drag and Drop
  • HTML Local Storage
  • HTML Application Cache
  • HTML Web Workers
  • HTML SSE
  • HTML Canvas/WebGL
  • HTML Audio/Video

    HTML5文档类型声明

    在 HTML5 中,文档类型声明很简单:
    <!DOCTYPE HTML>
    在所有 HTML 文档中规定文档类型很重要,这样浏览器才能了解所预期的文档类型。
    HTML 4.01 中的 doctype 需要引用一个 DTD,这是因为 HTML 4.01 基于 SGML。HTML5 不基于 SGML,也不需要引用 DTD,但是需要声明文档类型让浏览器按照它们应该的方式来运行。

外边距叠加

外边距叠加是一个相当简单的概念。 但是,在实践中对网页进行布局时, 它会造成许多混淆。 简单的说, 当两个或更多个垂直边距相遇时, 它们将形成一个外边距。这个外边距的高度等于两个发生叠加的外边距的高度中的较大者。但是注意只有普通文档流中块框的垂直外边距才会发生外边距叠加。 行内框、 浮动框或绝对定位框之间的外边距不会叠加。

一般来说, 垂直外边距叠加有三种情况:

  1. 元素自身叠加。当元素没有内容(即空元素)、内边距、边框时,它的上下边距就相遇了,即会产生叠加(垂直方向)。 当为元素添加内容、内边距、边框任何一项,就会取消叠加。
  2. 相邻元素叠加。相邻的两个元素,如果它们的上下边距相遇,即会产生叠加。
  3. 包含(父子)元素叠加。包含元素的外边距隔着父元素的内边距和边框, 当这两项都不存在的时候,父子元素垂直外边距相邻,产生叠加。添加任何一项即会取消叠加。

参见给了body position:relative后 margin-top影响其他元素定位位置是为什么?

变量对象

基本类型

红宝书上解释的五种基本类型:

  • number
  • string
  • boolean
  • undefined
  • null
    但是也有人认为是六种,加上object, 成为复杂数据类型。

特殊包装类

Boolean: 布尔对象
String: 字符串对象
Number: 数字对象
这些对象的创建,是通过相应的内置构造器创建,并且包含原生值作为其内部属性,这些对象可以转换省原始值,反之亦然。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var c = new Boolean(true);
var d = new String('test');
var e = new Number(10);

// 转换成原始值
// 使用不带new关键字的函数
с = Boolean(c);
d = String(d);
e = Number(e);

// 重新转换成对象
с = Object(c);
d = Object(d);
e = Object(e);

typeof操作符

返回的类型只有六种:

  • string
  • number
  • boolean
  • undefined
  • object
  • function

instanceof操作符

instanceof操作符用来比较两个操作数的构造函数。只有在比较自定义的对象时才有意义。如果用来比较内置类型,将会和typeof操作符 一样用处不大。

Object.prototype.toString获取[[class]]

检测一个对象的类型,强烈推荐使用Object.prototype.toString方法; 因为这是唯一一个可依赖的方式。正如上面表格所示,typeof的一些返回值在标准文档中并未定义, 因此不同的引擎实现可能不同。 我们使用Object.prototype.toString方法:

1
2
3
Object.prototype.toString.call([])    // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call(2) // "[object Number]"

事件监听

HTML内联属性

类似<button onclick="alert('你点击了这个按钮');">点击这个按钮</button>的方式,这种方式会使JS与HTML高度耦合,不利于开发和维护,不推荐使用。

DOM属性绑定

使用DOM元素的onXXX属性设置,简单易懂,兼容性好。缺点是只能绑定一个处理函数。

事件监听函数

使用事件监听函数element.addEventListener(<event-name>, <callback>, <use-capture>);,在element这个对象上面添加一个事件监听器,当监听到有事件发生的时候,调用这个回调函数。至于这个参数,表示该事件监听是在“捕获”阶段中监听(设置为true)还是在“冒泡”阶段中监听(设置为false)。

移除事件监听

使用事件解除绑定方法:element.removeEventListener(<event-name>, <callback>, <use-capture>);
需要注意的是,绑定事件时的回调函数不能是匿名函数,必须是一个声明的函数,因为解除事件绑定时需要传递这个回调函数的引用,才可以断开绑定。

模拟触发事件

内置的时间也可以被JavaScript模拟触发,使用dispatchEvent方法。

自定义事件

与自定义事件的函数有EventCustomEventdispatchEvent

Event

直接自定义事件,使用Event构造函数

CustonEvent

CustomEvent可以创建一个更高度自定义事件,还可以附带一些数据,具体用法如下:

1
var myEvent = new CustomEvent(eventname, options);

dispatchEvent

这个用于触发自定义的事件

事件顺序

W3C :首先进入事件捕获阶段->达到元素后->进入事件冒泡阶段。
开发者可以通过addEventListener函数的第三个参数设置事件触发的阶段,默认为false,冒泡阶段。而DOM1级别的事件绑定则只能在冒泡阶段触发。

事件代理

事件绑定后,检测顺序就会从被绑定的DOM下滑到触发的元素,再冒泡会绑定的DOM上。也就是说,如果你监听了一个DOM节点,那也就等于你监听了其所有的后代节点。
代理的意思就是只监听父节点的事件触发,以来代理对其后代节点的监听,而你需要做的只是通过currentTarget属性得到触发元素并作出回应。
使用事件代理意味着你可以节省大量重复的事件监听,以减少浏览器资源消耗。还有一个好处就是让HTML独立起来,比如之后还有要加子元素的需求,也不需要再为其单独加事件监听了。
获取点击的li节点的内容

1
2
3
4
5
6
7
8
<ul id="parent-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>

1
2
3
4
5
6
7
8
9
10
11
var ul =document.getElementsByTagName("ul")[0];
ul.addEventListener('click',function(){
//兼容IE
event = event || window.event;
//IE使用srcElement,这里获取目标元素
var target = event.target || event.srcElement;
//对目标元素进行判定
if(target&&target.nodeName.toUpperCase()=="LI"){/*判断目标事件是否为li*/
alert(target.innerHTML);
}
},false);

jquery delegate函数

$(selector).delegate(childSelector,event,data,function)
delegate()方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。
使用delegate()方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素)。

事件的Event对象

当一个事件被触发的时候,会创建一个事件对象(Event Object),这个对象里面包含了一些有用的属性或者方法。事件对象会作为第一个参数,传递给我们的回调函数。

常用属性和方法

type(string): 事件的名称,比如 “click”。
target(node): 事件要触发的目标节点。
currentTarget(node): 它就指向正在处理事件的元素:这恰是我们需要的。很不幸的是微软模型中并没有相似的属性, 你也可以使用”this”关键字。事件属性也提供了一个值可供访问:event.currentTarget。
bubbles (boolean): 表明该事件是否是在冒泡阶段触发的。
preventDefault (function): 这个方法可以禁止一切默认的行为,例如点击 a 标签时,会打开一个新页面,如果为 a 标签监听事件 click 同时调用该方法,则不会打开新页面。
stopPropagation (function): 很多时候,我们触发某个元素,会顺带触发出它父级身上的事件,这有时候是我们不想要的,大多数我们想要的还是事件相互独立。所以我们可以选择阻止事件冒泡,使用event.stopPropagation().
stopImmediatePropagation (function): 与stopPropagation类似,就是阻止触发其他监听函数。但是与stopPropagation不同的是,它更加 “强力”,阻止除了目标之外的事件触发,甚至阻止针对同一个目标节点的相同事件。
cancelable (boolean): 这个属性表明该事件是否可以通过调用event.preventDefault方法来禁用默认行为。
eventPhase (number): 这个属性的数字表示当前事件触发在什么阶段。

  • 0: none
  • 1: 捕获
  • 2: 目标
  • 3: 冒泡
    pageXpageY (number): 这两个属性表示触发事件时,鼠标相对于页面的坐标。
    isTrusted (boolean): 表明该事件是浏览器触发(用户真实操作触发),还是 JavaScript代码触发的。

事件的回调函数

事件绑定函数时,该函数会以当前元素为作用域执行,所以回调函数中的this是当前的DOM元素。如果我们需要指定作用域,可以选择:

  • 使用匿名函数包裹回调函数
  • 使用bind方法

常用事件

load 资源加载完成时触发。这个资源可以是图片、CSS 文件、JS 文件、视频、documentwindow等等。
DOMContentLoaded DOM构建完毕的时候触发, jQuery的ready方法包裹的就是这个事件。
beforeunload 当浏览者在页面上的输入框输入一些内容时,未保存、误操作关掉网页可能会导致输入信息丢失。当浏览者输入信息但未保存时关掉网页,我们就可以开始监听这个事件,这时候试图关闭网页的时候,会弹窗阻止操作,点击确认之后才会关闭。当然,如果没有必要,就不要监听,不要以为使用它可以为你留住浏览者。
resize 当节点尺寸发生变化时,触发这个事件。通常用在window上,这样可以监听浏览器窗口的变化。通常用在复杂布局和响应式上。出于对性能的考虑,你可以使用函数throttle或者debounce技巧来进行优化,throttle方法大体思路就是在某一段时间内无论多次调用,只执行一次函数,到达时间就执行;debounce 方法大体思路就是在某一段时间内等待是否还会重复调用,如果不会再调用,就执行函数,如果还有重复调用,则不执行继续等待。
error 当我们加载资源失败或者加载成功但是只加载一部分而无法使用时,就会触发error事件,我们可以通过监听该事件来提示一个友好的报错或者进行其他处理。比如 JS 资源加载失败,则提示尝试刷新;图片资源加载失败,在图片下面提示图片加载失败等。该事件不会冒泡。因为子节点加载失败,并不意味着父节点加载失败,所以你的处理函数必须精确绑定到目标节点。

IE事件

1
2
3
element.attachEvent(<event-name>, <callback>);
event = event || window.event`
node = event.srcElement || event.target;

ES6

先记录一些内容:

  • Arrow Function
  • Let
  • Proxy
  • Destructuring
  • Tail Calling
  • Template Strings
  • Class
  • Promises
  • Generator

for…in…和for…of…

for……in……

遍历对象所有的可枚举对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var obj = {
'a': 1,
'b': 2,
'c': 3
};
Object.prototype.age = 24;
Object.defineProperty(obj, "school", {
configurable: true,
writable: true,
//枚举的属性
enumerable: true,
value: 'whut'
})
// var a = Object.keys(obj);
for (var index in obj) {
if (obj.hasOwnProperty(index)) {
console.log(obj[index]);
}
}

for……of……

CSS截断

单行截断

多行截断

参考文献