Table of Contents

jquery的bind和on绑定事件的区别

主要区别是:事件冒泡
jquery文档中bind和on函数绑定事件的用法:
.bind(events [,eventData], handler)
.on(events [,selector]  [,data], handler)

从文档中可以看出,.on方法比.bind方法多一个参数'selector'
.on的selector参数是筛选出调用.on方法的dom元素的指定子元素,如:
$('ul').on('click', 'li', function(){console.log('click');})
就是筛选出ul下的li给其绑定click事件;

 
那么这个selector参数的好处是什么?
好处在于.on方法
原理是事件冒泡,进行事件委托,子元素把事件委托给父元素进行事件处理;
这样的好处 
1.万一子元素非常多,给每个子元素都添加一个事件,会影响到性能;
2.为动态添加的元素也能绑上指定事件;

如:
$('ul li').on('click', function(){console.log('click');})的绑定方式和
$('ul li').bind('click', function(){console.log('click');})一样;
我通过js给ul添加了一个li:$('ul').append('<li>js new li<li>');');
这个新加的li是不会被绑上click事件的

但是我用$('ul').on('click', 'li', function(){console.log('click');}方式绑定,
然后动态添加li:$('ul').append('<li>js new li<li>');
这个新生成的li被绑上了click事件

JS时间线

1、创建Document对象,开始解析Web页面;此阶段document.readyState = 'loading';
2、遇到link外部css,创建线程加载,并继续解析文档;
3、遇到script外部js,并且没有设置async、defer,浏览器加载并阻塞,等待js加载完成并执行该脚本,继续解析文档;
4、遇到script外部js,并且设置有async、defer,浏览器创建线程,并继续解析文档;
5、遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档;
6、当文档解析完成,document.readyState = 'interactive';
7、文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意defer与async的区别,可见另一篇博客);
8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段;
9、当所有async的脚本加载完成并执行后,img等加载完成后,document.readyStste = 'complete',window对象触发load事件;
10、从此,以异步响应方式处理用户输入,网络事件等;

js基本语法

变量(variable) 
  申明,赋值分解
  单一var
命名规则
  1.变量名必须以英文字母,_, $开头
  2.变量名必须包括英文字母,_,$,数字
  3.不可以用系统的关键字,保留字作为变量名
  
原始值保存在stack(一级缓存,先进后出数据结构):Number Boolean String undefined null  
但是typeof(null) 返回object.

引用值保存在heap(二级缓存):array object function ... date, RegExp

运算操作符
 + :1 数学运算符,字符串连接符 2 任何数据类型加字符串都等于字符串
 -,*,/,%,=,() :  优先级"="最弱,() 优先级较高
 ++, --, +=, -=, /=, *=, %= 

 赋值的顺序:自右向左;计算的顺序:自左向右

1 被认定为false的值:undefined, null, NaN, "", 0, false;
2 typeof返回的6种类型:number, string, boolean, undefined, object, function
3 && 是 前面如果返回的false就直接返回前面的值,如果返回true就执行后面的语句(碰到false就停)
4 || 前面如果返回的true就直接返回前面的值,如果是false就执行后面的语句。(碰到true就停)

类型转换

显式类型转换:

一 typeof函数返回的6种类型: number, string, boolean, undefined, object, function



var data1= 123; console.log(typeof(data1));   //打印number;

var data2 = "123"; console.log(typeof(data2)); //打印string;

var data3 = true; console.log(typeof(data3)); //打印boolean;

var data4 = {}; // 或 [] 对象或者数组

console.log(typeof(data4)); //对象或数组都返回object

var data5 = null; console.log(typeof(data5));  //打印object; 

虽然null是原始值,但是返回的是object。这个比较特殊。

var data6; console.log(typeof(data6)); //打印undefined;

var data7 = function() {}; console.log(typeof(data7));

//打印function



另外: typeof(data)  效果和  typeof data 一样。可以用空格代替().



二 显式类型转换: Number(mix), parseInt(string, radix), parseFloat(string), toString(radix), String(mix), Boolean(mix).



Number() :把参数都转成数字, 经过这个函数返回的结果都是数字类型,如果不能转换,就返回NaN。(No a Number)

var num = Number("123aaa"); console.log(typeof(num) + ": " + num);

"123aaa" => number: NaN

"-123"  => number: -123

true => number: 1

null => number: 0

"" => number: 0

undefined => number: NaN (6种false的值,除了undefined 其他都能转成0

"adfs"  => number: NaN



parseInt() 转换成整型数字。parseInt会想尽办法给你转成整型,而Number() 千方百计给你弄成一个数字类型就好。侧重点不一样。

var num = parseInt("123aaa"); console.log(typeof(num) + ": " + num);

"123aaa" => number: 123  (这个比较特殊,以数字为开始看到非数字为截止,但开头必须是数字)

"aa123" => number: NaN

"sdfa" => number: NaN

"1234.98" => number: 1234   (直接舍去小数点)

1234.98 => number: 1234



var num = parseInt("10", 16); console.log(typeof(num) + ": " + num);

"10" => 16   (16进制的10 被转出来 就是16)。



String() 致力于把任何东西都转成字符串



Boolean() 把所有东西转成 boolean类型。



toString() 这个用法不一样。这是对象上的属性方法。所以 undefind和 null没有 toString()的方法。

var demo = 123; var num = demo.toString(8);

console.log(typeof(num) + ": " + num); //打印173 因10进制的123 转为8进制的173

隐式类型转换

isNaN(); 把参数先放到Number(); 拿到的结果和NaN比对,所以 isNaN("abc") 返回true, isNaN("123")返回false;
因为Number(null)返回0, Number(undefined) 返回NaN.所以。。isNaN(null)返回false, isNaN(undefined)返回true
++/-- +/- (一元正负) : 先调用Number()  所以结果都是 number类型。

+ (运算符)  只要两侧有一个类型是字符串它就调用String() 让所有都编程字符串
- * / %  先调用Number(); 
&& || !  先全部转成Number()来做判断,但是 && || 返回的值是原先的值。
< > <= >=    如果都是字符串,就转成asscii码比较,  
== !=   
=== !=== 这两个不发生类型转换

其中NaN特例: NaN == NaN 返回false
变量未定义直接使用,只有在typeof里面才不报错。
console.log(typeof(typeof(a))); a变量没定义,所以第一个返回string类型的undefined,然后在返回就是string.

JS的作用域精解

[[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,
这些属性仅供javascript引擎存取,[[scope]]就是其中一个。

[[scope]]值的就是我们所说的作用域,其中存储了运行期上下文的集合。

作用域链:[[scope]]中存储的执行期上下文对象的集合,这个集合呈链式链接,我们就把这种链式链接叫做 作用域

运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义为一个函数执行时的环境,
函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数可能导致的创建多个执行上下文,当函数执行完毕,
他所产生的执行上下文被销毁。

查找变量:从作用域链的顶端一次向下查找

立即执行函数

标准形式: (function() {} ());

还有一种形式: (function(){}())();

闭包

个人理解:当内部函数b被保存到外部时,就会形成闭包。本质是因为本函数a在执行完时,本来是会立刻销毁自己的执行期上下文即aAO,但是因为里面有一个函数在外面还要被其他人调用到。所以就不能销毁,此时内部函数b的执行上下文会指向函数a的AO. 这样就形成了一个闭包

当内部函数被保存到外部时,将会形成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。

闭包的作用:

  1. 实现公有变量,如函数累加器
  2. 可以做缓存(存储结构),如 eater
  3. 可以实现封装,属性私有化,如Person();
  4. 模块化开发,防止污染全局变量