JavaScript笔记

JavaScript笔记

Web 发展史:
  1. Mosaic:是全世界第一款可以显示图片的浏览器
  2. Netscape Navigator ->2003 firefox 浏览器
  3. IE6 ->IE6浏览器
  4. 2008 -> Chrome 浏览器
  • 关于浏览器的内核部分:
  1. 渲染引擎(语法规则和渲染)
  2. js引擎
  3. 其他模块
  • JavaScript的语言特点:

    1. 解释性语言 –(不需要编译成文件)跨平台
    2. 单线程
    3. ECMA标注 ECMAscript
  • JavaScript执行队列:
    执行片段A1->执行片段A2->执行片段A3 (争抢时间片)

  • 主流浏览器及其内核:
    主流浏览器 内核
    IE trident
    Chrome wekit/blink
    firefox grcko
    Opera presto
    Safari webkit
  • 引入javascript的两种方式
    1
    2
    1.<script></script>
    2.<script src='.js'></script>

js变量名的命名规则

  1. 变量名必须以英语字母 ,_ ,$开头。
  2. 变量名里面可以包括英文字母,_还有$.
  3. 不可以用系统的关键字还有保留字作为变量名。
JavaScript基本语法:

数据类型分为原始值还有引用值

  1. ==原始值有:number , boolean , String ,undefinded ,null==
  2. ==引用值有:array ,object ,funciton ,date ,regexp==
  • 几个注意点:
  1. ==javascript对象才能拥有方法,然而number,String,boolean也可以拥有自己的方法,null和underfind是无法拥有方法的值。==
  2. 对象和数组属于可变类型,javascript程序可以更改对象属性值和数组元素的值。
  3. 数字,布尔值、null,和undefined属于不可变类型。
  4. ==原始值和引用值的区别在于,原始值存在于stack(栈)当中,规则是先进去的最后出来。
    而引用值是存在heap(堆)里面的 ,引用值拷贝的是地址。==

String的方法:
在javascript权威指南中,笔者列举出了许多字符串可调用的方法。

运算符:
1
2
3
4
5
+ - * /
不过特别要注意的是,任何“+”碰到字符串,都会变成字符串连接符。

1 / 0 --> Infinity = Number;
0 / 0 --> Nan
比较运算符:

字符串的比较是ASCII码数值的比较。

1
Infinity == Infinity	undefind == undenfind

特别注意的是 NaN!= NaN无穷大除以无穷大,给人以负数作开方运算或者算术云算法不是数字或无法转换为数字的操作数一起使用时都将返回NaN

逻辑运算符

1
&& 	|| 	!
  • 与运算符&&,在运算中,undefind ,null ,Nan ,” “ ,0 ,flase ,会转换成false . &&操作符碰到false就返回这个值
1
2
3
4
var a =1 && 2 ==> 2
var a = undefined && 2 ==> undefined
var a = NaN && undefined ==> NaN
var a = 1 && undefined ==> undefined
或运算符
1
2
||
或运算符中,找一个真的,然后返回。如果两个值都为假,那就返回第二个值。
在运算中,寻找一个真值,第一个为真则直接返回第一个值。若第一个为假,而又只有两个值,则返回第二个值,无论真假。
1
2
3
4
5
左移(<<)
将一个值左移相当于它乘以2,7<<2 = 28

右移(>>)
将一个值右移相当于它除以2, 7>>1=3 ,-7>>1=-4
条件语句:
1
2
3
if(条件){

}
1
2
3
4
5
6
7
2. switch(1){

case(1):
console.log('a');
break; //switch这种选择语句,遇到合适条件的case才会执行,而却会把全部的case看一遍,如果在只有一种
//条件下的case,则可以用break;停止运行。减少资源浪费。
}
对象
1
2
3
4
对象:
var obj ={
属性名 :"属性值"
}

typeof可以判别的值有:number,String,boolean ,object,undefined,function;这6种。
而typeof 在辨别null 和 Array 的时候一律返回object 。

类型转换:
显示类型转换:
  1. var num = Number(‘123’) –> 123
    注意:
    undefined ->Number() –> NaN

    null –> Number(null) –> 0

    ‘123abc’ –> Number() –> NaN

  2. parseInt(‘10’ ,16)
    可以把任何东西转换成整形,而且可以进行10进制,16进制的转换。
    parseInt(‘123abc’) –> 123
    parseInt(null) –> NaN
    parseInt(undefined) –> NaN

  3. parsefloat
    把数据转换成浮点类型。“123abc”可以识别数字并返回。

  4. boolean:会把underfined ,null ,0 ,-0 ,NaN ,”” 转换成false。

  5. toString: 将返回一个表示调用这个方法的对象值的字符串。

