js第一篇(基础)

以你之姓@ 2022-12-12 15:24 245阅读 0赞

JavaScript:依赖HTML的脚本语言(网景公司的Netscape)

script标签:三种写法(行内,内联,外联)

外联后script里面不需要写代码

script可以和style一样放在页面任意位置

初期建议放在/body和/html之间

注释:

//
/**/

输出语句:

  1. 加载至文档流:document.write();
  2. 用户提示:alert();
  3. 删除前的进一步提示:confirm();
  4. 输入框:prompt();
  5. 调试,控制台输出:console.log();

js语法要求:

单双引号尽量保持一种
分号可加可不加,要加都加,要不加都不加

变量:

本质就是存数据的容器—放在内存中

显示声明:var a = 5;

隐式声明:b = 5;

var a= b=c = 5;相当于 var a = 5;b = 5;c = 5;

一次性定义多个变量:var a = 3,b,c,d;

规则:

  1. 变量名不能数字开头,字母数字下划线美元符号组成
  2. 关键字不能作为变量名。

变量类型:

number:

var a = 10;

String:

若干个 任意字符 引号号包含起来

boolean

true,false

undefined未定义类型

var a ;.//undefined

object对象类型

三种表现形式:

数组:

var arr =[1,2,3]

json对象
null关键字

小数问题解决方案

js进行小数计算会精度损失

  1. var a = 0.2,b = 0.1;
  2. var c = a + b ;
  3. console.log(c);//0.30000000000000004

解决方案:

方法一:乘以10除以10

  1. var a = 0.2;
  2. var b = 0.1;
  3. var c = (a*10 + b *10) / 10;
  4. console.log(c);

方法二:强直保留小数点后几位
console.log(c.toFixed(3));

NaN(not a number)

  1. var a = 10;
  2. var b = 'abc';
  3. var c =a -b;//NaN
  4. console.log(c);//NaN

特点:

跟任何数据饭都不相等,包括自己

isNaN():检测一个数字是不是数字//true不是一个数字,false是数字
100a时显示true

字符串类型

单引号和双引号不可以嵌套他们自身

原因:引号虽然是字符,但是有特殊含义

解决:单嵌套双或相反;转义字符

注意:字符串拼接可以用加号

js可以输出标签的,doucment.write(“


“);

输出字符串长度:str.length

字符串也可以+=

运算符

赋值运算:

= ,+=,-=,…
作用;将右边的值赋给左边的变量

数字运算符

+ - * / %

字符串拼接:加号两边都是数字才运算

比较运算符

<等等

其中 ==是比较值的, ===是先比较类型,再比较值

因为 == 和!=是会自动进行数据类型转换的,转成数字再比较

强制类型转换

转为number:

Number():字符串纯数字才可以转为数字型,不然NaN

布尔true为1,false为0

undefined转数字是NaN

null转数字是0

parseInt();字符串前面的整数获取到

  1. "12.34"==>12

parseFloat()字符串前面的小数获取到

  1. "12.34"==>12.34

转boolean

Boolean(要转换的数据);

会转为false的情况;

NaN,0,’’,undefined,null

转字符串:

String():就是加个引号
数据.toString();
直接加上””;

自动类型转换

  1. 字符串拼接时,一边为字符串,另一边转为字符串
  2. 比较运算时,左右有一个是数字,另一个也会被转为数字比较
  3. 当进行除了加法以外的数学运算,会将两边转为数字再运算

逻辑运算

&& 与
||或
!非
通常连接两个表达式

控制台黑色数字为字符串类型,蓝色数字为数字类型

三元运算符

  1. 1 ? 2 :3;
  2. 1是正确的执行2,否则执行3
  3. 常用于双分支的替代
  4. 也可以将整个表达式赋值或者输出

进行数字加法运算的时候一定要检测是不是数字类型

逻辑分支

单分支:

if(条件){满足条件执行}
小括号内自动转换为boolean型

双分支

if(条件){当条件满足执行}else{不满足时执行}

多分支

if (条件) { 代码块 } else if ( 条件 ) { 代码块 } else if ( 条件) { 代码 块 }…else { 代码块 }(最后这个可写可不写)

单个多分支是多选一,多个单分支是多选多

分支语句可以简写

switch多路判断:

类似于多分支,只能判断一个变量跟某些值是否全等

  1. var num =1;
  2. switch(num){
  3. //switch小括号里面的值只能是变量
  4. case 1num ===1;(重点)
  5. 执行语句;
  6. break
  7. ...
  8. default:
  9. 执行语句;break
  10. }

break是可以省略的,称为case穿透

  1. num=2:
  2. case 2 console.log(“hello”);//这里省略break
  3. case 3console.log(“hello”);break;//这个就不判断了
  4. num=3
  5. case 3:跳过了case 2;但是倒过来写会执行case 2

注意:

  1. switch的运行效率是高于分支的,因为直接到达符合条件的地方,不需要从上往下判断
  2. 当判断是否相等时更加精确

分支语句的细节

小括号里面的可以放任何值,最终都转为boolean类型

自增自减运算

前缀先运算在操作,后缀先操作再运算

总结:
字符串的比较是逐位比较的,”|10”>”2”为false
switch倒着写可以实现累加的效果
剩下的多少秒:秒数%60
剩下小时 = 小时数 %24

循环

目的:处理重复
循环小括号的变量为全局变量

while循环:

  1. var i =15;
  2. while(i > 10){
  3. i--;
  4. console.log(i);
  5. }

do-while循环(while循环的变异)

  1. var i = 15;
  2. do{
  3. i--;
  4. }while(i<10);

至少执行一次

for循环

  1. for(var i = 15;i<10;i--){
  2. console.log(i);
  3. }

  1. var i = 0;
  2. for(;i<10;i++){
  3. console.log(a);
  4. }
  5. for (var i = 0; i < 10; i+2){
  6. console.log(i);
  7. }
  8. for (var i = 0;i < 10; salary = salary *0.1 ){
  9. i++;
  10. }

循环跳转:

break:跳出当前循环;
continue:跳出·此次循环,执行下次循环
continue的书写顺序要靠前,放在最后执行了效果等于没执行

循环的嵌套

for循环里面的还可以继续嵌套

DEBUG:

函数:

目的:处理重复
可以重复利用的工具

如何定义函数(%):

语法:function 函数名(){
代码段;
}

函数的定义其实是赋值过程,在内存中开辟fn的空间,fn存放代码

函数的调用:

函数名();//调用函数内部的代码
fn()中fn其实是数据类型(function),里面存放的是function后面的代码

定义一个函数:

  1. function fn(){
  2. console.log(123);
  3. }

在内存的显示:

  1. f fn(){
  2. console.log(123);
  3. }
  4. function //返回类型

