...
【2015.12.02-2016.02.22】期间的学习笔记。
相关博客:
1.
JS中的:
(1)continue 语句
(带有或不带标签引用)只能用在循环中。
(2)break 语句
(不带标签引用),只能用在循环或 switch 中。
(通过标签引用),break 语句可用于跳出任何 JavaScript 代码块:
===============================================================================
2.
JavaScript 是面向对象的语言,但 JavaScript 不使用类。
在 JavaScript 中,不会创建类,也不会通过类来创建对象(就像在其他面向对象的语言中那样)。
JavaScript 基于 prototype,而不是基于类的。
===============================================================================
3.
DOM 需要了解要删除的元素,以及它的父元素。
这里提供一个常用的解决方法:找到要删除的子元素,然后使用 parentNode 属性来查找其父元素:
var child=document.getElementById("p1");
child.parentNode.removeChild(child);
================================================================================
4.
onreadystatechange 事件被触发 5 次(0 - 4),对应着 readyState 的每个变化。
================================================================================
5. 闭包
在面向对象的程序设计语言里,比如Java和C++,要在对象内部封装一个私有变量,可以用private
修饰一个成员变量。
在没有class
机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量。我们用JavaScript创建一个计数器:
'use strict';
function create_counter(initial) {
var x = initial || 0;
return {
inc: function () {
x += 1;
return x;
}
}
}
它用起来像这样:
var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3
var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13
在返回的对象中,实现了一个闭包,该闭包携带了局部变量x
,并且,从外部代码根本无法访问到变量x
。
换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
================================================================================
6.
number
对象调用toString()
报SyntaxError:
123.toString(); // SyntaxError ,javascript的解析器的一个错误,它试图将点操作符解析为浮点数字面值的一部分
遇到这种情况,要特殊处理一下:
123..toString(); // '123', 注意是两个点!
(123).toString(); // '123'
================================================================================
7. 正则表达式
在正则表达式中,如果直接给出字符,就是精确匹配。用\d
可以匹配一个数字,\w
可以匹配一个字母或数字,所以:
'00\d'
可以匹配'007'
,但无法匹配'00A'
;'\d\d\d'
可以匹配'010'
;'\w\w'
可以匹配'js'
;
.
可以匹配任意字符,所以:
-
'js.'
可以匹配'jsp'
、'jss'
、'js!'
等等。
-
要匹配变长的字符,在正则表达式中,用*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示n-m个字符:
来看一个复杂的例子:\d{3}\s+\d{3,8}
。
我们来从左到右解读一下:
\d{3}
表示匹配3个数字,例如'010'
;\s
可以匹配一个空格(也包括Tab等空白符),所以\s+
表示至少有一个空格,例如匹配' '
,'\t\t'
等;\d{3,8}
表示3-8个数字,例如'1234567'
。
综合起来,上面的正则表达式可以匹配以任意个空格隔开的带区号的电话号码。
如果要匹配'010-12345'
这样的号码呢?由于'-'
是特殊字符,在正则表达式中,要用'\'
转义,所以,上面的正则是\d{3}\-\d{3,8}
。
但是,仍然无法匹配'010 - 12345'
,因为带有空格。所以我们需要更复杂的匹配方式。
进阶
要做更精确地匹配,可以用[]
表示范围,比如:
[0-9a-zA-Z\_]
可以匹配一个数字、字母或者下划线;[0-9a-zA-Z\_]+
可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100'
,'0_Z'
,'js2015'
等等;[a-zA-Z\_\$][0-9a-zA-Z\_\$]*
可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;[a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19}
更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
A|B
可以匹配A或B,所以[J|j]ava[S|s]cript
可以匹配'JavaScript'
、'Javascript'
、'javaScript'
或者'javascript'
。
^
表示行的开头,^\d
表示必须以数字开头。
$
表示行的结束,\d$
表示必须以数字结束。
你可能注意到了,js
也可以匹配'jsp'
,但是加上^js$
就变成了整行匹配,就只能匹配'js'
了。
=======================================================
8.
在函数的实现中:
修改arguments 的值会改变形参的值。
但是反过来则不行:修改形参的值并不会改变arguments 中的值。
在 strict 模式中,不能通过修改arguments 的值会改变形参的值。
=====================================================
9.
js中的代表对象的变量存储的是内存地址。
ECMAScript的函数调用中,所有参数的传递都是值传递(当传递的参数代表一个对象时,也仅仅是把实参存储的内存地址赋值给形参,还是值传递),不可能通过引用传递参数。
=====================================================
11.
js中的5种基本数据类型是按值访问的:Undifined, Null, Boolean, Number, String
js只能给引用类型的值动态地添加属性。
=====================================================
12. 不理解的地方
function creatPerson()
{
var localPerson = new Object();
localPerson.name = "mike";
return localPerson;
}
var globalPerson = creatPerson();
alert(globalPerson.name);
输出:mike
现在理解了。。
=====================================================
13.
<label> 标签为 input 元素定义标签(label)。
label 元素不会向用户呈现任何特殊的样式。不过,它为鼠标用户改善了可用性,因为如果用户点击 label 元素内的文本,则会切换到控件本身。
<label> 标签的 for 属性应该等于相关元素的 id 元素,以便将它们捆绑起来。
可以通过使用 "for" 属性将 label 绑定到另一个元素,或者直接在 label 元素内部放置元素。
属性 | 值 | 描述 |
---|---|---|
for | id | 规定 label 绑定到哪个表单元素。 |
form | formid | 规定 label 字段所属的一个或多个表单。 |
====================================================
14. ready事件
ready仅作用于document对象。由于ready事件在DOM完成初始化后触发,且只触发一次,所以非常适合用来写其他的初始化代码。
$(document).on('ready', function () {
//...
}); $(document).ready(function () {
//...
}); $(function () {
// init...
});
如果你遇到$(function () {...})的形式,牢记这是document对象的ready事件处理函数。
================================================
15. 用代码触发事件(以change事件为例)
有些时候,我们希望用代码触发change事件,可以直接调用无参数的change()方法来触发该事件:
var input = $('#test-input');
input.val('change it!');
input.change(); // 触发change事件
input.change()相当于input.trigger('change'),它是trigger()方法的简写。
为什么我们希望手动触发一个事件呢?如果不这么做,很多时候,我们就得写两份一模一样的代码。
==================================================
16. jQuery中的each函数
each() 方法规定为每个匹配元素规定运行的函数。
(提示:返回 false 可用于及早停止循环。)
语法:
$(selector).each(function(index,element))
其中:
index - 选择器的 index 位置
element - 当前的元素(也可使用 "this" 选择器)
===================================================
17. 针对表单元素,jQuery还有一组特殊的选择器:
:input:可以选择<input>,<textarea>,<select>和<button>;
:file:可以选择<input type="file">,和input[type=file]一样;
:checkbox:可以选择复选框,和input[type=checkbox]一样;
:radio:可以选择单选框,和input[type=radio]一样;
:focus:可以选择当前输入焦点的元素,例如把光标放到一个<input>上,用$('input:focus')就可以选出;
:checked:选择当前勾上的单选框和复选框,用这个选择器可以立刻获得用户选择的项目,如$('input[type=radio]:checked');
:enabled:可以选择可以正常输入的<input>、<select>等,也就是没有灰掉的输入;
:disabled:和:enabled正好相反,选择那些不能输入的。
此外,jQuery还有很多有用的选择器,例如,选出可见的或隐藏的元素:
$('div:visible'); // 所有可见的div
$('div:hidden'); // 所有隐藏的div
==================================================
18. jQuery能够绑定的事件主要包括:
鼠标事件
click: 鼠标单击时触发;
dblclick:鼠标双击时触发;
mouseenter:鼠标进入时触发;
mouseleave:鼠标移出时触发;
mousemove:鼠标在DOM内部移动时触发;
hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。
键盘事件
键盘事件仅作用在当前焦点的DOM上,通常是<input>和<textarea>。
keydown:键盘按下时触发;
keyup:键盘松开时触发;
keypress:按一次键后触发。
其他事件
focus:当DOM获得焦点时触发;
blur:当DOM失去焦点时触发;
change:当<input>、<select>或<textarea>的内容改变时触发;
submit:当<form>提交时触发;
ready:当页面被载入并且DOM树完成初始化后触发。
====================================
19. 对Promise的理解
// resolve 和 reject 这两个function类型的形参没有这样传进来:
// var p1 = new Promise(test(f1, f2));
// 而是分别在p1.then()和p1.catch()中传了进来:
// p1.then(f1(r));
// p1.catch(f2(reason)); var test = function (resolve, reject) { log('start new Promise...');
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () { if (timeOut < 1) { log('call resolve()...');
resolve('200 OK'); }
else { log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.'); } }, timeOut * 1000); } var p1 = new Promise(test); // 这里的两个匿名函数就分别是开头所说的f1和f2
p1.then(function (r) {
log('Done: ' + r);
}).catch(function (reason) {
log('Failed: ' + reason);
});
==============================
20. && 和 ||
(1) &&
(2) ||
============================================
21. 短路操作符的使用
$.fn.highlight2 = function (options) { // 要考虑到各种情况: // options为undefined // options只有部分key var bgcolor = options && options.backgroundColor || '#fffceb'; var color = options && options.color || '#d85030'; this.css('backgroundColor', bgcolor).css('color', color); return this; }
=============================================
22. 怎样写jQuery插件
$.fn.highlight = function (options) { // 合并默认值和用户设定值: var opts = $.extend({}, $.fn.highlight.defaults, options); this.css('backgroundColor', opts.backgroundColor).css('color', opts.color); return this; } // 设定默认值: $.fn.highlight.defaults = { color: '#d85030', backgroundColor: '#fff8de' }
用户使用时,只需一次性设定默认值:
$.fn.highlight.defaults.color = '#fff'; $.fn.highlight.defaults.backgroundColor = '#000';
然后就可以非常简单地调用highlight()了。
其中:
jQuery提供的辅助方法 $.extend(target, obj1, obj2, ...) ,
它把多个object对象的属性合并到第一个target对象中,遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高:
// 把默认值和用户传入的options合并到对象{}中并返回: var opts = $.extend({}, { backgroundColor: '#00a8e6', color: '#ffffff' }, options);
最终,我们得出编写一个jQuery插件的原则:
给$.fn绑定函数,实现插件的代码逻辑;
插件函数最后要return this;以支持链式调用;
插件函数要有默认值,绑定在$.fn.<pluginName>.defaults上;
用户在调用时可传入设定值以便覆盖默认值。
================================================
23. console.time() 和 console.timeEnd()
这两个方法用于计时,可以算出一个操作所花费的准确时间。
console.time("Array initialize");
var array= new Array(1000000);
for (var i = array.length - 1; i >= 0; i--) {
array[i] = new Object();
};
console.timeEnd("Array initialize");
// Array initialize: 1914.481ms
time方法表示计时开始,timeEnd方法表示计时结束。它们的参数是计时器的名称。调用timeEnd方法之后,console窗口会显示“计时器名称: 所耗费的时间”。
===============================================
24.
“DOM2级事件流”规定的事件流包括三个阶段:事件捕获阶段、事件处于目标阶段、事件冒泡阶段。
当一个事件发生以后,它会在不同的DOM节点之间传播(propagation)。这种传播分成三个阶段:
第一阶段:从window对象传导到目标节点,称为“捕获阶段”(capture phase)。
第二阶段:在目标节点上触发,称为“目标阶段”(target phase)。
第三阶段:从目标节点传导回window对象,称为“冒泡阶段”(bubbling phase)。
================================================
25. IE事件处理程序
IE实现了与DOM类似的两个方法:attachEvent()和detachEvent()。
这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。
由于IE只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。
在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。DOM0级事件处理程序会在其所属元素的作用域内运行;在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。在编写跨浏览器的代码时,牢记这一点区别非常重要。
attachEvent()也可以为一个元素添加多个事件处理程序,来看下面的例子:
var btn = document.getElementById("myBtn");
btn.attachEvent("onclick",function(){
alert("Clicked");
});
btn.attachEvent("onclick",function(){
alert("Hello World!");
});
与DOM方法不同的是,这些事件处理程序不是以添加它们的顺序执行,而是以相反的顺序被触发。单击这个例子中的按钮,首先看到的是“Hello World!”,然后才是“Clicked”。
================================================
26. addEventListener()和removeEventListener()
"DOM2级事件"定义了两个方法,用于处理指定和删除事件处理程序的操作:
addEventListener()和removeEventListener()。
所有DOM节点中都包含这两个方法,并且它们都接受三个参数:
要处理的事件名、作为事件处理程序的函数和一个布尔值。
最后这个布尔值如果是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。
===============================================
27.
f1.apply() 或者 f1.call() 的第一个参数是为了指定函数f1内的this指向谁。
对普通函数调用,我们通常把this绑定为null。
===============================================
28. base标签
为 页面上所有链接 规定 默认地址 和 默认打开方式
<base href="http://baidu.com" target="_blank">
===================================
29. <script>标签的async属性和defer属性
async:规定异步执行脚本(仅适用于外部脚本)
defer:规定是否对脚本执行进行延迟,直到页面加载为止
- 设置async,设置/不设置defer
脚本与页面并行解析。如果有多个脚本,执行属性也许跟它们在源代码中的顺序不一致,取决于哪个先加载完成
- 不设置async,设置defer
页面解析后执行脚本,脚本的执行顺序确定
- 不设置async和defer
遇到脚本立即执行,并且页面剩余的解析等待脚本完成执行
================================
30. 表单name
name属性规定表单名称,如果name="test",则Javascript可以使用document.forms.test来获取该表单
<form method="get" action="form.php" name="test"></form>
<script>
var oForm = document.forms.test;
console.log(oForm.method);//get
</script>
...