隐式类型转换:
1
2
3
4
5
1.isNan()
机制就是Number()进行转换成数字,然后再判断是不是
2.+ ->String类型
3. - * / % ->number类型
4. == !=
隐式类型转换:
  1. 减号,乘号,除号,取模等操作会尝试将他们所操作转换为数字Number,如果没办法转换成数字,结果就是NaN
  2. 大于,小于,大于等于,小于等于,跟上面一样。
  3. 字符串遇上+号就进行隐式类型转换,变成字符串类型。没有字符串的情况下则不发生转换。
1
==  !=
  1. 字符串 op 字符串,不会进行类型转换,直接比较;
  2. 对象op对象,引用都指向同一个对象才为true
  3. typeOf !! 会转换成Boolean类型
1
2
Boolean(Nan) == false;
null == undefinded // true
不发生类型转换:
1
2
3
4
5
6
7
===			//绝对相等
如果两个值为数字且数值相等,则它们相等。如果一个数值为0,另一个数值为-0,则它们同样相等。
!== //绝对不相等
!==也可以用来判断一个属性书否是underfind
var o = {x : 1}
o.x !== underfind //true o中有属性x
o.y !== underfind //false o中没有属性y

==typeof(typeof(number)) —>最后其实类型是String ,因为第一个typeof是返回的是String类型。==

函数:
  1. 函数表达分为命名表达式还有匿名函数表达式。
  2. 命名表达式:function text(){ }
    text(); ->调用
  3. 匿名表达式: var text :function() {}
形参与实参:
  1. 形参text(a,b) ==text.length== 可以知道形参的数量。
  2. 实参text(1,2)。==arguments.length== 可以知道实参的长度。
  • 形参出生是多少个就是多少个,以后不会再往后加了。

return:
使程序停止执行;
返回值

递归:

  1. 符合人的逻辑思维过程
  2. 递归一定要有递归出口
javascript预编译:
要点:
  1. 函数声明整体提升
  2. 变量声明提升
操作:
  1. imply global 暗示全局变量:即任何变量,如果变量未经声明就直接赋值,该变量为全局对象变量。
  2. 一切声明的全局变量,都是window的属性。即可以通过window调用。
javascript全局函数

escape(),eval_r() isFinite isNan() paresFloat() paresInt() unescape() 七个

预编译的四部曲(局部):(重要)
  1. 创建AO(执行期上下文)

  2. 找形参和变量声明。将变量和形参作为AO属性名,值为underfined。

  3. 将实参值和形参值统一。

  4. 在函数体里面找函数声明,值赋予函数体,->

    1
    function(){}

    这种–优先级最高,function会覆盖之前变量的值。

==注意:fcuntion a() {}这种叫函数表达式才算funciton, 在预编译里==

1
var b =function (){}

==这种,因为还没有执行,所以不算function(){}==

全局的预编译
  1. 创建GO

——————-(其余步骤相等)

==在预编译的规则中,先生成GO ,再生成AO。==

作用域