在这里插入图片描述

形参:形式上的参数

实参:实际意义上的参数,用于给形参赋值,调用时候的小括号内,类型和个数需要和形参相对应

函数的优点:重复执行,模块化编程
函数的书写:先写核心代码,然后用函数包裹起来

匿名函数:

  1. var fn=function(){
  2. //定义变量fn,赋值一个函数
  3. console.log(123);
  4. }
  5. fn();//调用

使用场景:事件中

总结:函数可以没有名字,然后将函数赋值给一个变量——同样能使用

原因:函数的定义过程,其实就是在内存空间中开辟了空间,存放一段代码作为值

fn里面的值:
fn的内容

自调用函数(匿名函数使用小括号包起来):

匿名函数的fn代表的是:

  1. function(){
  2. console.log(123);
  3. }

那么fn()就是

  1. (function(){
  2. console.log(123);
  3. })();

也可以写成:

  1. ! function(){
  2. console.log(123);
  3. }();

!可以换成~,能看懂别人这么写就可以

好处是什么?省去了调用

函数提升篇:

代码执行顺序:

从上而下,从左至右,逐字符依次执行。只有有名字的函数才叫函数的定义(打%的地方)。

预解析:

从所有代码中找到变量的定义和函数的定义,找到了就会将变量的定义和函数的定义放到所有代码的最前面,然后再执行。

注意:函数的大括号可以约束声明提升,但是if语句等的大括号不具有约束性

  1. var a = 10;
  2. 分为两个步骤:定义a,将a赋值为10

题目检测:

  1. console.log(fn);
  2. fn();
  3. var fn = function(){
  4. console.log(123);
  5. }

运行结果:
undefined
报错

  1. fun();
  2. var fn = function(){
  3. console.log("我是fn函数");
  4. }
  5. function fun(){
  6. console.log("我是fun函数");
  7. }
  8. fn();
  9. fn = 100;
  10. fn();

运行结果
我是fun函数
我是fn函数
报错

  1. fn();
  2. function fn(){
  3. console.log("我是一个fn函数");
  4. }
  5. fn();
  6. var fn = 100;
  7. fn();

运行结果
我会fn函数
报错

这里预解析的时候函数和变量重名,保留函数

  1. var a= b;
  2. a = 0;
  3. b = 0;
  4. console.log(a);
  5. console.log(b);

直接报错
因为b没被定义就被使用,一定要先定义再使用

  1. var fun = 200;
  2. fun();
  3. var fun = function(){
  4. console.log("我是一个fun函数");
  5. }

直接报错,因为预解析后fun这个空间的值是200,不是函数,无法调用

  1. function fn(a){
  2. console.log("我是fn函数");
  3. a();
  4. functio a(){
  5. console.log("我是函数a");
  6. }
  7. }
  8. fn(10);

我是fn函数
我是函数a

注意:形参赋值是在函数提升和参数提升之前的

  1. console.log(num);
  2. if(false){
  3. var num = 100;
  4. }

undefined

注意:不会执行的代码也是要预解析的

return关键字

让一个函数返回值,后面的语句都不会执行
return只能停止函数,break只能停止循环和switch
函数中的循环可以加return
循环中的函数可以加break;

没有return的函数默认返回undefined

函数的书写步骤

  1. 先写核心代码
  2. 再写上函数外壳
  3. 然后寻找形参,提出来

作用域

能起作用的区域

在不同地方定义的函数和变量,起作用的范围是不同的

不在任何函数内定义的变量称为全局变量

在函数内定义的变量称为局部变量

全局变量在局部范围内有效
局部变量在全局范围内无效

函数定义好了就相当于创建了个作用域,任何函数都可以创建作用域

作用域可以嵌套作用域链

作用域链的使用规则:

赋值:
先从当前作用域查找变量的定义,没有找上一级,直到全局,全局有就赋值给全局变量;全局没有就隐式定义这个变量——-不过不存在提升过程。

运算、比较、输出等操作,先从当前作用域查找变量的定义,没有就杀上一级,直到全局,全局没有就报错,有则使用。

递归函数:

注意内存溢出错误(Maximum call stack size encoded)

先定义一个空函数,然后往空函数里面输入值:

  1. function fn(){
  2. if(num ==1){
  3. return 1;
  4. }
  5. return num*fn(num-1);
  6. }

注意一定要写return

事件

匿名函数的应用:

目的:

  1. 处理用户在网页上的行为,如点击,右击等

事件三要素:

  1. 事件源:

    1. 能触发某种行为的HTML标签
  2. 事件类型:

    1. 拖拽,移动
  3. 事件处理程序:

    1. 函数

在js中使用标签id代表标签,不要使用常见的关键字(name,start,stop)

语法(事件的定义):

事件源.onclick = function(){
console.log(123);
}

常见的事件类型


















































事件类型 含义
click 单击
dblclick 双击
mouseover 鼠标移入
mouseout 鼠标移出
submit 事件源form,点击的是submit
常见于表单验证,点击之后,跳转页面
keydown 键盘按下,window.onkeydown
keyup 键盘抬起,window.onkeyup
focus 获得焦点/光标
blur 失去焦点
load 等页面所有加载完后最后开始加载,window.onload
,可以让script放在任何位置,不用考虑加载顺序问题

注意,知识点来了:事件的函数是由系统来调用的,事件的类型有系统提供的

事件的书写

第一种:

  1. div.onclick = function(){
  2. console.log(123);
  3. }

第二种;

  1. btn.onclick =fn;
  2. function fn(){
  3. console.log(123);
  4. }

第三种:行内书写

  1. onclick ="javascript:console.log(123);"//只能写一个语句
  2. onclick=onclick(){
  3. }

js的关键字:

this:在全局中表示window(浏览器窗口),在事件中代表事件源

对象

对象分为数组/json对象/null

json:

定义:

多个数据(键值对)组成的集合
直接定义:

  1. var obj ={
  2. name:"张三",
  3. age:12
  4. }

构造函数:

  1. var obj =new Obj({
  2. name:"张三"
  3. });

对象数组的组成:

键值对形式:

键必须是字符串,在定义的时候可以不加;键中包含连字符“-”,那就须要加上引号

值是任意类型(可以是函数)

对象的操作:

增删改查:


























操作 写法
对象.键 = 值;/对象[“键”] = 值 ;
delete 对象.键/delete 对象[“键”]
存在那个键值对,增的形式就可以修改
console.log(obj.name/obj[“name”])

对象的遍历:

js提供了特殊的for

for(var attr in obj){
obj[attr];
}

attr是键,obj是对象

**注意:**错误写法如下

  1. var a ="name";
  2. obj.a;//这么写是错误的,因为obj里面没有a这个键

