【前端】Web前端学习笔记【1】

时间:2021-07-14 11:01:23

...

【2015.12.02-2016.02.22】期间的学习笔记。

相关博客:

Web前端学习笔记【2】


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}

我们来从左到右解读一下:

    1. \d{3}表示匹配3个数字,例如'010'

    2. \s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' ''\t\t'等;

    3. \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) &&

【前端】Web前端学习笔记【1】

(2) ||

【前端】Web前端学习笔记【1】

============================================

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插件的原则:

    1. 给$.fn绑定函数,实现插件的代码逻辑;
    2. 插件函数最后要return this;以支持链式调用;
    3. 插件函数要有默认值,绑定在$.fn.<pluginName>.defaults上;
    4. 用户在调用时可传入设定值以便覆盖默认值。

================================================

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>

...