[[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不行,这些对象仅供js引擎存取,[[scope]]就是其中一个。==其存储了运行上下文的集合==。

作用域链:

[[scope]]中所存储的执行器上下文对象的集合,集合呈链式连接。 ==作用域上的作用域,生成的AO都是同一份。并且在每个作用域上修改的值,如果自己有就修改自己的值。

==查找变量:从作用域的顶端依次向下查找,而AO在GO的顶端。==

闭包:

==但凡是内部函数被保存到了外部,就一定会生成闭包。==

缺点:当内部函数被保存到外部时,将会生成闭包。闭包会导致原有的作用域链不释放,造成内存泄露(像内存泄露,只是说内存被占用)

闭包的作用:

  1. 实现公有变量。
    例如说做一个函数累加器。
    1
    2
    3
    4
    function a (count){
    count ++;
    return count;
    }
  2. 可以做缓存(存储结构)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    属性:键 -- 值
    方法: 设置缓存 setCache
    缓存的获取 getCache

    function configCache(){
    var obj = {};
    return {
    setCache : function (k ,v){
    obj[k] = v ;
    },
    getCache : function (k){
    return [k];
    }
    }
    }
  3. 可以实现封装,属性私有化
  4. 模块化开发,放置污染全局变量

闭包的例题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function test(){
var num = 100;
function a () {
num ++;
console.log(num);
};
function b (){
num -- ;
console.log(num)
};
return [a,b];

}
var myarr = test();
myArr[0]();
myArr[1]();
//这里打印的事101 100 ,在test函数执行完成后,test函数生成的AO作用域
,test砍掉与其AO的连线,但retrun[a,b]把结果保存了出来,既函数a b依然使用连着test的AO,而且是同一份变量。因此改变同一份值。
立即执行函数:

(也有执行器上下文,也需要预编译)

1
(function() {} ()) 执行之后就立即被销毁。
1
2
3
传递参数:(function(a,b,c)){
console.log(a+b+c);
}(1,2,3)
  • 注意:只有表达式才能被执行符号执行(执行符号就是()),利用立即执行函数把内部数据传到外部,也用于数据的初始化;
    ‘ , ’逗号可以把后面的值返回;
对象:

所有的对象继承了两个转换方法,第一个是toString(),它的作用是返回一个反应这个对象的字符串。

  • toSting
    1. 数组类继承的toString()可以将每一个数组元素转换成一个字符串,并在元素之间添加都好并合并成结果字符串
    2. 函数类的toString()可以返回这个函数的实现定义的标识方式。
    3. 日期类的toString可以返回一个可读的日期和时间字符串。
    4. RegExp类定义的toString()方法将RegExp对象转换成表达正则表达式直接量的字符串

另外一个方法是ValueOf()。如果存在任意原始值,它就默认将对象转换为表示它的原始值。

this

this :代表在某一对象里面的第一人称,例如this.health

  1. 函数预编译过程 this -> window

  2. 全局作用域里 this -> window

  3. call/apply 可以改变函数运行时的this 指向

  4. obj.func(); func里面this指向 obj
    在对象内部的增删改查。

    this指向只有在最终代码执行的时候才能知道指向谁

  5. new 调用时指的是被构造的对象

  6. call、apply调用,指向我们指定的对象

  7. 对象调用,如执行obj.b(),this指向obj

  8. 默认的,指向全局变量window(相当于执行window.fun())

1
this.wife='FengZe' ,即在这里直接进行添加和修改。
1
删除:delete xx.name;
对象创建方法;
  1. var obj = {} 对象字面量/对象直接量。

  2. 通过构造函数创建:

    1. 系统自带构造函数 var obj = new object();
      构造函数要用大驼峰式方法来写:TheFirstName
      构造函数的内部原理:(一定要有new,不然就不是构造函数了)
    2. 在函数体最前面隐式加上this ={}
    3. 执行this.xxx=xxx;
    4. 隐式返回this
构造函数的内部原理
  1. 在函数体前隐式的执行 this = {}
  2. 执行 this.xxx = xxxx
  3. 隐式的返回 this
包装类:

==原始值是坚决不能有方法的,如果能赋予属性,则是因为经历的包装类==

new String();

new Boolean();

new Number();

null 和 undefined 不能有属性

对象创建方法:
  1. 对象字面量

    1
    2
    3
    4
    5
    6
    7
    8
    var obj ={			//对象字面量、对象直接量
    name : "FengZe",
    sex : "male",
    wfie : "xingyu",
    smoke : function () {
    console.log('i am smoking !");
    }
    }
  2. 构造函数:

    1. 系统自带的构造函数 object –> var obj = new object();
  • ==注意:构造函数要用大驼峰式的方法来写: TheFirstName这种==
  1. 自定义
1
2
3
function xx(){

}
构造函数的内部原理

(一定要用new ,不然就不是构造函数了)

  1. 在函数体最前面隐式加入this = {}
  2. 执行this.xxx=xxx;
  3. 隐式地返回this;

包装类:
new String();
new Boolean ();
new Number ();

原型:
  1. 定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的睡醒和方法。原型也是对象。

  2. 利用原理,可以提取共有属性。

  3. 独享通过隐式属性查看原型–>

    1
    __proto__
  4. 通过constructor 查看对象的构造函数。

例子:如果生产一种汽车,而这种汽车大部分是相同的,而小部分作为选配部分,可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Car (owner,power){
this.owner = owner,
this.power = power
}

Car.prototype = {
name :'BMW',
tite :18,
run : function (){
console.log("i am running ");
}
}

var car1 = new Car('feng','900');


delete.Car.name ,这样就可以删除了Car.prototype里面的属性了。
原型链:
1
2
Crand.protype.__prtot__ = object.prototype -->是所有对象的最终原型。
var obj = object.create("原型")

当继承的对象son 已经new出来后,再修改原型链就无效了。

1
2
例: var person = Object.create(Person.prototype)
是绝大多数对象最终都会继承自object.prototpype, 大也有例外的,例如说object.create(null)
call/apply

call /apply 作用是转移this指向

  1. 借用别人的函数实现自己的功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Person.call(obj);
//call需要把实参按照形参个数传进去,而apply需要传输一个arguments 区别在于传参列表不同。

function Person(){
this.name = name;
this.sex = sxe;
this.age = age;
}

function Student(){
Persion.call(this,name,sex,age);
this.grade = grade;
this.tel = tel;
}
继承 extend
继承的发展史:
  1. 传统形式 ->原型链 缺点:过多继承了没用的属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    function Father(){
    this.name = 'Father';
    }

    Son.prototype = Father
    function Son(){

    }
    var son = new Son();
  2. 借用构造函数 (借用别人的构造函数)

    缺点:

    1. 不能继承借用构造函数的原型。
    2. 每次构造函数都要执行多个方法。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      function Person(name,age){
      this.name = name;
      this.age = age;
      }

      function Student(name,age,sex,grade){
      Person.call(this.name,age,sex);
      this.grade = grade;

      }

      var student = new Student();
  3. 共享原型(共用一个原型链)
    缺点:

    1. 不能随便改动自己的原型,因为他们拥有同一个原型。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      Father.prototype.name = 'He';
      function Father(){

      }
      function Son(){

      }
      Son.prototype = Father.prototype;
      var son = new Son();
  4. 圣杯模式

1
2
3
4
5
6
//函数F是一个中间层
function F(){
F.prototype = Father.prototype;
son.prototype = new F();
son.prototype.constuctor = son;
}
命名空间:

管理变量,能防止污染全局,适用于模块化开发

属性拼接问题:
1
2
3
function (num){
return this['name' + num];
} //输入num 得出num1的效果
对象的枚举:

(遍历和枚举)

1
2
3
4
1. for()
2. for(var prop in obj){

}

当遍历不知道对象的数量多少的时候,可以用for in循环解决问题

  1. [hasOwnProperty]obj.hasOwnProperty(), 用来判断属性是不是自己的,是不是从原型链上拿过来的。

  2. in 属性只能用来能不能访问到这个属性
    in运算符希望它的左操作数是一个字符串或可以转换成字符串,希望它的右操作数是一个对象。如果右侧的对象拥有一个名为左操作数的属性名则返回true.

1
2
3
4

'height' in obj

var point = {x:1 ,y:1} 'x' in point -->true
  1. A instanceof B
    可以看A对象是不是从B的构造函数,构造出来的。Object ==可以看A对象的原型链上有没有B的原型==。
    instanceof 运算符希望左操作数是一个对象,右操作数标识对象的类。如果左侧对象是右侧对象的实例则返回true
1
2
3
var d  = new Data();
d instanceof Data; //true,d是由Data() 创建的
d instanceof Number; // false ,d不是由Number创建的。
1
2
[] instanceof Array ->true
Object ->true

toString方法:
toString() 方法可把一个逻辑值转换为字符串,并返回结果。

1
2
object.prototype.toString.call([]);  ---> [Object Array]
object.prototype.toString = function (){}
克隆:
浅层克隆,深层克隆。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//浅层克隆
var obj = {
name:'Feng',
wight:"60"
}

var obj1 = {}


function shallowclone(origin, target){
var target = target || {};
for(var prop in origin){
target[prop] = origin[prop];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//deepclone 深层克隆
var obj = {
name: "feng",
sex: 'male',
wife: {
name: "fish"
}
}

var obj1 = {};

function deepClone(Origin, Target) {
var Target = Target || {},
toStr = Object.prototype.toString,
arrStr = '[object Array]';
for(var prop in Origin){
if(typeof(Origin[prop]) == 'object'){
if(toStr.call(Origin[prop]) == arrStr){
Target[prop] = [];
}else{
Target[prop] = Origin[prop];
}
deepClone(Origin[prop],Target[prop]);
}
else{
Target[prop] = Origin[prop];
}
}
}

deepClone(obj,obj1);
  • 对象序列化指的是对象的状态转换为字符串,也可以将字符串还原为对象。ECMAScript5提供了JSON.stringify()和 json.parse()用来序列化和还原js对象。但注意函数,RegExp,Error和underfind不能序列化和还原。
1
2
3
o = {x : 1 , y:{z : [false , null ,'']}  };
s = JSON.stringify() // s = {x : 1 , y:{z : [false , null ,'']} }
p = JSON.parse() //p是o的深拷贝
三目运算符:

问号前面放判断语句,如果结果为真则执行冒号前面的语句,否则指定冒号后面的语句

1
2
?:
例:1>0? 2:1 如果1大于0 则选择2,否则选择1。
数组:
  1. 数组的第一个元素索引为0,最大可能索引为2 32(2的32次方) -2。
  2. JavaScript数组是动态的,根据需要变长变短。数组都有一个length属性。
1
2
var arr = []; 	数组字面量;
var arr = new Array();

可以传参数,但如果只写一个数会认为这是数组的长度。

  • 数组继承了默认的Value0f()方法,这个返回一个对象而不是一个原始值,因此,数组到数字的转换则调用toString方法。空数组转换成为空字符串,空字符串转换成数字0。
常用的方法:
  • 改变原数组: push ,pop,shift ,unshift,sort,reverse ,splice

  • 不改变原数组:concat ,join, split, toString ,slice

  1. push()–在数组的==最后一位添加数据,并返回最后的长度==
    1
    2
    3
    4
    5
    6
    Array.prototype.push = function(){
    for(var i = 0 ; i < arguments.length; i++ ){
    this[this.length] = arguments[i];
    }
    return this.length;
    }
  2. pop ()–把数组的最后一位剪切出来,并返回最后一位的长度
  3. unshift()–在数组前面添加数据,并可以通过传参添加多个数据,
  4. shift() 在数组前面减
  5. reverse() 数组颠倒
  6. splice()
    1
    2
    3
    4
    5
    arr.splice (从第几位开始 , 截取多少的长度  ,在切口处添加的新数据)

    var arr = [1, 2, 3];
    arr.splice(0,2,4);
    console.log(arr); // [4,3]
  7. sort()给数组排序,但这个是用ASII码排序的,因为有时候会不尽人意。也可以自行添加函数。

如何优化sort()方法进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//步骤
function sort(a , b){
if(a - b > 0){
return 1; // a 与 b 的位置发生转换
}else{
return -1; // a 与 b 的位置不发生转换
}
}

-->
a - b > 0 --> 可以写成 a > b

return 1 或 -1 可以写成 return a - b

a - b 是升序, b - a 是降序

如何给数组乱序:

1
2
3
4
5
  var arr = [5, 2, 7, 1, 9];
arr.sort(function () {
return Math.random() - 0.5;
});
console.log(arr);
  • 不改变原数组:
  1. concat :拼接数组,并且不影响前面的数组,也不会排序
  2. toString :把数组变成字符串
  3. slice() 从该位开始截取,截取到该位
    1
    2
    var arr = [1,2,3];
    arr.slice(1 ,3) --> [2,3]
  4. join() 要字符串,然后用字符串连接
    1
    2
    var arr = [1,2,3];
    var a = arr.join('-') --> [1-2-3]
  5. split () 用” xxx “来拆分数组。
    1
    2
    3
    4
    var arr = [1,2,3];
    var a = arr.join('-') --> [1-2-3]

    var b = a.split('-') --> ["1","2","3"]
类数组:

类数组不是数组,当然没有数组的方法。
构成要素:属性为索引,必须要有length 属性,最好有push方法
==类数组的好处是把数组和对象的属性都拼接在一起==

优点:类数组的关键点在于length

1
2
3
4
Array.prototype.push = function(target){
obj [obj.lenght] = target
obj.length++;
}

如此来实现push方法。

arguments.callee
  1. arguments.callee包含了一个函数的引用去创建arguments对象,它能让一个匿名函数方便指向本身。例如计算阶乘
    1
    2
    3
    4
    5
    6
    var num  =(function (n){
    if(n == 1){
    retrun 1;
    }
    return n * arguments.callee(n - 1);
    })
  2. arguments.caller()
    1
    2


try…catch

不影响try catch 下一块代执行,但不会执行try块里面的那行代码

几种常见错误类型:

1
2
3
4
5
6
7
Error:有6种错误信息
EvalError
RangeError ;数值越界
ReferenceError :非法或不识别的引用
SyntaxError :语法错误
TypeError :操作的类型错误
urIError:uri不当
es5严格模式

(即es3.0与es5.0冲突的部分使用es5.0的解决办法)

浏览器基于es3.0+es5.0的新增方法
“use strict”; 开启严格模式(并且要在代码的第一行来写)

  1. 在es5严格模式中,不允许使用argument.callee ,with{} caller 并且变量赋值前必须声明,局部里面的this一定要被赋值,拒绝重复的属性。
  2. 可以设置全局严格模式和函数内部严格模式(推荐)
在严格模式下有以下几种要求:
  1. 禁止使用with 语句
  2. 创设eval 作用域
  3. 禁止this关键字指向全局对象
  4. 禁止在函数内部遍历调用栈
  5. 禁止删除变量,只有configurable
  6. 设置为true的对象属性才能被删除。
  7. 变量必须声明
重名报错
  1. arguments对象的限制
    不允许对arguments赋值
  2. arguments不再追踪参数的变化
    禁止使用arguments.callee
DOM (Document Obect Model)
  • DOM定义了表示和修改文档的方法,DOM对象即为宿主对象。由浏览器厂商定义,用来操作html 和xml 。
  • DOM树中总共分成以下4种节点:Element(元素),Text类型(文本节点),Comment类型(注释节点),Document类型(document节点)
    1
    var div = document.getElementsByTagName('div')[0];  //后面这个0一定要选中。
数组去重方法:
1
2
3
4
5
6
7
8
9
10
11
Array.prototype.unique = function() {
var temp = {};
var arr = [];
var len = this.length;
for (var i = 0; i < this.length ; i++){
if(!temp[this[i]]){
temp[this[i]] = 'abc';
arr.push(this[i]);
}
}
}
DOM的基本操作:
  1. 对节点的增删改查:
    1. 查看元素节点:
      1. document.getElementById()
      2. document.getElementsByTagName()
      3. document.getElementsByClassName()
      4. document.getElementsByName()
    2. 增加元素节点:
      1. createElement
      2. createTextNode
      3. cloneNode
      4. createDocumentFragment
    3. 增加节点
DOM选择器:
1
doucument.getElementById() //元素ID在IE8 一下浏览器是不区分大小写的,而且也返回匹配name 属性的元素;就是说写name可以当成id选择器(ie 8浏览器以下可以)
  1. getElementsByTagName() //标签名
  2. getElemehtsByName() //只有部分标签name可生效(表单,表 ,img ,iframe)
  3. getElementsByClassName() 在IE8 及以下的版本中不使用方法。
  4. .querySelector() //css选择器,在ie7级以下的版本中没有
    1
    var a = document.querySelector('#a > span > p')
  5. .querySelectorAll() //css选择器,在ie7 及以下的版本中没有 选一组
    ==不过querySelector选出来的只是之前的副本,并不是实时性的==

==document 代表整个文档,html只是文档里面的跟标签。==

遍历节点树:

(遍历的是节点,有文本节点,元素节点等等等等)

  1. parentNode ->父节点 (最顶端的parentNode 是#document;)
  2. childNodes ->子节点
  3. firstChild –>第一个子节点
  4. lstChild –>最后一个子节点
  5. nextSibling ->后一个兄弟节点
    previousSiling ->前一个兄弟节点
遍历元素节点数:

(这个是访问元素节点,比较正常)

  1. parentElement ->返回当前元素的父元素节点(IE不兼容)
  2. children ->只返回当前元素的元素子节点
  3. firstElementChild –> 返回的第一个元素节点
  4. lastElemeentChild –> 返回的最后一个元素节点
  5. nextElementSibling / previousElementSibling 返回后一个兄弟元素节点 / 返回前一个兄弟元素节点
1
node.childElementCount === node.children.length
节点类型:
元素节点 --1
属性节点 --2
文本节点 --3
注释节点 --8
doucument --9
DocumentFragment --11

节点的四个属性:

  1. nodeName //只能读取,不能写入。
  2. nodeValue //text(文本)节点或comment(注释)节点的文本内容,可读写。
  3. nodeType //该节点的类型 只读 判断元素是啥。
  4. attributes // element 节点的属性集合

节点的一个方法:
node.hasChildNodes();

DOM结构树:
Document是系统的函数,只能系统自己调用。

==getElementByTagName () 方法定义在Document.prototype 和Element.prototypes上==

增:

1
2
3
4
var div = document.getElementsTagNmae(‘div’) ;
document.createTextNode();
document.createComment();
document.createDocumentFragment();

插:

1
2
PARENTNODE.appendChild();
PARENTNODE.insertBefore(a,b) // 插入A在插入B之前

删:

1
2
parent.removeChild();
child.remove();

替换:

1
parent.replaceChild(new,origin)
Element节点的一些属性:
1
2
3
4
5
innerHTML
innerText (火狐不兼容) /textContent (老版本IE不好使)
Element节点
ele.setAttribute('id' ,'only')
ele.getAttribute('id')
实例:在页面中插入一句话,并设置类名
1
2
3
4
5
6
7
8
9
var div = document.createElement('div');
var p = document.createEelement('p');
var text = document.createTextNode('泽丰,最帅');
div.setAttribute('class','example');
div.setAttribute('id','handsome');
p.setAttribute('class','rico');
p.appendChild(text);
div.appendChild(p);
document.body.appendChild(div);
Date 对象方法:
  1. 获取时间的方法
    1. getDate()
    2. getDay()
    3. getFullYear()
    4. getMonth()
    5. getHour()
    6. getMinutes()
    7. getSeconds()
    8. getTime()
  1. Interval:
    定时器:但定时器是非常不准的。

  2. setInterval: 定时器

  3. clearInterval:清理计时器

5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  //实现一个三分钟的定时器
var minuteNode = document.getElementsByTagName('input')[0];
var secondNode = document.getElementsByTagName('input')[1];

var minute = 0;
var second = 0;


var timer = setInterval(function (min) {
second++;
if (second > 59) {
second = 0;
minute++;
}

minuteNode.value = minute;
secondNode.value = second;

if (minute == 3) {
clearTimeout(timer);
alert("时间到");
}
}, 1000)
DOM基本操作:

查看滚动条的滚动距离:

1
window.pageXOffsize YOffsize

==IE8及IE8以下不兼容==

查看视口的尺寸:

1
window.innerWidth /inner.Height
  • 标准模式 /怪异模式也叫混杂模式(向后兼容),可在浏览器查document.compatMode,如果是CSS1Compat则是标准模式,如果是BackCompat则是向后兼容。
    clintHeight / clientHeight
查看元素的几何尺寸:
1
domEle.getBoundingClientRect();

兼容性很好
该方法返回不是实时的;

查看元素尺寸:

1
dom.offsetWidth  dom.offsetHeight

//求的是视觉上的尺寸,当然不包含margin

查看元素的位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dom.offsetLeft  dom.offsetTop
//封装一个方法查看位置的方法
function getScrollOffset() {
if (window.pageXOffset) {
return {
x: window.pageXOffset,
y: window.pageYOffset
}
}
else {
return {
x: document.body.scrollLeft + document.documentElement.scrollLeft,
y: document.body.scrollTop + document.documentElement.scrollTop
}
}
}
1
dom.offsetParent

//查看父级的。能求有定位的父级。

让滚动条滚动:

window上的三个方法:

1
2
3
scroll()
scrollTo() 这两个方法是一样的,滚动到某一个位置
scroolBy() 累加滚动距离

阅读器小demo ,就是reader.js

脚本化CSS(DOM控制CSS)
  1. 可读写行间样式,没有兼容性问题,遇到float这样的保留字属性,前面应加css
    1
    2
    3
    4
    5
    6
    abc.style.width = '200px';
    //这个200px写在行间样式是可以读得到的
    //但没法读取在head里写的style样式的width


    div.style.float == div.style.cssfloat
  2. 复合属性必须拆解(borderWidth,borderHeight,borderradius),组合单词变成小驼峰式写法;
    写入的值必须是字符串格式
查询计算样式:
1
2
3
window.getComputedStyle(ele,null);

var elem = window.getComputedStyle(abc,null);

看到权重最高的,所以这个最准确。这个也不能改样式。
计算样式只读

返回的计算样式的值都是绝对值,没有相对单位
ie8及以下不兼容
ie8及以下使用这种方法 ele.currentStyle(div, null)

1
2
3
4
5
6
7
8
9
//封装一个getStyle()方法,解决兼容性问题
function getStyle(elem , prop){
if(window.getComputedStyle){
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}

}

查询样式:
div.currentStyle–> CSSStyleeclaration

事件:
事件的绑定:
1
2
ele.onXXX= function(event ){}  		//程序this指向是dom元素本身
特点:兼容性很好,但是一个元素的同一事件上只能绑定一个处理程序,基本等同于写在HTML行间上
1
2
3
4
5
obj.addEventListeber(type, fn,flase);	//程序this指向是dom元素本身
ie9 以下不兼容,可以为一个时间绑定多个处理程序

obj.attachEvent('on'+type ,fn) //程序this指向window
IE独有,一个时间同样可以绑定多个处理程序

绑定事件,当事件在循环里面,就一定要考虑要不要使用闭包。

事件处理程序

解除事件:

1
2
3
4
ele.onclick = false /null
ele.removeEventListener(type,fn ,false)
ele.detachEvent('on' +type ,fn);
若绑定匿名函数,则无法解除
事件处理模型——事件冒泡,捕获

结构上嵌套关系的元素,会存在事件冒泡的功能。

事件捕获:
只有chrome上可以用

把flase 变成ture,从结构的最外面向里面进行捕获.

  • 一个对象的一个事件,绑定两个函数,分别是冒泡还有捕获。执行的顺序是先触发顺序,先捕获,后冒泡。

==focus, blur , change submit reset ,select 等事件不冒泡==

取消冒泡:

W3C标准event.stopP

阻止默认事件:
  1. 默认事件——表单提交,a标签跳转,右键菜单等
    return false; 以对象属性的方式注册的时间才有效
1
event.preventDefault() IE9以下不兼容
事件对象:

event ||window.event 用于IE

事件源对象:
  1. event.target 火狐只有这个
  2. event.srcElement ie只有这个
  3. chorm 全都有
  4. div.box就是事件源对象
事件分类:

键盘类事件:

  1. Json就是为了传输数据:
    1. 以xml这种语言传输数据,xml相对于html比较随性,可以自定义标签。
    2. 规定json 属性名要加双引号,json传输的时候其实传输的是字符串。
1
2
JSON.stringify() --->把数据传输给后台   json ->string
JSON.parse() ---->后台把数据传输给前台,string -json
1
domtree + csstree = randerTree

==尽量减少dom节点的增加或者删除,以优化性能
reflow 是效率最低的。dom节点的宽高变化==,

1
2
例如说display none--->block
offsetWidth offsetLeft
repanint 重绘

效率相对没有这么低,是可以接受的

异步加载js:

加载工具方法没必要阻塞文档。

三种方法异步加载js:

  1. defer = “defer” 这个就是异步加载的js了。只有IE能够用。要等到dom文档全部解析完之后才会被执行
  2. async 异步加载。 async = “async” 也可以实现异步加载。W3C方法。加载完就执行。asynv只能加载外部脚本
  3. 创建script,插入DOM,可以按顺序执行。
  • 使用onload方法,可以让所有资源加载完之后立即执行,除了IE都兼容。
1
2
3
4
5
6
IE 使用onreadystatechange() 方法

$(document).ready(function () {
}) //这种是当DOM解析完就执行的部分

与window.onload 方法之间的区别。 onload是最低的写法
JS时间线
BOM

定义borwser Object Model

定义了操作浏览器的接口

BOM对象:

Window ,History ,Navigator Screen,Location

由于浏览器不同,Bom对象的兼容性很低,一般情况只用部分功能。

1
2
3
转义字符:“\”  写到字符串里面,会把反斜杠后面的字符转义成正常文本
多行字符串
字符串换行符 \n
正则表达式:

匹配特殊字符或特殊搭配原则的字符的最佳选择
———例如验证邮箱地址

两种创建方式:

1
1. 直接量  var reg = new RegExp();

两种方法:

  1. text() 只能判断有没有符号要求的片段,只能返回true和 false
  2. match()
    可以判断符合的片段,并返回给你
修饰符:
1
2
3
4
5
6
i  执行对大小写不敏感的匹配

g 执行全局匹配

m 执行多行匹配
一个表达式就代表一位 ,里面填的就是区间
元字符:
1
2
3
\w ===[0-9A-z_]

\W ===[^w]
量词:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
n只是代表这个数,并不是特定的n

n+ 这个变量可以出现一次到无数次

n* 区间是零到正无穷

n? 匹配任何包含零个或一个n的字符串

n{x}

n {x,y} {3,5} 先匹配5个,再不行匹配三个

n$ 结尾 ,是要以这一整个片段结尾
^n 开头
RegExp对象属性:
1
2
3
4
global
ignoreCase //忽略大小写
multiline //多行
lastIndex

方法;
exec():
index 索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/()/		//()代表字表达式  \1代表反向引用第一个表达式的内容
var reg = /(\w)\1\1\1/ 可以匹配aaaaaabbbbb这种

var reg = /(\w)\1(\w)\2/g 可以匹配aabb这种表达式


search()

match() 匹配不到显示-1

split 可以填字符串,还有正则表达式

replace(‘a', 'b'); //替换字符,
非正则表达式:把前面的替换成后面的 ,因为没有权限所以只能替换一个。
正则表达式:具有访问全局的能力,把两个都能替换。rag =/a/g
1
2
3
var reg = /(\w)\1(\w)\2/g;
var str = "aabb";
console.log(str.replace(reg,'$2$2$1$1')); //这种可以把字符把aabb转换成bbaa
1
toUpperCase() 可以使字母大写
  • 正向预查,正向断言
1
/a(? =b)/g 后面就是一个b
1
2
abs() 可以去得正数和负数的绝对值
floor() 可以进行四舍五入
ui多线程
  1. JS可以操作DOM元素,进而会影响GUI的渲染结果,因此JS引擎线程与GUI渲染线程是互斥的。

######重新理解定时器
1.setTimeout的等待时间结束并不是直接执行setTimeout属于异步操作,进入任务队列排队,等所有的同步操作运行后才开始执行任务队列,执行操作。

bind的使用