正确写法:

  1. var a = "name";
  2. obj[a];

对象的方法

对象的值如果是函数,那么这个键就叫做对象的方法

如果碰到多个键值对,就用对象

构造函数初体验

被用来new创建对象的函数都是构造函数

任意函数都可以new来当构造函数,当一个函数被用来创对象,就可叫构造函数

系统提供了一些构造函数来创建对象

  1. //系统内置的构造方法
  2. var num = new Number(12);
  3. String();
  4. Booelan();
  5. 这里的num是对象型,可以参与数学运算并得到结果

原理:js的底层处理任何的数据都是对象处理的,为了让开发者更加接近于正常的理解,js提供了基本数据类型,供开发者使用。

数组

也是多个数据的集合,但是相较于对象,数组在内存是按顺序排列的

数组的定义

一:直接定义

var arr=[1,2,3,4,5];

二:构造方法

var arr =new Array(5);
创建了5个empty
不建议使用

上面两种方式的区别只存在都给里面放个数字

  1. var arr=['a'];
  2. vae arr = new Array('a');
  3. //这两个是一致的

数组的特性:

数组对象里面有属性length,可通过arr.length获取数组长度

数组第一个下标为0,最后一个下标为arr.length-1

数组的操作


























操作 写法
arr[i]= [1,2,3]
delete arr[i] 或者arr.length = 0;
arr[i ] =“d”,arr[i]已经存在
arr[i]

数组遍历:

方法一:

  1. var length = arr.length;//因为每次判断都要取值一次,浪费时间
  2. for(var i = 0;i <length;i++){
  3. console.log(arr[i]);
  4. }

方法二:

  1. for(var i in arr){
  2. console.log(arr[i]);
  3. }

这个方法是遍历对象的,当然可以遍历数组

二维数组:

数组的元素类型没有限制,所以是数组类型也可以

嵌套两层为二维数组,嵌套三层为多维数组

查看三维数组中的某个元素arr[0][2][1];

建议:数组里面只放一种数据类型,对象里面放多种数据类型

数组的操作方法:

  1. splice(开始位置,删除个数,增加元素)

参数一和参数2必须写,参数三为可选项
最常用,插入删除修改数组
被操作数组被修改

pop():删除最后一个元素
unshifted():开头加上元素
shift():开头减少元素
push():末尾加上一个任意类型元素

  1. concat()数组拼接:

var res =arr1.concat(arr2);
var res1 = arr1.concat(“a”,“b”);//也是拼接在arr1数组末尾
拼接在数组末尾,arr2数组元素拼接进arr1中

  1. 数组的排序sort:

arr.sort(function(a,b){
return b-a;//降序 return a - b;为升序
})

  1. 连接join:

arr.join(“-“)
按照指定字符拼接成字符串

利用数组写页面

  1. var arr = [
  2. {
  3. name: "手机",
  4. img: "https://www.baidu.com/img/dong_8ff048ec89a4c8b4d638def4ce4dafda.gif",
  5. price: 50,
  6. desc: "真便宜,没好货"
  7. }
  8. ]
  9. document.write("<ul>");
  10. document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>");
  11. document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>");
  12. document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>");
  13. document.write("</ul>");

基本类型的内存机制:

栈内开辟空间,放入数据,b=a就是将a内存里面的数据复制一份到b

引用类型的内存机制:

数组在栈内开辟空间,将数组内容放在堆内存,栈内存存放数据的地址,b=a赋值的是数组的地址,修改的是堆内存的数组,对a的值也会产生改变

冒泡算法

算法原理:每相邻的两个元素比较大小,不符合规则就交换两个元素的位置

  1. var arr=[1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2];
  2. var length = arr.length;
  3. for(var i = 0; i<arr.length;i++){
  4. for(var j = 0;j<length -1;j++){
  5. if(arr[j]>arr[j+1]){
  6. var tmp =arr[i];
  7. arr[j] = arr[j+1];
  8. arr[j+1] =tmp;
  9. }
  10. }
  11. }
  12. console.log(arr);

选择排序

原理:每次选择最小的或最大的值放在合适的位置

  1. var arr = [1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2];
  2. for(var j = 0; j <arr.length - 1 ; j ++ ){
  3. var min = arr [j];
  4. for(var i = j+1 ;i <arr.length; i++ ){
  5. if(arr[j]> arr[i] ){
  6. var tmp = arr[i];
  7. arr[i] = arr[j];
  8. arr[j] = tmp;
  9. }
  10. }
  11. }
  12. console.log(arr);

ES5 简单认识

ES5 兼容性最好的版本

ES6也称为ES2005

ES:ECMAScript的简写

严格模式:

“use strict”;

要求:

  1. 不允许隐式定义变量
  2. 不允许普通函数内this代表window
  3. 不允许形参重名(js函数形参重名是可以执行的,但是不建议这么写)

写法:

在script的最前面或者在函数的最上面写上”use strict”;

好处:

消除怪异语法,更加规范化
运行效率更高

严格模式也受到作用域限制

数组方法:

  1. indexOf():查第一个值在数组中第一次出现的下标,查不到返回-1
  2. map():将数组的每个值处理,返回新元素组成的新数组

    arr.map(function(v,i,a){

    1. return v*0.3;

    })
    v:数组元素,i:数组下标;a:数组本身
    i,a是可选项

  3. filter方法:
    过滤函数
    满足条件的元素组成新数组返回。
    参数和map一致

    爱如如.filter(function(v,i,a){

    1. return v< 60;
    2. })

4.reduce方法:归并

  1. arr.reduce(function(v,i,a){
  2. return v<60;
  3. })

a:第一次值为arr[0],之后是上一次函数的return,没有返回undefined
b:a[次数];

map和filter用的最多

字符串

字符串的比较规则

从左到右逐个字符比较的

字符大小规则遵循ASCII码

数字<大写字母<小写字母

排名越靠前越小(a<z)

字符串的操作


















操作 形式
str[i]
增删改 没有,都会形成新的字符串

遍历字符串

for(var char of String){
console.log(“字符”+char);
}

常见的API

  1. charAt():通过指定的下标获取字符串的字符(极其鸡肋,不要记)
    str.charAt()
    2.charCodeAt():通过指定下标获取字符对应的ASCII码

3.固定写法:String.fromCharCode()——-通过ASCII码返回一个字符

  1. var num= 97
  2. var s = String.fromCharCode(num);
  3. console.log(s);
  1. indexOf()
    查字符在字符串中第一次出现的下标,没有返回-1
  2. lastIndexOf():
    查字符串最后一次出现的下标,返回值为下标或者-1
  3. substr():
    截取字符串,参数一开始截取的下标,参数二截取长度(不写默认截取到尾)
  4. substring():截取字符
    参数一:开始下标
    参数二:结束下标(不写默认到结尾,不包含参数二的)
  5. slice()
    截取字符串,和substring一样的
    截取从左到右,不是从右到左
    开始下标为负数的话,-1表示倒数第一个
    数组里面也有slice方法
  6. split():
    把字符串转成数组(俗称“炸”)
    使用指定的分隔符将字符串分割成很多小字符串,组成数组并返回
    没有参数将整个字符串当做元素放入数组
    split(“”):每个字符都当成元素组成新数组
  7. replace():
    替换字符串中的指定内容,只能替换一次,循环才可以替换多次
    str.replace(“html”,“css”);
    var s = str.replace(“”)
  8. trim()
    去除左右的空格,可分为trimLeft()和trimRight()

toLowerCase();//全部小写
toUpperCase()//全部大写

Math Date

math对象:系统内置的对象

math不像String和Date是对象的类,因此没有构造函数Math(),像Math.sin()这样的函数只是函数,不是某个对象的方法。无需创建,通过把慢作为对象使用就可以调用其所有的属性和方法














































格式 功能
Math.PI 圆周率
Math.round() 四舍五入
Math.pow(底数,幂数) 次方
Math.random() 获取随机数
Math.floor() 向下取整
Math.ceil() 向上取整
Math.max() 最大值
Math.min() 最小值
Math.abs() 求绝对值

对Math.random()进行封装

  1. function Random(a,b){
  2. var res = parseInt(Math.random()*(b-a))+a;
  3. return res;
  4. }

生成一个[a,b)的随机整数

进制转化

除了十进制以外的进制都是字符串形式

10进制转为其他进制:
num.toString(8);//转为八进制
其他进制转为10进制:
var res = parseInt(str,n);
//str为进制字符串,n为str是什么进制的

Date对象

系统提供的构造函数

var date =new Date();
console.log(date);//当前时间

date对象在我们打印日期的时候自动调用toString方法。

格里尼治时间戳:从格林尼治的1970.1.1.0.0.0到现在的毫秒数,就是现在的时间戳

获取:

var date =new Date();


















































获取什么 格式
获取年 var year = date.getFullYear()
获取月 var month = date.getMonth()
获取日 var day = date.getDate()
获取时 var hour = date.getHours()
获取分 var minute = date.getMinutes()
获取秒 var seconds = date.getSeconds()
获取毫秒 var milisecond = date.getMiliseconds()
获取时间戳 var time = date.getTime()
获取星期几 var week = date.getDay()
快速获取时间戳 var res =+new Date();

注意:js里面的月份是0~11,输出时需要加1

设置:

get改为set就可以了

星期是不可以设置的

设置时间戳:date.setTiems(0)//格林尼治时间
在线运行js

设置·指定时间的时间戳
var date = new Date(“2020-10-10 11:21:05”);
var date = new Date(1010,10,10,0,0,0);

通过构造方法设置时间戳:
var d = new Date(0);

获取当前代码执行时的时间戳

  1. Data.now()

格式化输出时间日期:
date.toDateString();//只看年月日
date.toLocaleTimeString();//只看时分秒
date.toLocaleString();//都看

BOM(浏览器对象模型)

Browser Object Model

操作浏览器都是使用对象来操作的:window对象(浏览器窗口)

window有子对象,每个子对象都针对着一个操作

js实现跳转的方法

window.open():
window.location.href=“地址”
window.location.assign():
window.location:

window子对象:BOM中的顶级对象

注:window可省略

navigator(获取浏览器信息)

没什么卵用,对于学爬虫的估计有用
window.navigator.appCodeName 浏览器内核名称
window.navigator.appName浏览器名称
window.navigator.appversion:浏览器版本
window.navigator.userAgent:浏览器信息

history历史记录(你打开的网页记录)

前进:
history.back();
后退:
history.forward()
刷新:
history.go();//正数前进,负数后退,0刷新当前页面

location:地址栏

href属性:
location.href是完整的地址栏地址,赋值可以实现跳转

search属性:
获取地址栏数据
location.search
也可以赋值设置,注意是键值对形式

hash属性:
获取地址栏的锚点:
location.hash=”#bottom”

页面重定向(跳转方法):
location.assign(“地址”);

新地址替换当前地址:
location.replace();

刷新当前页面:
location.reload();

window弹出方法:

alert();
prompt();
confirm();

注意:
全局变量其实是window的属性,全局函数是window的方法,只不过平时省略了window,全局中的普通函数中的this代表的就是window对象。

window获取浏览器的尺寸

innerWidth/innerHeight 包含滚动条,相当于视窗的宽高(去掉了window)

window事件(重点):

window.onload = function(){
//页面加载完再执行
//放在同步中就是同步加载完的最后,异步中就是异步最后
}

window.onreszize = function(){
//改变窗口大小就执行
}

window.onscroll = function(){
//浏览器滚动条滚动时执行
}

定时器(重点):

分两种:每隔一段时间执行一次和延时一段时间只执行一次

第一种:

  1. var timer =window.setInterval(function(){
  2. console.log("123");
  3. },1000)

清除:

  1. clearInetrval(timer);
  2. //形参是当前页面第几个定时器,一般为定时器返回值或者数字,会执行一次

注意:定时器一定要停,不然内存溢出

之前的内存溢出的情况(死循环,递归函数)

第二种:

  1. window.setTimeout(function{
  2. console.log(123);
  3. },2000)
  4. //也有返回值,也用来清除,同样代表第几个定时器

清除:clearTimeout();

重点:定时器的返回值

timer这个返回值其实是最后一次点击的定时器的返回值

清除定时器的时候,其实是清除了最后一个定时器,前面几次点击产生的定时器没有清除,也清除不掉了

同步操作和异步操作

同步:
上面的语句执行完,下面才会执行,排队等待

异步:
同时执行(和同步)

运行流程:

  1. js是单线程的(同时只能做一件事)
  2. 当js线程看到异步代码(栈空间),将异步交给浏览器(多线程)
  3. 浏览器等异步操作执行时机,时机成熟放入一各队列等待时机
  4. js线程如果将所有的同步执行完,会从队列中找到需要执行的代码才会执行。

总结:
定时器和延时器不一定精准(因为异步的定时器会受到同步时间的耽误)
所有异步都是在同步执行完之后执行的
异步效率高

DOM操作

dom(document object model)文档对象模型

操作HTML文档 的方法

之前我么使用id来表示这个标签,如:

  1. <div id="box"></div>
  2. box.onclick (function(){
  3. console.log(123);
  4. })

如何获取标签元素


































操作 写法
使用id名获取 document.getElementById(“id名”);
类名获取元素 document.getElementsByClassName(“box”);
标签名 document.getElementsByTagName(“”);
使用name属性获取 document.getElementsByName(“sex”);
CSS选择器获取元素 document.querySelector(“选择器”),只能获取满足css选择器的第一个
CSS选择器选择元素的集合 var oDiv = Document.querySelectorAll(“li”)

注意:2,5,6条低版本IE不兼容

在编写过程中使用name作为变量名,控制台输出出现异常,不能用name作为变量名

属性操作:






















操作 写法
元素对象.getAttribute(“属性的键”)
removeAttribute(“键”)
有则改,无则增 setAttribute(键,值)

特殊的: img.src和input.value

最重要的:input.checked

内容操作

元素.innerText,值为标签内容,设置标签样式是不生效的
元素.innerHTML:标签内容,值为标签生效

特殊情况:

表单元素的值:
document.querySelector(“input”).value;

设置样式:

写在行内的style标签里面的

类名操作:

标签.className=””;
这么写清空类名

滚动过的距离














垂直滚动 document.documentElement.scrollTop
水平滚动 document.documentElement.scrollLeft

当文档声明没有时,documentElement换成body

  1. 文档声明就是<!DOCTYPE html>

兼容写法:

  1. var t = document.documentElement.scrollTop||document.body.scrollTop

立即回到顶部:

  1. t = 0;(就是设置document.documentElement0t只是存变量值的)也可以定时器不断减少慢慢变化

html基本结构获取写法


























部位 写法
html docuemnt.documentElement
body document.body
head document.head
title document.title

节点

节点:html文档的组成部分

DOM节点分(了解):
元素节点(标签),属性节点(),文本节点(文本内容),注释节点(注释)

注意:
文本节点:标签内的文本和标签之间的换行空格(为什么写移动端最好别换行空格,因为算文本,会被当做文字放大)都算文本节点

获取节点:

上面的getElementById等都是获取节点,但是这里的获取节点是依靠关系,不是直接获取

重点:






























































获取什么 怎么获取
子节点 childNodes
子标签 children
父节点 parentNode
父标签 parentElement
第一个节点 firstChild
最后一个节点 lastChild
子元素中第一个标签 firstElementChild
子元素中最后一个标签 lastElementChild
获取上一个节点 previousSibling
获取下一个节点 nextSilbling
获取上一个节点元素 previousElementSibling
获取下一个节点元素 nextElementSibling
获取所有属性节点 atributes

节点属性

都是属性,不是方法






















写法 作用
nodeType 获取节点类型
nodeName 获取节点名
nodeValue 获取节点值

nodeType返回值:
1表示元素节点;3表示文本节点;8表示注释节点;2表示属性节点

nodeName:
标签节点为标签名的大写形式(DIV),文本节点为(#text),注释节点为(#comment)

nodeValue:
标签为null,文本节点为文本内容,注释节点为注释内容

节点操作






































操作 写法
删除当前元素 元素.remove()
新建元素 createElement(“元素名”)
父元素加子节点(追加在子元素最末尾) 父元素.appendChild(oDiv)
将子节点插到某个子节点之前 父元素.insertBefore(新元素 ,被插队的节点)
替换节点 父元素.replace(新节点,旧节点)
删除节点 removeChild(被删除的子节点)
复制节点自身 元素.cloneNode()

复制节点传参true可以将里面的内容也复制

下面全程高能

获取样式:

var styles = window.getComputedStyle(元素);
styles.属性

低版本IE不兼容

兼容写法

  1. function getStyle(){
  2. try{
  3. return window.getComputedStyles(ele[attr]);
  4. }catch(e){
  5. return ele.currentStyle[attr];//IE兼容写法
  6. }

获取元素大小


















clientWidth/Height number型,不含边框
offsetHeight/Width 含边框

都是只读类型,offsetHeight对于行内一直为0

获取元素的位置


















offsetLeft/offsetTop 获取到设置过定位父元素的距离{机制和定位机制一样,逐级向上寻找定位元素}
offsetParent 获取设置过定位的父元素,最终到body

获取窗口大小:


















window.innerHeight/Width 含滚动条
document.documentElement.clientWidth/clientHeight 不含滚动条

变量定义技巧

一个局部想要使用另一个局部的变量,可以将变量定义在全局

使用自调用函数传参(形成保留作用域)

  1. for (var i = 0; i < ulis.length; i++) {
  2. ( function(i) {
  3. ulis[i].onclick = function () {
  4. that.className="";
  5. that =this;
  6. for (var j = 0; j < ulis.length; j++) {
  7. ulis[i].className = "";
  8. }
  9. this.className = "active";
  10. for (var j = 0; j < olis.length; j++) {
  11. olis[j].className = "";
  12. }
  13. olis[i].className = "active";
  14. }
  15. })(i);
  16. }

下拉框select>option里面的value可以

document.querySelector(“select”).value获取到

事件

为了提高浏览器检索优先级:能不用标题标签就别用

事件:用户的动作(单击,右击等)

下面是事件类型:

鼠标类






















































右击 contextmenu
鼠标按下 mousedown
鼠标抬起 mouseup
鼠标移入 mouseover
鼠标移出 mouseout
鼠标滚轮 mousewheel(火狐里面用DOMmousescroll)
鼠标单击 click
鼠标双击 dblclick
鼠标移动 mousemove
移入 mouseenter
移出 mouseleave
  1. document.documentElement.addEventListener('DOMMouseScroll',function(){
  2. console.log("火狐");
  3. })

mouseover和mouseenter的区别:

相同点:没有子元素时候行为一致

mouseover用的比较多,mouseenter经常被忘掉

mouseenter不会冒泡,mouseover会

不论鼠标指针穿过被选元bai素或其子元素,都会du触发 mouseover 事件。对应mouseout
只有zhi在鼠标指针穿过被选元dao素时,才会触发 mouseenter 事件。对应mouseleave
这样的话,mouseenter子元素不会反复触发事件,否则在IE中经常有闪烁情况发生。(复制自百度)

键盘类






















keypress 键盘按下
keydown 看英文,不解释
keyup 按键抬起(一定要注意执行时机,获取按下那个键的键盘码不能用这个)

区别自己百度,使用最多的是keyup

表单事件






























focus 光标点进去
blur 光标(闪烁的竖杠)丢失就触发该事件
change 下拉框改变就触发
input 实时监听文本框的内容变化(类似百度的搜索框,IE中是propertychange)
submit 给submit标签绑定的(form.submit,必须要结合提交按钮使用)

事件流

事件从开始触发到执行结束的流程(一连串的事情)
捕捉阶段:从文档由外向内找目标元素
目标阶段:找到目标文件,执行文件
冒泡阶段:执行完就要离开

事件外的元素也绑定了事件的话,冒泡阶段由内向外会触发外面的事件

事件侦听器(一个事件绑多个函数)

onClick的缺点:一个元素绑多个onClick会被覆盖

事件侦听器(兼容性):

元素.addEventListener(“click”,function(){
//可以实现多个不覆盖,但是IE不行
})
元素.attachEvent(onclick,function(){

})

  1. function bindEvent(btn,type,handler){
  2. try{
  3. btn.addEventListenter("type",handler);
  4. }catch(e){
  5. btn.attachEvent(on+"type"handler);
  6. }
  7. }

第二种:

  1. function bindEvent(btn ,type,hander){
  2. if(btn.addEventListener){
  3. btn.addEventListener(type,hander)
  4. }else if(btn.attachEvent)){
  5. btn.attachEvent("on"+type,handler)
  6. }else{
  7. btn["on"+type] = handler
  8. }
  9. }

第三种:

  1. function bindEvent(btn,type,handler){
  2. try{
  3. btn.addEventListener(type,handler)
  4. }catch(err){
  5. try{
  6. btn.attachEvent("on"+type,handler)
  7. }catch(e){
  8. btn["on"+type] = handler }}}

访问对象中不存在的属性是undefined

好处:

  1. 同一类型事件可以绑定多次:

    button.addEventListener(“click”,function(){

    1. console.log("点击");
    2. });
    3. button.addEventListener("click",function(){
    4. console.log("点击");
    5. });
    6. button.addEventListener("click",function(){
    7. console.log("点击");
    8. });
  2. 可以指定当前事件在捕获阶段执行

  3. 有第三个参数,代表是否在捕捉阶段执行(默认false表示冒泡阶段执行)
    attachEvent没有第三个参数,因为IE浏览器的事件流,没有捕获阶段

事件解绑

按钮能点击,说明加载到内存中了,所以点击才能生效


点击完后还能点击,希望只执行一次,减少内存负担(所需要解绑)


null为引用类型的空,undefined为基本类型的空

  1. btn.onclick = null;//解绑

事件监听器解绑

前提里面的函数不能是匿名函数了

  1. var fn = function(){
  2. console.log(123);
  3. }
  4. 解绑:
  5. 事件源.removeEventListener("click",fn);
  6. 事件源.detachEvent("onclick",fn);

解绑又有兼容性问题——封装函数:

  1. function unbindEvnet(ele,type,handler){
  2. if(ele.removeEventListener){
  3. ele.removeEventListener(type,handle)
  4. }else if(ele.detachEvent){
  5. ele.detachEvent(“on”+type,handle);
  6. }else {
  7. ele[“on”+type] = null;
  8. }
  9. }

阻止事件冒泡

事件时有系统调用的,不是我们手动调用的,系统将事件对象放在小括号内,存放和当前事件相关的一系列信息。

  1. small.onclick = function(e)
  2. {
  3. console.log(e);
  4. e.stopPropagation();//阻止事件冒泡
  5. }

在IE中的兼容写法
事件对象:window.event
阻止冒泡:e.cancelBubble=true;

事件对象的简单操作














































e.type 事件类型 如“click”等
e.button 鼠标按键信息 左键是0,右键是2,滚轮是1
e.keyCode 键盘码 回车13,数字字母遵循ASCII码
e.shiftKey/ctrlKey/altKey 组合键 true或者false
e.offsetX/Y 光标在元素上的坐标位置
e.clientX/Y 指光标在浏览器上的位置 指视窗距离,不包含滚动过的距离
e.pageX/Y 光标在房钱页面上的绝对位置 包含滚动过的距离

注意:键盘码低版本火狐不兼容
兼容写法:

var keycode =e.keyCode||e.which

简单的拖拽效果

  1. var div = document.querySelector("div");
  2. //拖拽一定先按下鼠标
  3. div.style.position="absolute"
  4. div.style.left="0"
  5. div.style.top="0"
  6. div.onmousedown = function(e){
  7. //这里代吗都是在鼠标按下的时候执行的-----按下后再移动鼠标(鼠标移动事件)
  8. var e = e ||window.event;
  9. var x = e.offsetX;
  10. var y =e.offsetY;
  11. div.onmousemove = function(ev){
  12. //这里写div可以将鼠标甩出来,换成 document,解绑也需要document
  13. //鼠标移动只会执行这里的代码
  14. var ev = ev ||window.event;
  15. var x1 = ev.clientX;
  16. var y1= ev.clientY;
  17. var l = x1 - x;
  18. var t = y1 - y;
  19. div.style.left=l+"px";
  20. div.style.top = t+"px";
  21. }
  22. }
  23. 只要鼠标在div上,触发onmosemove,外面的onmousedown就不会停止,需要解绑里面的
  24. 这时需要解绑:
  25. div.onmouseup= function(){
  26. div.onmousemove =null;
  27. }
  28. 存在点击后快速离开,解绑无效果,那么把移动的事件源由div改为document(就算被甩出div范围也依旧在document范围)

拖拽限制

  1. var div = document.querySelector("div");
  2. //拖拽先按下鼠标
  3. div.style.position = "absolute"
  4. div.style.left = "0"
  5. div.style.top = "0"
  6. div.onmousedown = function (e) {
  7. //这里代吗都是在鼠标按下的时候执行的-----移动鼠标-----鼠标移动事件
  8. var e = e || window.event;
  9. var x = e.offsetX;
  10. var y = e.offsetY;
  11. document.onmousemove = function (ev) {
  12. //鼠标移动只会执行这里的代码
  13. var ev = ev || window.event;
  14. var x1 = ev.clientX;
  15. var y1 = ev.clientY;
  16. var l = x1 - x;
  17. var t = y1 - y;
  18. if (l < 0) {
  19. l = 0;
  20. }
  21. if (t < 0) {
  22. t = 0;
  23. }
  24. if (l > document.documentElement.clientWidth - div.offsetWidth) {
  25. l = document.documentElement.clientWidth - div.offsetWidth;
  26. }
  27. if (t > document.documentElement.clientHeight - div.offsetHeight) {
  28. t = document.documentElement.clientHeight - div.offsetHeight;
  29. }
  30. div.style.left = l + "px";
  31. div.style.top = t + "px";
  32. }
  33. }
  34. div.onmouseup = function () {
  35. document.onmousemove = null;
  36. }

阻止默认行为

链接的跳转,鼠标右键出现的窗口都是默认行为

  1. return false(事件函数最后加上)
  2. e.preventDefaulte e.returnValue =false(IE中)(利用事件对象来阻止)
  3. 将链接地址改为javascript:;

事件委托

将子元素的事件委托给父元素:例如点击事件,委托后每个子元素都可以有点击

好处:你新增的元素不需要再次单独绑定事件,十分方便

兼容写法:

target = e.target ||e.srcElement;(兼容低版本IE)
target代表的是所有子元素

  1. <ul>
  2. <li>11111111111</li>
  3. <li>22222222222</li>
  4. <li>33333333333</li>
  5. <span>4444444444</span>
  6. </ul>
  7. <button>添加</button>
  8. </body>
  9. <script>
  10. var ul = document.querySelector("ul");
  11. ul.onclick = function(e){
  12. var e = e||window.event;
  13. var target = e.target ||e.srcElement;
  14. if(target.nodeName=="LI"){
  15. target.innerText="修改";//加条件限制target范围
  16. console.log(target);
  17. }
  18. }

注意点:

  1. 拖拽的时候一定是事件嵌套,事件的事件对象是不一样的
  2. mouseover和mouseout是一对,mouseenter和mouseleave是一对,尽量不要混用
  3. 在head里面写script标签,要将代码写在这个事件内部;script在body的底部,就不要加了,加了也没用,还会覆盖前面的
  4. 键盘事件通常是keyup
  5. 获取键盘码时有些特殊键盘码无法显示,大小写有时候会混乱,不要研究为什么

offset的一个坑

没有设置小盒子的时候,光标就是大盒子上的位置,就是offsetX
一旦设置了小盒子的位置,光标立马就会在小盒子上,此时的offset就是光标在小盒子上的位置。

拖拽效果不要使用offsetX/Y

e.clientX/Y都是只读数据

正则表达式

用处:验证字符串,提取满足的字符串,替换字符串

但是还有很多用法,无法说清,不仅仅只是简单地实现表单验证

书写规则:

  1. 创建:
    var reg =new RegExp();
    var reg = /规则/;
  2. 可接受写法
    var reg = /html/;
    var reg =/^html$/;
    var reg = /\w$/;
    var reg =/\d$/;
    var reg =/^\d{5,12}$/;





































































符号 意义
^ 放在规则前表示必须是这个开头
$ 放在规则结尾表示必须以这个结尾
{m,n} 至少m个,至多n个
{n,} 至少n位,多了不限制
{n} 必须是n位
\w 任意字母数字下划线
\d 任意数字
. 代表一个字符(注意字符是重点)
\s 代表一个空格
[a-z] 小写a到小写z,不是固定解法,[a-zA-Z]表示任意一个字母
\u4e00 -\u9fa5 汉字,不要记,会查就行
+ 至少一个
? 最少0个,最多1个
* {0,},任意个
() 表示包起来的是一个整体,还有个用法是用来捕获变量

手机号:

方式一:

  1. var str = "28715260980";
  2. var reg =/^1[3-9][0-9]{9}$/;
  3. var res= reg.test(str);
  4. console.log(res);

方式2:

  1. var str = "28715260980";
  2. var reg =/^1[3-9]\d{9}$/;
  3. var res= reg.test(str);
  4. console.log(res);

qq邮箱

  1. var reg = /^[1-9]\d{4,11}@qq\.com$/; //.有特殊意义,需要转义
  2. var res = reg.test("1974744790@qq.com");
  3. console.log(res);

网易邮箱

  1. var reg = /^[a-zA-Z]\w{5,17}@(163|162)\.com$/;
  2. var str = "shaoguoqing10@163.com";
  3. console.log(reg.test(str));
  4. 注意:空格也算在规则内

QQ邮箱+网易邮箱:

  1. var reg= /(^[1-9]\d{4,11}@qq\.com$)|(^[a-zA-Z]\w{5,17}@(163|162)\.com$)/;
  2. var str = "1974744790@qq.com";
  3. console.log(reg.test(str));

方法:






























test 正则方法,验证是否满足规则
search 验证是否有满足规则的那一段,有返回下标,没有返回-1
exec 正则方法,找到匹配的输出为数组的第一个元素,找不到为null
match 字符串方法,没有匹配返回null,和exec没什么区别
replace(reg,“str”) 将str里和reg匹配的替换成js,只能替换一次,替换多次/html/g;多次忽略大小写/html/gi;

注意:
exec(): 正则方法
在字符串中找到匹配的为输出的数组第一个元素,找不到为null
如果想要具体的某个值,可以给那个值加上(),第二个元素为小括号内的值

文件格式检测:

  1. var reg = /^\w{1,}\.(jpg|jpeg|bmp)$/
  2. var str ="1.jpg";
  3. var res= reg.test(str);
  4. console.log(res);

字符串首行去空格

  1. var str=" ab dc ";
  2. var reg = /(^\s+)|(\s+$)/g;
  3. var replace = str.replace(reg,"");
  4. console.log(replace);

ES5,ES6语法

表单验证要么都是失去焦点的验证,要么都是提交按钮的验证,不然冲突,失去焦点优先级高,提交按钮无效。

数组方法






























v,i,a 形参,名字随便起的,代表数组元素,下标,调用数组,一般第二第三个参数都是省略不写的
foreach() 只能遍历,没有返回值
some 判断数组中至少有一个满足条件
every 判断数组中是否所有元素都满足条件
find() 查找数组中第一个满足元素的元素
findIndex() 满足条件的下标(用法类似find)

foreach:

  1. arr.forEach(function(v,i,a){
  2. console.log(v);
  3. })

some:

  1. var res = (function(v,i,a){
  2. return v>30;
  3. })

every:

  1. var res = arr.every(function(v,i,a){
  2. return v==60;
  3. })

find:

  1. var res = arr.find(function(){
  2. return v>5;
  3. })

ES6:

定义变量:

var的特点:能预解析,全局变量属于window

两个关键字定义变量: const,let
特点:不能预解析;不在window上(因为自己的作用域)

let定义的变量,创建了一个作用域

  1. for(let i = 0; i<3;i++){
  2. };
  3. console.log(i);//报错,表示i未定义

let定义过的变量,不能重复定义:
好处:以前事件外循环参数需要函数传入,现在将循环参数改为let就可传入,因为let创建了个作用域

  1. var button = document.querySelectorAll("button");
  2. for (let i = 0; i < button.length; i++) {
  3. button[i].onclick = function () {
  4. console.log(i);
  5. }
  6. }
  7. function f2(){
  8. var i = 5;
  9. for(var i=0;i<=10;i++){
  10. }
  11. console.log(i); // 11
  12. var j = 5;
  13. for(let j=0;j<=10;j++){
  14. }
  15. console.log(j); // 5
  16. }
  17. f2();

const:常量,值可被初始化,但不能赋值。也不在window上,也不能预解析,不希望改变的量就用const来定义

箭头函数

形参列表只有一个参数,小括号可以省略
大括号内只有一行代码,省略大括号
若一行代码内只有return关键字,return关键字可以省略

  1. let fn = res=> res;
  2. let fn= function (res){
  3. return res;
  4. }

函数默认值

function(a,b=10){
console.log(a,b);//b不传值就是10,传值10被覆盖
}
如果a有默认值,不想改变,可以实参传undefined

…运算符

  1. 将多个形参整合成一个数组:

    let fn = (…arr)=>{

    1. console.log(arr);
    2. }
    3. fn(10,20,30);
  2. 将数组拆分成多个值

    let fn = (a,b,c)=>a+b+c;
    let arr =[1,2,3];
    const res = fn(…arr);
    console.log(res);

  3. 可以将对象拆分成多个键值对

    var ch ={

    1. naem:"翠花",age:12}

    var zz = {

    1. name="李四",age:14,wife:{
    2. ...ch}}

    这里注意加载顺序

总结:实参分解形参合并,对象直接拆

对象

  1. 键与值相同可以只写一个:

    var name=”张三”;
    var age = 12;
    var obj = {

    1. name,age}
  2. 方法也可以简写:

    var ff ={

    1. eat:function(){
    2. console.log("eat");}};
    3. 改写:
    4. var ff = {
    5. eat(){
    6. console.log("eat")}}
    7. 调用:
    8. obj.eat();
  3. 解构赋值
    快速将对象或者数组中的值赋给多个变量

    var name=”张三”;
    var age = 12;
    var zs ={

    1. name,
    2. age,
    3. eat(){
    4. console.log("吃");},
    5. sport(){
    6. console.log("运动");},
    7. wife:{
    8. name:"翠花",age:12}

    }
    var {

    1. name.age,eat,sport}=zs;

    console.log(name,age,eat,sport);

注意变量名和键名需要保持一致

取别名:
var {name:n,age:a,eat:e,sports:s}=zs;
console.log(n,a,e,s);
套娃操作:

var {wife}=zs;
var name={wife};
简化套娃操作:var {wife:{name:n}} = zs;

数组结构:

  1. var arr = [1,2,3,4];
  2. var[a,b,c] =arr;
  3. var [a] =arr;
  4. //只想获取c
  5. var [_,_,c]=arr;
  6. //数组的多重解构(套娃)
  7. var arr =[
  8. "马蓉",
  9. "王宝强",
  10. [
  11. "贾乃亮",
  12. "PGOne",
  13. "李小璐"
  14. ]
  15. ]
  16. var [_,_,[a]] = arr;

字符串

字符串是不支持多行定义的,使用模板字符串就可以了(反引号)

  1. var name="张三";
  2. var str=`
  3. 姓名:${
  4. name}
  5. `;
  6. name+str;

字符串方法

返回值是boolean型:
startsWidth:字符串是否以某个文字开头;
字符串是否以某个文字结尾;
includes:判断字符串是否有某个字符(split炸要是成三段就是含有这个字符)

具体查看数据类型:

Object.portotype.toString.call(对象名);

伪数组

是对象,像数组能遍历,但是不能用数组方法

之前getElementByTagNames等获取到的就是。

特点:

  1. 键是数字,有一个键为length,值为元素个数
  2. 数组的length属性颜色淡,但是可以调用
  3. 对象没有length,但是伪数组有
  4. 伪数组的键其实是字符串,也有引号
    arr[“0”];

自创伪数组:

  1. var weishuzu={
  2. 0:"第一个",
  3. 1:"第二个",
  4. 2:"假设这是极限",
  5. length:3
  6. }
  7. for(let i = 0;i<wieshuzu.length;i++{
  8. console.log(weishuzu[i]);
  9. }

伪数组转为数组

var arrv = Array.prototype.slice.call(obj);

伪数组的遍历

for(var i = 0 ; i <obj.length;i++){
console.log(obj[i});
}

函数中的关键字:arguments

function fn(){
console.log(arguments);
}
fn(1,2,3);arguments是存放实参的伪数组

this关键字代表什么






































所在范围 代表
全局,普通函数 window
定时器中 window
自调用函数 window
对象方法中 当前对象
箭头函数 自己所处作用域的this
用对象调用的方法 this代表这个对象
事件 代表事件源

所有用对象调用的方法,this代表这个对象
函数定义不知道this是什么,只有调用的时候才知道。

点击调用函数的时候,相当于调用了document的onclick方法

  1. for(var i=0;i<imgs.length;i++){
  2. imgs[i].onclick = function(){
  3. var path = this.src; //利用this获取变化的i值
  4. document.body.style.backgroundImage = 'url('+path+')';
  5. document.body.style.backgroundRepeat = 'no-repeat';
  6. document.body.style.backgroundSize = '100% 100%';
  7. box.style.height = 0;
  8. }
  9. }

点击跳转至推荐文章

如何改变this

将fn中的this改为arr

1. call方法:被函数调用的方法

  1. fn.call(arr)//相当于函数的调用
  2. 本质:调用函数被改成函数.call()
  3. 调用call之后函数就被调用了
  4. var obj = {
  5. fn(a,b){
  6. console.log(a,b);}
  7. }
  8. var arr =[1,2,3];
  9. obj.fn.call(arr,1,2);
  10. 相当于arr调用了obj里面的fn方法,第一个参数后面的都是obj.fn需要的参数

感觉讲的非常详细,可以点这个链接去看看
undefined+undefined = NaN

apply:

也是调用函数,和call差不多,也能改变this

函数的实参会组成数组传入

  1. var arr =[1,2,3];
  2. var obj ={
  3. name:"张三",
  4. fn(a,b,c){
  5. console.log(c)
  6. }
  7. }
  8. obj.fn.apply(arr,[1,2,3]);

bind:

复制函数,参数相当于复制出函数里面的this
点击跳转至推荐文章

  1. var obj = {
  2. name: "张三",
  3. fn(a,b){
  4. console.log(this);
  5. console.log(a+b);
  6. }
  7. }
  8. var arr = [1,2,3]
  9. //下面都是实现相同功能的不同写法,bind返回的是复制的函数
  10. // obj.fn(1,2)
  11. // obj.fn.call(arr,1,2)
  12. // obj.fn.apply(arr,arr)
  13. //obj.fn.bind(arr,...arr)();

下一篇:DOM高级-运动

注:全篇为个人笔记,仅供参考,如有错误请指出

发表评论

表情:
评论列表 (有 0 条评论,245人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Node.js Stream - 基础

    背景 在构建较复杂的系统时,通常将其拆解为功能独立的若干部分。这些部分的接口遵循一定的规范,通过某种方式相连,以共同完成较复杂的任务。譬如,shell通过管道`|`连接各