js
javascript是什么,从哪来
- 网页是什么,由html超文本标记语言实现的一种在浏览器中可以查看的文档类型。默认情况下,此文档没有任何交互功能,为了提升用户体验,需要给文档添加行为,交互等功能。此时需要一种脚本语言,给文档添加行为或交互。这个脚本语言就是javascript。
- javascript的历史
- 网页的组成:html结构,css样式,javascript行为
- ECMA是javascript的规划化组织,推出了javascript的规范,叫ECMAscript。
javascript的组成:ECMAscript语法规范,DOM文档对象模型document,BOM浏览器对象模型window
javascript写在哪,写什么
-
javascript写在哪
-
行内:标签的行为属性内
<div class="box" onclick="alert(1)"></div>
- 只能行为触发,不能自动执行
- 造成了html和js的混乱:结构和行为没有分离,不方便维护,无法复用代码
- 不推荐
-
内部:script标签内
<!-- 此处是html代码 --> <script> // 此处是js代码 alert(2); </script>
- 能自动执行
- 依然不方便复用
- 不推荐
-
外部:js文件内,在html文件内使用script标签的src属性引入
// index.js alert(3);
<!-- html文件 --> <script src="./index.js"></script>
- 能自动执行
- 实现了结构和行为的分离
- 方便复用,方便管理和维护
- 推荐
-
关于执行顺序
- 默认情况下,自上而下执行
-
错误的写法:
- 内部和外部的js不能共用一个script标签
<script src="./index.js"> alert(2); </script>
-
-
写什么(打印语句)
- 打印:将计算机的执行结果,显示给用户
- 打印到浏览器的弹出框:BOM
- alert()
- 会将打印的数据,强行以字符的形式显示
- 一次只能打印一个数据
- 不能解析标签
- 阻塞程序执行
- 打印到网页:DOM
- document.write()
- 会将打印的数据,强行以字符的形式显示
- 一次可以打印多个数据
- 能解析标签
- 不会阻塞程序执行
- 打印到浏览器的控制台:V8引擎
- console.log()
- 以数据原有的形式显示
- 一次可以打印多个数据
- 不能解析标签
- 不会阻塞程序执行
数据类型
- 数据类型:
- 为了让计算机方便的存储或执行指定的数据,将数据进行分类,分类之后形成了数据类型
- 分类:
数值型(number)
:0,1,2,3,4,5,6,7,8,9,NaN字符型(string)
:所有被引号包裹的数据,双引号",单引号’,反引号`布尔型(boolean)
:真true,假false对象型(object)
:是一种数据的无序集合,由键值对组成,一般标志是:{}函数型(function)
:表示功能的封装,一段代码的集合,标志是:functionundefined(undefined)
:undefined,没有值,但是该变量已存在(变量声明了,但未赋值)null(object)
:null,是一个空指向
- 如何检测数据类型
- 关键字:typeof
- typeof 要检测的数据
- typeof(要检测的数据)
- 关键字:typeof
运算符
-
算术运算符
+
,-
,*
,/
,%
+
号:两边只要有一个数据是字符,那么运算规则就是字符串的拼接-
,*
,/
,%
:将两边的数据,转成数值后,再进行数值运算- 运算过程中,自动将原本的数据类型作为其他数据类型进行运算,这种现象叫:隐式数据类型转换
- NaN:not a number:不是数字的数值型数据,表示非法的错误的数值转换
// var a = "10"; // var b = 3; // console.log(a + b); // 103 +有字符表示拼接 // console.log(a - b); // 7 将字符转数字再运算 // console.log(a * b); // 30 // console.log(a / b); // 3.3333333.... // console.log(a % b); // 1 // var a = "10"; // var b = "3"; // console.log(a + b); // 103 // console.log(a - b); // 7 // console.log(a * b); // 30 // console.log(a / b); // 3.3333333.... // console.log(a % b); // 1
-
关系运算符(比较运算符)
>
,>=
,<
,<=
,==
,===
,!=
,!==
>
,>=
,<
,<=
,==
,!=
:两边只要有一个是数值,那就按照数值的比较规则比较,两边都是字符,那就按照字符的比较规则,比较- 字符的比较规则:逐位按照ASCII码比较,得到结果就停止比较
===
,!==
:严格比较,不仅比较大小,还比较类型(没有隐式类型转换)
-
逻辑运算符
||
,&&
,!
- …
-
赋值运算符
=
,+=
,-=
,*=
,/=
,%=
- =号赋值和算术运算符的缩写
- 隐式类型转换规则,参考算术运算符
- 使用算术运算符计算之后,再存回(覆盖)原变量
-
一元运算符
- 自增
++
,自减--
- 每次增加或减少1
- 前:先计算,后使用
- 后:先使用,后计算
- 自增
数据类型的转换
- 如果当前需求的数据类型是A类型,但是程序计算的结果是B类型,只能转换
-
隐式类型转换:运算过程中,程序自动将已知数据作为其他类型操作
-
场景:
- 运算符
-
规则:
-
其他转字符
- 利用+号
- 除了对象显示object,其他的都原样显示
var a = ""; console.log(a + 1); // 1 console.log(a + true); // true console.log(a + {name:"admin"}); // [object object] console.log(a + [1,2,3]); // 1,2,3 console.log(a + function(){}); // function(){} console.log(a + undefined); // undefined console.log(a + null); // null console.log(a + NaN); // NaN
-
其他转数值
-
利用-号
var a = 0; console.log( "abc" - a ); // NaN console.log( "123" - a ); // 123 console.log( "123abc" - a ); //NaN console.log( true - a ); // 1 console.log( false - a ); // 0 console.log( {} - a ); // NaN console.log( [] - a ); // 0 console.log( [1,2,3] - a ); // NaN console.log( [3] - a ); // 3 console.log( ["hello"] - a ); // NaN console.log( undefined - a ); // NaN console.log( null - a ); // 0 console.log( function(){} - a ); //NaN
-
-
其他转布尔
-
-
-
强制(显示)类型转换
-
其他转字符
- xxx.toString(); 直接转成字符
var num = 123.456; console.log(typeof num); // number console.log(num); // 123.456 var str = num.toString(); console.log(typeof str); //string console.log(str); // 123.456
- xxx.toFixed(); 保留小数点位数,返回值为一个字符
// 保留n位小数,不够就补0,多了就四舍五入 console.log(typeof num); // number console.log(num); // 123.456 var str = num.toFixed(5); // 保留五位小数,返回的是字符 console.log(typeof str); // string console.log(str); // 123.45600
- String(xxx);将其他类型转成字符
- 默认情况下,对象直接转字符,得到:[object Object]
- 其他类型相当于直接套了个引号
// 其他转字符 console.log(String(123)); //123 console.log(String(123.456)); // 123.456 console.log(String(true)); // true console.log(String({})); // [object object] console.log(String({ name: "admin" })); // [object object] console.log(String([])); // console.log(String([1, 2, 3])); //1,2,3 console.log(String(["hello"])); // hello console.log(String(function () {})); // function(){} console.log(String(undefined)); // undefined console.log(String(null)); // null console.log(String(NaN)); //NaN
-
其他转数值
- 严格:只要出现非数字,就是NaN
- 非严格:从左向右依次转换,能转则转,不能转就停止,第一位就不能转,直接NaN
- parseInt()
- 非严格,不能识别小数点
// parseInt(par) 函数转成数字 var str = "123"; // 123 var str = "123.789"; // 123 var str = "123abc"; // 123 var str = "abc123"; // NaN var str = "123abc456"; // 123 var str = "abc"; // NaN console.log(typeof str); // console.log(str); // var num = parseInt(str); // console.log(typeof num); console.log(num);
- parseFloat()
- 非严格,能识别小数点
var str = "123"; // 123 var str = "123.789"; // 123.789 var str = "123abc"; // 123 var str = "abc123"; // NaN var str = "123abc456"; // 123 var str = "abc"; // NaN // console.log(typeof str); // console.log(str); var num = parseFloat(str); console.log(typeof num); console.log(num);
-
Math.round()
- 严格,四舍五入取最近的整数,只要出现非数字,就是NaN;
var str = "123"; // 123 var str = "123.789"; // 124 var str = "123abc"; // NaN var str = "abc123"; // NaN var str = "123abc456"; // NaN var str = "abc"; // NaN // console.log(typeof str); // console.log(str); var num = Math.round(str); console.log(typeof num); console.log(num);
-
Number()
- 严格
- undefined,NaN,对象,函数,有多个数据的数组,有字符数据的数组都是NaN
- true转1,false转0
- 空数组转0,有一个数字的数组转成这个数字的数值
- null转0
var str = "123"; // 123 var str = "123.789"; // 123.789 var str = "123abc"; // NaN var str = "abc123"; // NaN var str = "123abc456"; // NaN var str = "abc"; // NaN var str = []; // 0 var str = [3]; // 3 // console.log(typeof str); // console.log(str); var num = Number(str); console.log(typeof num); console.log(num);
-
console.log( Number(true) ) //1
console.log( Number(false) ) // 0
console.log( Number(null) ) //0
console.log( Number(undefined) )//NaN
console.log( Number(NaN) ) // NaN
console.log( Number(function(){}) )//NaN
console.log( Number({}) ) //NaN
console.log( Number({name:“Admin”}) )//NaN
console.log( Number([]) ) //0
console.log( Number([1,2,3]) ) //NaN
console.log( Number([3]) ) //3
console.log( Number([“hello”]) ) // NaN
```
-
其他转布尔
- Boolean()
- 字符转布尔:非空字符为true
- 数值转布尔:非0和非NaN,为true
- 对象,数组,函数都是true
- undefined,null,NaN都是false
- Boolean()
三目运算符和NAN
- 三元运算符
- 变量 = 条件 ? 值1 : 值2;
- var a = n > 10 ? n : “0” + n;
- 关于NaN
- isNaN()专门用来判断是不是NaN
- 有隐式类型转换:其他转数值,严格转换
- 关于if的小括号
- 有隐式类型转换:其他转布尔
背诵1
-
js中的数据类型有哪些,如何检测
- string,number,boolean,object,function,undefined,null
- typeof 数据
-
js有哪些内容组成,分别表示什么
- ECMAScript:语法,规范
- DOM:文档对象模型,document
- BOM:浏览器对象模型,window
-
常见的运算符有哪些
- 算术:+,-,*,/,%
- 关系:>,>=,<,<=,,=,!=,!==
- 逻辑:||,&&,!
- 赋值:=,+=,-=,*=,/=,%=
- 一元:++,–
- 三元:条件 ? 值1 : 值2
-
强制类型转换中字符转数值的方法有哪些
- parseInt()
- parseFloat()
- Math.round()
- Number()
-
其他转布尔的规则是什么
- 字符:非空为true
- 数值:非0位true
- 对象,数组,函数,都是true
- undefined,null,NaN,都是false
-
哪些语句可以实现分支结构
- if(){}
- if(){}else{}
- switch(){
case 值1:
语句1;break;
…
default:
默认语句;
}
-
如何将一个数字保留3位小数
- num.toFixed(3)
函数 - function
-
空调概念:由一堆电子元器件组成的,实现调节空气的功能,经过封装的,可以被开关或遥控器启动的家用电器
-
函数概念:由一堆代码组成的,实现某个功能,经过封装的,可以直接使用或行为调用的代码段
-
特点:
- 忽略细节
- 重复使用
- 选择使用
-
创建函数
- 声明式:声明关键字:function
- function 函数名(){ 一堆代码 }
- 赋值式:利用var变量赋值,创建函数
- var 变量名 = function(){ 一堆代码 }
- 区别:…
- 声明式:声明关键字:function
-
函数的执行
- 直接执行:
- 函数名()
- 行为执行:
- 行为,动作,事件
- 事件源.onclick = 函数名
- 直接执行:
-
函数的分类 - 写法
- 有名函数
- function 函数名(){}
- 正常函数,正常使用
- 无名函数
- function(){}
- 非正常函数,不能直接使用,只能作为值使用
- 作为赋值式创建函数的值
- 作为事件处理函数使用
- 作为参数使用,叫回调函数
- 作为返回值使用,叫闭包函数
- 作为匿名函数的函数体,使用
- 匿名函数
- (function(){})()
- 自执行函数
- 为了生成一个新的作用域
- 有名函数
-
js中的行为分类有哪些
- 鼠标类
- 左键单击:click
- 右键单击:contextmenu
- 左键双击:dblclick
- 按下:mousedown
- 抬起:mouseup
- 移动:mousemove
- 进入:mouseover / mouseenter
- 离开:mouseout / mouseleave
- 键盘类 - 只有有焦点的元素才能触发
- 按下:keydown
- 抬起:keyup
- 点击:keypress
- 浏览器类 - 加给window才能生效
- 加载:load
- 滚动:scroll
- 改变大小:resize
- 表单类 - 获取具体的表单控件
- 输入:input
- 获取焦点:focus
- 失去焦点:blur
- 内容改变:change
- 提交:submit
- 重置:reset
- 鼠标类
-
如何添加行为(事件)
- 事件源(页面上的元素,浏览器):
- 选择器:id选择器:document.getElementById(“id名”)
- on方式添加
- 事件源.on事件类型
- btn.onclick
- 设置事件处理函数
- 通过赋值的方式将函数赋值给指定的事件
- btn.onclick = 函数名
- btn.onclick = function(){}
- 事件源(页面上的元素,浏览器):
-
函数的入口 - 函数的参数
- 从函数外部向函数内部传输数据的方式
- 接收:函数定义时,接收的参数,叫形参
- 发送:函数执行时,发送的参数,叫实参
- 参数的位置:小括号内
- 参数的数量:
- 无数个,每两个参数之间用逗号隔开
- 实参和形参的数量一致,一一对应
- 形参多,多出来的形参是undefined
- 实参多,多出来的实参,通过arguments获取
- 参数的类型:
- 任意类型
- arguments是函数内部专属的对象,保存了当前所属函数的所有实参
- arguments虽然是对象,但以伪数组的形式存在
- 索引:数组[0]
- 长度:数组.length
- 配合循环解析arguments中所有的数据
- 当函数的参数个数不确定时,使用arguments找到所有参数
- arguments虽然是对象,但以伪数组的形式存在
- 参数的应用
- 计算3个任意数字的和
- 参数个数确定,使用具体的形参接收即可
- 计算任意个任意数字的和
- 参数的个数不确定,不适用形参接收,直接找arguments
- 别忘了解析arguments
- 参数的个数不确定,不适用形参接收,直接找arguments
- 计算3个任意数字的和
-
函数的出口 - 返回值
- 将函数内部的执行结果,返回到外部,函数的执行语句身上
- 如果函数没有主动设置返回值,默认返回undefined
- 通过关键字return
- return 要返回的数据或变量
- 方便将程序的执行结果进行二次使用或另做他用
- return的功能
- 返回值
- 立即结束函数
- 一个函数只能执行一次return
- 返回值的数量:
- 只能返回一个
- 一个函数只能执行一次return,一个return只能返回一个数据
- 返回值的类型:
- 任意类型
背诵2
- 函数的创建和执行
- 创建
- 声明式:function fn(){}
- 赋值式:var fn = function(){}
- 执行
- 直接执行:函数名()
- 行为执行:事件源.on事件类型 = 函数名/无名函数
- 创建
- 函数的参数分类和数量关系
- 形参和实参
- 一致,一一对应
- 形参多,多出来的形参是undefined
- 实参多,多出来的实参可以找arguments
- 如何实现函数的返回值,同时会造成什么后果
- return 要返回的数据
- 结束函数
- 程序的三大结构分别是什么,如何实现
- 顺序:默认结构
- 选择:分支语句:if(){},if(){}else{},switch(){}
- 循环:循环语句:while(){},do{}while(),for(){}
- 如何将数值3.1415926保留3位小数,并且类型依然为数值
- var num = 3.1415926;
- parseFloat(num.toFixed(3))
- 常见的事件由哪些(15+)
- 鼠标类:click,dblclick,contextmenu,mousemove,mouseover,mouseout,mousedown,mouseup,mouseenter,mouseleave
- 键盘类:keydown,keyup,keypress
- 表单类:input,change,focus,blur,submit,reset
- 浏览器类:load,resize,scroll
作用域
- 概念:变量或函数作用的区域,变量或函数生效的区域
- 作用域分类:
- 全局:不属于任何函数的区域
- 局部:属于某个函数的区域
- 作用域链(变量的读写规则)
- 基本的规则:
- 父不能访问子
- 子可以访问父
- 特殊规则:
- 变量的读取,先在自身作用域中查找,找到了就使用,没有找到,向上层作用域依次查找,找到了就停止查找,并使用,直到全局作用域都没找到,报错
- 变量的修改(写),先在自身作用域中查找,找到了就修改,没有找到,向上层作用域依次查找,找到了就停止查找,并修改,直到全局作用域都没找到,自动声明成全局(非严格模式下)
- 基本的规则:
- 变量的分类
- 全局作用域内的变量,叫全局变量
- 生命周期:随着程序的执行一直存在
- 占内存
- 方便
- 污染全局变量的命名空间
- 局部作用域内的变量,叫局部变量
- 生命周期:朝生暮死,跟随当前作用域的创建而创建,作用域的结束而删除
- 节省内存
- 麻烦
- 折中处理方案:
- 既能不多占内存,又能很方便的使用变量
- 利用匿名函数生成更大的作用域,包裹原有的全局变量和使用全局变量的功能
- 匿名函数:自执行函数
- 全局作用域内的变量,叫全局变量
声明提升
- 使用var声明的变量,都会提前到作用域最开始的位置声明。原位赋值
- 使用function声明的函数,整体提升到作用域最开始的位置
- 当var遇到function
- var声明的变量 和 function声明的函数 重名
- 这本来就是不被允许的
- var先提升,function后提升,所以function生效
- 赋值式创建函数
- 因为语法格式,var后有名字,所以var提升
- function后没有名字,所以function,没有提升
- var声明的变量 和 function声明的函数 重名
// (function(){
// console.log(a); //
// function a(){ 1 }
// console.log(a); //
// function a(){ 2 }
// console.log(a); //
// function a(){ 3 }
// console.log(a); //
// var a = "hello";
// console.log(a); //
// var a = function(){ 4 }
// console.log(a); //
// a = "world";
// console.log(a); //
// })();
// ↑↑↑等价于↓↓↓
// (function(){
// var a
// var a
// function a(){ 1 }
// function a(){ 2 }
// function a(){ 3 }
// console.log(a); // f3
// console.log(a); // f3
// console.log(a); // f3
// console.log(a); // f3
// a = "hello";
// console.log(a); // hello
// a = function(){ 4 }
// console.log(a); // f4
// a = "world";
// console.log(a); // world
// })();
对象1
-
对象:数据的无序集合,数据的打包形式
-
对象的组成(本质):键值对
- 所有可以被描述的客观存在的事物,都可以使用对象表示
-
对象的作用(意义):存储数据,编程
-
对象的优势:
- 提升了信息的查找速度
- 提升了信息的传输速度
-
对象的基本表示语法
- {键:值,键:值,…}
-
对象的创建
- 字面量:
- var obj = {}
- 构造函数:
- var obj = new Object();
- 字面量:
-
对象的操作语法:
- 点语法:当对象的属性是一个具体的值时
- .
- 对象.属性名
- 对象. 属性名 = 值
- 中括号语法:当对象的属性不是一个具体的值,是一个变量时
- []
- 对象[存储了属性名的变量]
- 对象[存储了属性名的变量] = 值
- 删除对象的属性:
- 关键字:delete
- delete 对象.属性
- 关键字:delete
- 点语法:当对象的属性是一个具体的值时
-
构造函数
- 构造函数不是一种新的函数写法,是函数的一种新的执行方式
- new执行
- 一般情况下,函数名中首字母被大写的函数(大驼峰),可以被new执行
- 如:Object(),String(),Number(),Boolean(),Function(),Array(),Date(),RegExp(),…
- new执行的结果必然是对象
- 构造函数不是一种新的函数写法,是函数的一种新的执行方式
-
对象的分类
- 宿主对象:寄生于某个平台的对象,document,window
- 本地对象:ECMA自带的,是数据的映射,可以直接使用,可以执行使用,还可以new使用
- Object,Number,String,Boolean,Array,Function,Date,RegExp
- 内置对象:ECMA自带的,可以直接使用的,不需要经过处理的对象
- Math
- JavaScript的顶层对象
- window
- js中所有的全局变量或函数,都会自动绑定到window
- 给window添加的属性或方法,都会自动声明成全局(哪怕是在局部给window添加)
- 一般情况下,window可以被省略
-
对象的属性,保存的是数据,类似于变量
-
对象的方法,保存的是功能,类似于函数
背诵3
-
函数的分类及各自的特点
- 有名函数:正常函数,正常使用
- 无名函数:非正常函数,不能直接使用,只能作为值使用
- 赋值式创建函数的值
- 事件处理函数
- 作为参数
- 作为返回值
- 作为匿名函数的函数体
- 匿名函数:会自动执行,利用匿名函数开启新的作用域
-
什么是作用域链
- 读写变量时,先从自身作用域开始查找,依次向上级作用域查找,任意一层找到了就使用,并停止查找,直到全局作用域,如果都没有找到,读,会报错;写,会自动声明成全局
-
什么是声明提升,规则是什么
- var的声明提升:提前到作用域最开始的位置声明,原位赋值
- function的声明提升,整体提升到作用域最开始的位置
-
什么是递归,有什么特点
- 在函数内部调用自身
- 消耗大量的性能
- 使用递归表达编程思维
-
对象的本质和意义本分是什么
- 本质:键值对
- 意义:存储数据和编程
-
内置的构造函数有哪些
- String()
- Number()
- Boolean()
- Object()
- Array()
- Function()
- Date()
- RegExp()
-
对象的操作语法及其使用场景
- 点语法:当对象的属性是具体的值时
- 中括号语法:当对象的属性不是具体的值时,是变量时
数组
-
数组:数据的组合,数据的有序集合
- 数组内的数据,默认都是有编号的(索引,下标,序号),从0开始,依次递增
- 数组内所有数据的总数量用length表示,意味着最后一个数据的索引是length-1
- 数组的意义:当有多个数据需要处理,但是只能处理一个数据时,将数据打包成数组
-
创建数组
- 字面量:var arr = [];
- 构造函数:var arr = new Array();
- 区别:有且只有一个数值型数据时,字面量认为这就是一个数据,构造函数认为是数组的长度
-
数组的操作
-
直接操作:索引配合长度 *****
- 查:…
- 增:insert(arr, index, data)
function insert(arr, num, data){ for(var i=arr.length;i>num;i--){ arr[i] = arr[i-1]; } arr[num] = data; }
- 改:…
- 删:del(arr, index)
function del(arr, num){ for(var i=num;i<arr.length-1;i++){ arr[i] = arr[i+1]; } arr.length = arr.length-1; }
-
内置方法操作
- 方法:属于某个对象的函数叫方法
- 数组的方法
- 数组的内置方法
- push 末尾增加,传入增加的数据,返回数组的长度,改变原数组
- unshift 首位增加,传入增加的数据,返回数组的长度,改变原数组
- shift 首位删除,无参数,返回删除了的数据,改变原数组
- pop 末尾删除,无参数,返回删除了的数据,改变原数组
- slice (m,n) 截取,传入截取的起点和终点(包头不包尾,尾不写到最后),返回截取出来的新数组,不改变原数组
- splice(index,num) 删除并替换,传入开始删除的位置,删除的个数,替换的数据,不写个数删除到最后,不写替换就不替换,返回删除的数据,改变原数组
- join 将数组中的数据按照指定的符号连接成字符,传入一个符号,返回连接后的字符,不改变原数组
- reverse 翻转数组,不传入参数,返回翻转之后的数组,改变原数组
- concat 合并数组,传入需要合并的数组,返回合并之后的数组,不改变原数组
- sort 排序,传入一个回调函数(可选),自身又接收两个形参,回调函数需要主动返回两个形参之差。不写,默认字符的比较规则,返回排序之后的数组,改变原数组
- …
- xxx的方法的学习方式:
- 功能:
- 参数:
- 返回值:
- 是否改变原数组:
-
-
数组的分类
- 对数据进行分类之后,按照不同的类型存储在不同的数组中
- 都是字符的数组,叫字符数组
- 都是数值的数组,叫数值数组
- 都是对象的数组,叫对象数组(json数组)
- 都是数组的数组,叫数组数组(二维数组,多维数组)
- 复杂数组的操作
- 逐层解析
-
栈堆
- 内存中的存储单元
- 栈:一般存储堆地址,类似于身份证
- 先进后出的读写规则
- 一般存储变量名或某些基本数据或复杂数据的地址
- 空间较小,比较稳定,不可被修改
- 堆:一般存储数据,你家的房子
- 先进先出的读写规则
- 一般储存数据,被栈指向
- 空间较大,可被修改
- 栈和堆,一一对应,可以多对一,不能一对多
-
值传递和引用传递
- 根据数据在内存中的存储形式划分
- 值传递(基本数据)
- 字符,数值,布尔,undefined,null
- 值就是地址,地址就是值,都存在栈中
- 因为值就是地址,地址就是值,所以复制时,直接复制即可
- 引用传递(复杂数据)
- 对象,函数,数组
- 地址是地址,值是值,地址存在栈中,值存在堆中
- 栈中的地址指向了堆中的数据
- 因为地址是地址,值是值,所以,复制时,默认复制的是地址
- 导致,如果根据其中一个地址修改了数据,另一个地址指示的数据也会发生变化
- 这种现象叫:浅拷贝
- 值传递(基本数据)
- 根据数据在内存中的存储形式划分
-
引用传递的深浅拷贝
- 浅拷贝:只拷贝地址,不拷贝值
- 深拷贝:拷贝值
- 遍历老对象,逐个拷贝老对象的值,到新的对象
-
对象的遍历
- 对象是数据的无序集合,无法通过循环遍历
- 新的遍历方式:for-in
for(var i in obj){ i是遍历的对象的键(属性) obj[i] }
背诵4
-
数组的创建和区别
- 字面量:var arr = []
- 构造函数:var arr = new Array()
- 有且只有一个数值型数据时,字面量认为就是数据,构造函数认为是数组的长度
-
什么是栈堆,之间有什么关系
- 都是内存的存储单元
- 栈:一般保存变量名,或堆的地址,稳定不可修改,空间小
- 堆:一般保存数据,空间大,可被修改,被堆中的地址指向
- 关系:一对一,多对一,不能一对多
-
数组的方法有哪些,分别是什么功能(15+)
- push unshift pop shift slice splise concat join reverse sort
-
什么是值传递,什么是引用传递,代表数据有哪些
- 值传递(基本数据):复制时复制的是值,值就是地址,地址就是值
- string,number,boolean,undefined,null
- 引用传递(复杂数据):复制时复制的是地址,地址是地址,值是值
- object,function,array
- 值传递(基本数据):复制时复制的是值,值就是地址,地址就是值
-
什么是深浅拷贝,如何实现深拷贝
- 浅拷贝:只拷贝地址
- 深拷贝:拷贝值
- 实现:解析复杂数据,拿到内部的值,拷贝值
- 遍历数组或对象
- 数组的遍历:循环
- 对象的遍历:for-in
-
对象的优势是什么
- 提升了信息的传输速度
- 提升了信息的查找速度
-
对象和数组的区别是什么
- 对象是数据的无序集合
- 数组是数据的有序集合
ECMAScript5
-
严格模式
- 开启:作用域的第一行,添加字符串:“use strict”
- 当前作用域就会处于严格模式下
- 建议开启方式:利用匿名函数生成一个独立作用域,开启严格模式
- 严格模式开启之后的变更
- 1.变量必须先声明,再使用。
- 2.不允许参数重复
- 3.arguments保存的实参不受形参改变而影响。
- 4.没有明确隶属对象函数中的this指向undefined
- 5.禁止使用0开头的数值表示8进制
- 6.with语句不允许使用
- 7.不允许通过arguments.callee找到自身
- 开启:作用域的第一行,添加字符串:“use strict”
-
数组的方法
- indexOf(data,start) 从左到右根据数据查索引,返回查询的数据,查询不到返回-1,不会改变原数组
- lastIndexOf(data,start) 从右向左根据数据,查索引,返回查询的数据,查询不到返回-1,不会改变原数
- forEach 数组遍历的方法,回调函数有三个参数,val,index,arr 没有返回值,不改变原数组。
var arr = ["a","b","c","d","c","a","b","d"]; console.log(arr); var result = arr.forEach(function(val, idx, self){ console.log(val, idx, self); });
-
map 遍历,并根据原数组创建出新数组,回调函数参数一样,返回一个新数组,不改变原数组
var result = arr.map(function(val, idx, self){ console.log(val, idx, self); return val });
-
filter遍历,并从原数组中过滤出符合条件的新数组回调函数参数一样,数组内是返回值为true时的回调函数遍历到的数据。返回一个新数组,不改变原数组
-
some 遍历,并查询,找到了,根据需求,单独处理,回调函数一样,返回值是boolen值,只要有一个是true,那就是true,全部为false,才是false(查找数组中是否包含某个元素)
-
every 只要有一个是false,那就是false,全部为true,才是true(是否所有元素都满足特定条件)
字符
-
字符的创建
- 字面量:var str = “hello”
- 构造函数:var str = new String(“hello”);
- 说明:构造函数方式创建出的字符虽然被typeof检测出object,但是可以作为正常字符使用
-
字符的操作 - 不会被修改原字符
- 直接操作
- 索引+length
var str = "hello world"; str[0]
- 方法操作
- indexOf 根据数据查位置.
- lastIndexOf 根据数据查索引
- contact 合并字符串
- slice(m,n) 从m截取到n
- substring(m,n) 从m截取到n
- substr(m,m) 从m开始截取n个
- replace(old,new) 替换
- split 分割,用什么分割和join对立
- 直接操作
内置对象 - Math
- Math是数学对象,提供了各种数学操作
- 属性
- 圆周率:Math.PI
- 方法
- 绝对值:Math.abs()
- 四舍五入取最近的整数:Math.round()
- 0~1之间的随机数(不含):Math.random()
- 向上取整:Math.ceil()
- 向下取整:Math.floor()
- 开平方:Math.sqrt()
- 幂次方:Math.pow()
- 取最大值:Math.max()
- 取最小值:Math.min()
- 正弦:Math.sin()
- 余弦:Math.cos()
- 正切:Math.tan()
- 范围随机数
- Math.round(Math.random()*(b-a)+a)
本地对象 - Date
-
日期对象:Date,获取系统日期
-
获取日期:将日期格式化,显示常见的日期格式,或单独使用某个部分
- 创建日期对象
- var d = new Date();
- 获取日期的每个部分
- get系列…
console.log(d.getFullYear()); console.log(d.getMonth()); // 0~11 console.log(d.getDate()); console.log(d.getDay()); // 0~6 console.log(d.getHours()); console.log(d.getMinutes()); console.log(d.getSeconds()); console.log(d.getMilliseconds()); // 时间戳 console.log(d.getTime()); console.log(Date.now());
- 创建日期对象
-
设置日期:获取指定日期
- 创建时
- var data = new Date(“2020.01.09”)
// 创建时 // 字符参数 // 个数:1个 // 没有设置的部分:清0 // 超出上限部分:Invalid Date // 月份范围:1~12 var d = new Date("2008.8.8"); var d = new Date("2008.8.8 8:8:8"); var d = new Date("2008.8.32 8:8:8"); // 数值参数 // 个数:多个 // 没有设置的部分:清0 // 超出上限部分:向前进1 // 月份范围:0~11 var d = new Date(2008, 8, 8); var d = new Date(2008, 8, 8, 8, 8, 8); var d = new Date(2008, 8, 32);
- 创建后
- 利用set系列进行设置
// 创建后 // 没有设置的部分:以当前日期为准 // 超出上限部分:向前进1 // 月份范围:0~11 // var d = new Date(); // set系列 // d.setFullYear(2008); // d.setMonth(8); // d.setDate(32); // d.setHours(8); // d.setMinutes(32); // d.setSeconds(32); // d.setMilliseconds(32); // console.log(d); // console.log(d.getMilliseconds()) // 直接设置时间戳 // 设置从1970年1月1号 0:0:0秒过去了的毫秒数 // var d = new Date(); // d.setTime(100000000000); // console.log(d);
- 创建时
-
计算两个日期之间的差值
- 利用时间戳进行计算
var d1 = new Date("2008.8.8 8:0:0") var d2 = new Date("2021.7.1 8:0:0") // 有兼容:两个日期对象直接计算 // console.log(d1 - d2); console.log(d1.getTime()) console.log(d2.getTime()) // 先获取指定日期的时间戳,再计算差值 console.log(d1.getTime() - d2.getTime())
计时器
- 计时器
- 开启
- setInterval(回调函数, 毫秒数)
- 功能:每隔指定的毫秒数,执行一次回调函数
- 参数:参数1:回调函数,参数2:毫秒数
- 返回值:当前计时器的唯一标志,用来被清除
- 关闭
- clearInterval(要清除的计时器的唯一标志)
- 开启
- 延时器
- 开启
- setTimeout(回调函数, 毫秒数)
- 功能:延迟指定的毫秒数,只执行一次回调函数
- 参数:参数1:回调函数,参数2:毫秒数
- 返回值:当前延时器的唯一标志,用来被清除
- 关闭
- clearTimeout(要清除的延时器的唯一标志)
- 开启
背诵5
-
字符的方法有哪些(10+)
- str.indexOf() 根据字符查询索引
- str.charAt() 返回指定位置的字符
- str.slice() 从m查询到n
- str.substring() 从m查询到n
- str.substr() 从m查寻n个
- str.replace() 替换
- str.split() 用字符进行分割字符串
- str.concat() 字符串连接
- str.search() 检索与正则表达式相匹配的值
- str.match() 找到一个或多个正则表达式的匹配
- str.charCodeAt() 返回指定索引位置字符的 Unicode 值
-
ES5新增的严格模式下的变更
- 变量必须先声明再使用
- 函数的形参不允许重复
- arguments保存的实参不受形参的改变而影响
- arguments.callee不允许使用
- 没有明确隶属对象的函数中的this不指向window
- 进制使用0开头的数值表示八进制
- 进制使用with语句
-
ES5新增的数组的方法
- arr.indexOf()
- arr.forEach()
- arr.map()
- arr.filter()
- arr.some()
- arr.every()
- arr.reduce()
-
对象的分类,并举例说明
- 宿主:window,document
- 本地:String,Number,Object,Date
- 内置:Math
-
如何获取范围随机数
- Math.round(Math.random()*(max-min)+min)
-
如何获取3天之后的日期对象
- var d = new Date();
- d.setDate(d.getDate() + 3)
- d
-
如何将十六进制"3ae"转成二进制
- parseInt(“3ae”, 16).toString(2);
BOM
-
概念:
- js的三大组成之一:BOM:浏览器对象模型,浏览器的抽象,提供了浏览器的各种操作,这个对象是window,因为js运行在浏览器中,所以window是js的顶层对象
- window提供了浏览器窗口之间的操作
- BOM缺乏标准,沿用了ECMAscript的标准,提出一些小的修改或变更
- window包含了浏览器所有的功能内容,并将一些重要内容再次抽象成对象,称为window的子对象
- window的子对象有:document,history,location,navigator,screen,frames
- window还具有一些自身的方法或功能
-
window自身的方法和事件
- 方法:属于对象的函数,叫方法
- window的方法,属于window的函数,就是全局函数
- parseInt()
- parseFloat()
- isNaN()
- typeof()
- setInterval()
- setTimeout()
- clearInterval()
- clearTimeout()
- alert()
- …
- confirm()
- prompt()
- open()
- close()
- 事件:window表示浏览器,浏览器的事件
- load
- resize
- scroll
- 方法:属于对象的函数,叫方法
-
window的子对象的使用
- document
- history:浏览器的历史记录
- 查看当前历史记录个数:history.length
- 后退:history.back()
- 前进:history.forward()
- 去哪:history.go(n); n为正,前进;n为负,后退;n为0,刷新
- location:当前窗口的地址(url)
- 查看或设置地址:
- location.href
- 重新赋值会导致页面跳转
- 查看或设置地址的某个部分:
- 域名+端口:location.host
- 域名:location.hostname
- 端口:location.port
- 路径:location.pathname
- 查询数据:location.search
- 锚点链接:location.hash
- 重新赋值会导致页面跳转
- 刷新:
- location.reload()
- 跳转:
- 跳转到当前页面:location.assign("")
- 跳转到指定URL:location.assign(“url”)
- 查看或设置地址:
- navigator
- screen
// 当前浏览器的可视区域的尺寸 var clientW = document.documentElement.clientWidth; var clientH = document.documentElement.clientHeight; console.log(clientW, clientH); // 浏览器滚走了的距离 var scrollT = document.documentElement.scrollTop; var scrollL = document.documentElement.scrollLeft; console.log(scrollT, scrollL);
- frames
DOM
-
概念
- DOM,文档对象模型,document,是页面的抽象,是js操作页面的入口
- DOM的规范是W3C提供
- DOM是页面的抽象,DOM的结构等同于页面的结构,树状结构(家族结构)
- DOM结构的每个组成成分都叫,节点。每个节点的数据类型都是对象
- 根据不同的成分,称为不同的节点
- 标签(元素)节点
- 文本节点
- 注释节点
- 属性节点
- 根节点
- 根据不同的成分,称为不同的节点
- js是行为语言,控制页面产生行为,页面上有各种节点,选择器选中其中一个节点之后,操作节点的属性,样式,内容,标签自身
-
选择器
-
根据选择的节点类型划分
- 元素节点选择器:
- id,className,tagName,name,query,queryAll,children,parentNode,previousElementSibling,nextElementSibling,body,head,firstElementChild,lastElementChild
- 其他节点选择器
- 根节点:document
- …
- 元素节点选择器:
-
根据选择到的元素的个数划分
- 单个节点选择
- id,query,parentNode,previousElementSibling,nextElementSibling,document,body,head,firstElementChild,lastElementChild
- 多个节点选择器:一定要解析数组之后才能操作元素
- className,tagName,name,queryAll,children
- 单个节点选择
-
根据选择的关系划分
- 直接选择:
- id,className,tagName,name,query,queryAll,document,body,head
- 间接选择:
- children,parentNode,previousElementSibling,nextElementSibling,firstElementChild,lastElementChild
// id:选择到的是单个元素,就算有多个元素符合条件,也是只能选中第一个元素 var oBox = document.getElementById("box"); console.log(oBox); oBox.style.background = "red" // className:选择到的是数组形式,就算没有符合条件的元素,也是数组形式 var aCont = document.getElementsByClassName("cont"); console.log(aCont); aCont[0].style.background = "yellow" aCont[1].style.background = "yellow" aCont[2].style.background = "yellow" // tagName var aSpan = document.getElementsByTagName("span"); console.log(aSpan) // name:只有表单元素才有name属性 var aPass = document.getElementsByName("password"); console.log(aPass); // ES5新增:支持css选择器写法 // query var ele = document.querySelector("#box") var ele = document.querySelector(".cont") var ele = document.querySelector("span") console.log(ele); // queryAll var ele = document.querySelectorAll(".cont") console.log(ele); var omsg = document.getElementsByClassName("msg")[0]; var omsg = document.querySelector(".msg"); var olist = document.querySelector(".list"); // 子元素选择器 console.log(omsg.children); console.log(olist.children); console.log(olist.firstElementChild); console.log(olist.lastElementChild); // 父元素选择器 var oXbox = document.querySelector(".xbox") console.log(oXbox.parentNode); // 兄弟元素选择器 var omsg = document.querySelector(".msg"); console.log(omsg.previousElementSibling); console.log(omsg.nextElementSibling); // 根元素 var omsg = document.querySelector(".msg"); console.log(document); console.log(omsg.ownerDocument); // 特殊元素选择器 console.log(document.body); console.log(document.head); // 直接操作title标签的内容 console.log(document.title);
- 直接选择:
- 节点的过滤(相对其他DOM的知识点来说,不那么重要)
-
- | nodeType | nodeName | nodeValue |
---|---|---|---|
元素节点 | 1 | 大写的标签名 | null |
属性节点 | 2 | 属性名 | 属性值 |
文本节点 | 3 | #text | 文本内容 |
注释节点 | 8 | #comment | 注释内容 |
根节点 | 9 | #docuemnt | null |
-
样式操作
- 行内样式 - 专用于设置
- 作为html标签的style属性操作:
<span style="width:100px"></span>
- 获取:obox.style.xxxxxxx
- 设置:obox.style.xxx = “”
- 作为html标签的style属性操作:
- 非行内样式 - 专用于获取
- 没有写在html标签的style属性内
- 正常浏览器获取:getComputedStyle(obox).xxxxxx
- IE浏览器获取:obox.currentStyle.xxxxxx
- 设置:无法设置
- 样式的最终操作:
- 使用非行内操作获取样式
- 封装获取非行内样式的兼容处理
- 使用行内操作设置样式
- obox.style.xxx = “xxx”
- 使用非行内操作获取样式
- 样式没有删除操作,只有清空或重置
// 行内样式的操作 var obox = document.querySelector(".box") // 获取 console.log(obox.style); console.log(obox.style.width); console.log(obox.style.height); console.log(obox.style.background); console.log(obox.style.border); // 无法获取非行内 // 设置 obox.style.width = "200px"; obox.style.border = "solid 20px yellow"; // 非行内样式的操作 // 获取 // console.log(getComputedStyle(obox)) // console.log(getComputedStyle(obox).border); // console.log(getComputedStyle(obox).width); // 可以获取行内 // 设置(非行内样式无法设置) // getComputedStyle(obox).width = "200px"; // 正常浏览器:getComputedStyle // IE低版本浏览器:obox.currentStyle // console.log(obox.currentStyle) // 非行内样式获取的兼容封装 function getStyle(ele, attr){ if(ele.currentStyle){ return (ele.currentStyle[attr]); }else{ return (getComputedStyle(ele)[attr]); } } // console.log(getStyle(obox, "width")) // console.log(getStyle(obox, "height")) // console.log(getStyle(obox, "background")) // console.log(getStyle(obox, "border")) // 快速设置行内样式 // obox.style.width = "200px"; // obox.style.height = "200px"; // obox.style.background = "yellow"; // obox.style.color = "green"; // obox.style.fontSize = "60px"; // obox.style.cssText = "width:150px;height:150px;font-size:30px;color:green;background:yellow";
- 行内样式 - 专用于设置
-
属性操作
-
html属性:直接写在html标签上的属性
<span class="box" title="这是title" abc="这是自定义的abc"></span>
- ospan.title
-
js属性:不是直接写在标签内的属性
<span></span>
- ospan.innerHTML
- ospan.abc
-
无论是html属性还是js属性,又都分为内置和自定义
- 所有的内置属性,都可以使用对象的操作来操作
- 自定义的js属性,也可以使用对象的操作来操作
- 所有的HTML属性,都可以通过getAttribute() | setAttribute() | removeAttribute()操作
-
属性分类(有哪些属性)(内置)
- 所有的DOM操作,都属于属性操作,不可能一口气把所有属性学完,会在其他知识点中不断的补充属性分类
- html属性,分标签
- id,className,title,src,href,type,value,…
- js
- …
// 各种属性的操作测试 // var obox = document.getElementsByClassName("box")[0]; // html的内置 console.log(obox.title); obox.title = "修改之后的title"; // js的自定义 console.log(obox.abc); obox.abc = "hahahahah"; console.log(obox.abc); // html的内置 console.log(obox.getAttribute("title")); obox.setAttribute("title", "又一次修改之后的title") // html的自定义 console.log(obox.getAttribute("abc")); obox.setAttribute("abc", "修改之后的abc") // // js的内置 // console.log(obox.innerHTML); // obox.innerHTML = "world" // html的自定义 console.log(obox.getAttribute("innerHTML")); obox.setAttribute("innerHTML", "qqqqq") // 对象的操作:直接查看,是获取;重新赋值,是设置 // 方法操作:getxxxx获取,setxxxxxx设置,removexxxxxx删除 // ================= // js内置属性分类 var obox = document.getElementsByClassName("box")[0]; // 标签内容(可以解析标签) console.log(obox.innerHTML); obox.innerHTML = "<b>加粗的文字</b>"; // 标签内容(不能解析标签) console.log(obox.innerText); // obox.innerText = "<b>加粗的文字</b>"; obox.innerText = "这是文字这是文字这是文字这是文字这是"; // class名 console.log(obox.className); obox.className = "hahahah box" // 获取标签名字 console.log(obox.tagName); // 获取包含padding和border的尺寸 console.log(obox.offsetWidth); // 获取包含padding的尺寸 console.log(obox.clientWidth); // 获取包含可滚动区域的尺寸 console.log(obox.scrollHeight); // 获取元素相对于包含块偏移的位置(不止margin和position) console.log(obox.offsetLeft); document.onclick = function () { // 滚动时滚走了的距离 obox.scrollTop = 200; console.log(obox.scrollTop); }
-
-
内容操作
- innerHTML
- innerText
- value
-
标签操作
- 创建元素
- 插入元素
- 删除元素
- 修改元素
- 获取元素:选择器
// 这是一个字符,这不是元素 // var span1 = "<span></span>"; // console.log(span1) var obox = document.querySelector(".box"); // 创建元素 var span = document.createElement("span"); console.log(span); span.innerHTML = "这是一个span"; span.style.cssText = "font-size:30px"; // 插入元素 obox.appendChild(span); // 直接删除指定元素 obox.remove(); // 从父元素删除指定的子元素 document.body.removeChild(obox); // 改(不推荐使用) console.log(obox.outerHTML); obox.outerHTML = "<em>"+ obox.innerHTML +"</em>"
- 创建元素
背诵6
-
Math的常见方法有哪些
- Math.abs()
- Math.ceil()
- Math.floor()
- Math.sqrt()
- Math.pow()
- Math.max()
- Math.min()
- Math.round()
- Math.random()
- Math.sin()
- Math.cos()
- Math.tan()
-
如何获取昨天的日期对象
- var d = new Date()
- d.setDate(d.getDate()-1)
- d
-
计时器和延时器的开启和关闭
- 开启:
- setInterval(回调函数,毫秒数)
- setTimeout(回调函数,毫秒数)
- 关闭:
- clearInterval(计时器的唯一标志)
- clearTimeout(延时器的唯一标志)
- 开启:
-
window的子对象有哪些
- document:文档
- history:历史记录
- length:历史记录个数
- back():后退
- forward():前进
- go(n):正前进,负后退,0刷新
- location:地址
- href
- host
- hostname
- port
- search
- hash
- pathname
- reload()
- assign(url字符)
- navitagor:浏览器信息
- screen:视口尺寸
- frames:框架信息
-
刷新当前页面的方式有哪些
- history.go(0)
- location.reload()
- location.assign("")
-
如何浏览器的可视区域大小,及浏览器滚动时滚走了的距离
- document.documentElement.clientWidth
- document.documentElement.clientHeight
- document.documentElement.scrollTop
- document.documentElement.scrollLeft
-
DOM中的元素选择器有哪些(6+)
- document.getElementById()
- document.getElementsByTagName()
- document.getElementsByClassName()
- document.getElementsByName()
- document.querySelector()
- document.querySelectorAll()
- 父元素.children
- 第一个子
- 最后一个子
- 子选父
- 上一个兄弟
- 下一个兄弟
- body
- head
-
DOM的节点分类
- 根节点
- 元素节点
- 文本节点
- 属性节点
- 注释节点
-
window的方法和事件
- 方法
- alert()
- confirm()
- prompt()
- open()
- close()
- 事件
- load
- 页面结构和引入的资源全部加载完成
- resize
- 改变浏览器大小
- scroll
- 滚动浏览器
- load
- 方法
事件
- 事件源:绑定事件的元素
- 在事件处理函数中使用关键字this获取事件源
- 事件类型:该事件对应的行为
- 事件处理函数:事件发生时,要执行的功能
- 事件的绑定方式:
- 赋值式绑定事件:事件源.on事件类型 = 事件处理函数
- 事件对象
- 用来记录事件发生时,产生的相关信息的对象
- 事件对象默认隐藏,需要主动获取
- 正常浏览器:事件处理函数的第一个参数
- IE低版本浏览器:主动在window身上使用event属性
- 兼容处理:利用判断语句,如果其中有一种不存在,值必然是undefined
- 事件对象只能在事件处理函数中使用,事件处理函数外部,拿不到事件对象
- 事件对象只有在事件发生时,才被绑定,事件没有发生,事件没有对象
- 事件目标:触发事件的元素
- 没有事件冒泡的情况下:事件源和事件目标是同一个元素
- 有事件冒泡:事件源和事件目标不一定是同一个元素
鼠标事件对象的常用属性
- 相对于事件目标的坐标:e.offsetX / Y
- 相对于浏览器的可视区域的坐标:e.clientX / Y
- 相对于页面的坐标:e.pageX / Y
- 相对于显示器的坐标:e.screenX / Y
- 鼠标的按键:e.button
- 鼠标的按键:e.buttons
- 鼠标的按键:e.witch
- 事件目标:e.target
obox.onmousedown = function (eve) {// 第一个参数代表事件对象
var e = null;
if (eve) {
e = eve;
} else {
e = window.event;
}
console.log(e);
}
键盘事件对象的常用属性
- 获取按键的ASCII码(正常):e.keyCode
- 获取按键的ASCII码(IE):e.which
- 功能键ctrl / control键:e.ctrlKey
- 功能键shift键:e.shiftKey
- 功能键alt / option键:e.altKey
- 功能键win / command键:e.metaKey
默认事件
- 凡是不是开发者定义的,浏览器自带的行为或事件,叫默认事件
- 如:
- 文本域内回车会换行
- 右键菜单
- a标签的默认跳转
- 文字的选中
- 表单的重置按钮
- 表单的提交按钮
- …
- 如:
- 如何阻止默认事件(按需使用)
- 借助事件对象
- e.preventDefault();
- e.returnValue = false;
- 借助事件对象
var olist = document.querySelector(".list")
document.oncontextmenu = function(eve){
var e = eve ? eve : window.event;
// IE:e.returnValue = false;
// 正常:e.preventDefault();
console.log(e.preventDefault)
// 阻止默认事件
stopDefault(e);
// console.log(1);
olist.style.display = "block";
olist.style.left = e.pageX + "px";
olist.style.top = e.pageY + "px";
}
document.onclick = function(){
olist.style.display = "none";
}
// 阻止默认事件的兼容封装
function stopDefault(e){
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
}
事件流
-
事件的执行顺序
- 具有父子关系的嵌套元素,相同事件之间的执行顺序
- 先从外向内,事件捕获
- 然后目标阶段,真实要触发的元素的事件
- 最后从内向外,事件冒泡
- 事件冒泡,最初是由微软提出的,所以,IE低版本浏览器只支持冒泡
- 事件冒泡,浏览器默认的事件流的状态
-
事件冒泡
- 触发某个元素的某个事件时,会依次向上触发所有父元素的相同事件
- 如何阻止(按需使用)
- 借助事件对象
- e.stopPropagation();
- e.cancelBubble = true;
- 借助事件对象
背诵7
-
js如何操作html属性(增删改查)
- 增:ele.setAttribute(“名字”,“值”)
- 删:ele.removeAttribute(“名字”)
- 改:ele.setAttribute(“名字”,“新值”)
- 查:ele.getAttribute(“名字”)
-
如何获取非行内样式(兼容封装)
function getStyle(ele, attr){ if(getComputedStyle){ return getComputedStyle(ele)[attr] } return ele.currentStyle[attr]; }
-
如何创建元素a并插入到另一个元素b中
- var a = document.createElement(“div”);
- b.appendChild(a);
-
鼠标事件对象上的坐标类属性有哪些,分别相对于什么
- 相对于事件目标:e.offsetX / Y
- 相对于浏览器可视区域:e.clientX / Y
- 相对于页面:e.pageX / Y
-
键盘事件对象,如何获取键码,兼容处理
- e.keyCode ? e.keyCode : e.which
-
如何阻止默认事件(兼容封装)
function stopDefault(e){ if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } }
-
如何阻止事件冒泡(兼容封装)
function stopBubble(e){ if(e.stopPropagation){ e.stopPropagation(); }else{ e.cancelBubble = true; } }
事件的绑定方式
- 赋值式(DOM0级事件绑定):
- 绑定:事件源.on事件类型 = 事件处理函数
- 删除:事件源.on事件类型 = null
- 重复绑定,会覆盖
- 监听式(DOM2级事件绑定):
- 可以重复绑定
- 绑定:
- 正常:事件源.addEventListener(“事件类型”, 事件处理函数, 事件流的状态)
- IE:事件源.attachEvent(“on事件类型”, 事件处理函数)
- 删除:
- 正常:事件源.removeEventListener(“事件类型”, 事件处理函数, 事件流的状态)
- IE:事件源.detachEvent(“on事件类型”, 事件处理函数)
事件委托
- 将多个子元素的相同事件委托给页面上现存的共同的父元素,利用事件冒泡的原理,通过事件目标找到真正触发事件的元素
- 特点
- 节省性能
- 可以给页面上暂时不存在的元素绑定事件
- 注意
- 事件委托最好使用监听式绑定事件
- 如非特殊处理,在事件委托中无法使用this找到事件目标
- 事件源和事件目标的区别
- 找到子元素的方式有很多,不一定非得使用一种方式
- 事件目标的兼容:e.target | e.srcElement;
- 事件源:绑定事件的元素
- 事件目标:触发事件的元素
var obox = document.querySelector(".box")
obox.addEventListener("click",function(eve){
var e = eve ? eve : window.event;
// 获取事件目标
var target = e.target ? e.target : e.srcElement;
if(target.className === "abc"){
console.log(target.innerHTML);
// console.log(this)
}
})
背诵8
-
键盘事件时,如何获取键码,空格回车方向键的键码分别是多少
- e.keyCode
- e.which
- 32,13,37,38,39,40
-
什么是事件冒泡(概念)
- 会依次向上触发所有父元素的相同事件
-
什么是事件委托(概念)
- 将多个子元素的相同事件,委托给页面上现存的共同的父元素,利用事件冒泡的原理,通过事件目标找到真正触发事件的元素
-
绑定事件的方式有哪些,特点是什么,及兼容处理
- 赋值式:不能重复绑定,没有兼容
- 事件源.on事件类型 = 事件处理函数
- 监听式:能重复绑定,有兼容
- 正常:事件源.addEventListener(“事件类型”, 事件处理函数, 事件流的方向)
- IE:事件源.attachEvent(“on事件类型”, 事件处理函数)
- 赋值式:不能重复绑定,没有兼容
-
什么是事件源,什么是事件目标,什么情况下事件源等于事件目标,什么情况下不等于
- 事件源:绑定事件的元素
- 事件目标:触发事件的元素
- 没有发生元素嵌套时,事件源就是事件目标
- 发生的元素嵌套,触发了事件冒泡,事件源和事件目标不相等
-
事件流分为哪些阶段,按顺序书写
- 事件捕获
- 目标阶段
- 事件冒泡
-
对象的分类,并举例说明
- 本地对象:String,Number,Function,Boolean,Array,Object,Date,…
- 内置对象:Math
- 宿主对象:document,window
正则表达式
- 正则,字符的正确的规则,正则自身的数据类型是对象,正则表达式
- 用来约束字符的规则
- 正则的意义
- 节省操作,减少字符串的遍历和单独的处理
- 并没有提升性能,还会多消耗一些性能
- 正则的使用
- 查找:从一串字符中找到符合条件的子串
- str.match(reg);
- str.search(reg);
- reg.exec(str);
- 替换:从一串字符中找到符合条件的子串,并替换成其他字符
- str.replace(reg, newStr);
- 验证:检查一串字符是否符合规则要求
- reg.test();
- 正则的创建
- 字面量:var reg = /a/;
- 构造函数:var reg = new RegExp(“a”);
- 区别:
- 构造函数能根据变量的内容创建正则
- 如果构造函数创建正则时,接收的不是变量,那么必须写成字符的形式
- 正则的组成
转义字符
\d 数字0-9
\w 数字字母下划线
\s 空格
\D 非数字
\W 非数字字母下划线
\S 非空格
\ 将正则中有含义的符号转成普通字符
. 通配符
修饰符
g 全局
i 忽略大小写
量词
?0或1
+1或以上
*0或以上
{n}n次
{n,m} 至少n次,至多m次
| 或
[] 中元符,中元符内的的元素都是或的关系
[^] 表示非
/^ $/ 开头和结尾
// - 邮编
// var str1 = "123245";
// var reg = /^[1-9]\d{5}$/;
// console.log(reg.test(str1));
// - qq号
// var str = "2629812077";
// var reg = /^[0-9]\d{5,10}$/;
// console.log(reg.test(str));
// - 手机号
// var str = "15595310655";
// var reg = /^[1][3-9]\d{9}$/;
// console.log(reg.test(str));
// - 邮箱
// var str = "cbbgs_dd@qq.com.cn";
// var reg = /^\w{4,10}@[\w-]{2,10}(\.[a-z]{2,4}){1,2}$/;
// console.log(reg.test(str));
// - 固话
// var str = "0216-335340-098";
// var str = "335340-098";
// var str = "335340";
// var reg = /^([0]\d{4}-)?\d{6}(-\d{3})?$/;
// console.log(reg.test(str));
// - 网址
// var str = "https://www.baidu.com";
// var str = "http://www.baidu.com";
// var str = "www.baidu.com";
var str = "baidu.com";
var reg = /^(https?:\/\/)?([\w-]{3,10}\.)?[\w]{2,11}(\.[a-z]{2,5}){1,2}$/;
console.log(reg.test(str));
this
- this一般存在于函数中,表示当前函数的执行对象,是一个指向,只有在函数执行时才会绑定指向的内容,函数没有执行时,是没有任何绑定的
- 关于this的绑定
- 默认绑定:没有明确隶属对象的函数,执行时,内部的this指向window(非严格模式)
- 隐式绑定:有明确所属对象的函数,被所属对象执行时,内部的this指向执行对象
- 隐式丢失:将已经被隐式绑定this的函数,通过赋值传给了其他变量,此时通过其他变量执行函数,会造成this的隐式丢失,一般都是丢失到window身上
- 强制(显式)绑定:通过函数的方法,可以主动设置this的指向,设置成什么就是什么
- 修复隐式丢失:利用bind方法
- new绑定:使用new关键字执行函数,此时函数内的this指向new出来的实例(对象)
- 面向对象编程
// 默认绑定
function fun(){
console.log(this)
}
fun(); //window
// 隐式绑定
var obj ={
name:"admin",
fun:function(){
console.log(this)
}
}
obj.fun(); // obj
// 隐式绑定丢失
setInterval(obj.fun,1000); //window
var b = obj.fun; // obj
b(); //丢失
// 强制绑定 :通过函数的方法来绑定 有call apply bind
函数的方法
-
执行语法
function fn(){} fn.xxx()
-
分类
- 功能
- 参数
- 返回值
- 是否改变原数据:否
-
修复隐式丢失
var obj = { name : "obj", fun : function(){ console.log(this); } } var a = obj.fun; a(); // 隐式丢失 var b = a.bind(obj); var a1 = b(); console.log(a1) // 利用bind()方法来解决隐式绑定丢失的问题
window.onload = function(){
function fun(a,b){
console.log(a,b);
console.log(this);
return "hello";
}
// call()方法
// 第一个参数是规定this的指向
// 第二个至多个参数:是函数的真正参数。
// 返回值为函数的返回值
// var re = fun.call("this指向我","函数的参数1","函数的参数2");
// console.log(re)
// apply()方法
// 第一个参数是规定函数的指向
// 第二个参数是一个数组,这个数组的内容就是函数的参数
// 返回值是函数的返回值
// var re = fun.apply("this指向我",["函数的参数1","函数的参数2"]);
// console.log(re)
// bind()方法
// 第一个参数是规定this的指向
// 第二个方法乃至多个:是函数的真正参数
// 返回值是一个可执行函数,这个可执行函数的返回值是原函数的返回值
var re = fun.bind("this指向我","函数的参数1","函数的参数2");
var ret = re();
console.log(ret)
}
JSON
- json是一种通用数据,是一种有语法格式的记事本数据,与所有编程语言无关,但是每种编程语言都有对json的支持
- json的语法
- js中的json语法
- json数据必须是字符!一般使用单引号包裹
- 必须遵守js中对象或数组的基本格式要求
- 如果使用了js对象的语法,那么对象的key必须使用双引号包裹
- json中不允许出现没有意义的逗号
- json中不允许出现函数,undefined,NaN
- json文件(xxx.json)中的json语法
- 必须遵守js中对象或数组的基本格式要求
- 如果使用了js对象的语法,那么对象的key必须使用双引号包裹
- json中不允许出现没有意义的逗号
- json中不允许出现函数,undefined,NaN
- js中的json语法
- json和对象的转换
- json转对象:
- 先符合json格式要求
- var obj = JSON.parse(json);
- 对象转json
- 先符合对象格式要求
- var json = JSON.stringify(obj);
- json转对象:
ES6
-
声明关键字
- let,const,class,import,export
- let和const用来声明变量
- var a = 1;
- let b = 2;
- const c = 3;
- let与var的区别
- let没有提升
- 全局变量不会绑定到window
- 不允许重复声明
- 块级作用域:花括号就是作用域
- 暂时性死区
- let与const的区别
- const声明的变量不允许修改地址,可以修改值
-
字符的扩展
- U编码的表示方式
- 老版本:默认使用四位的十六进制,超出范围的字符使用两个四位的十六进制
- 新版本:使用五位的十六进制:"\u{20bb6}"
- 关于U编码的转换(新)
- str.codePointAt()
- String.fromCodePoint(134070)
- 新增了一些字符的方法
- str.repeat(5) 重复五遍
- str.includes(“a”) 是否包含这个字符
- str.startsWith(“h”) 以什么开始
- str.endsWith(“ld”) 以什么结束
- 新增了字符串模板(拼接方式)
- ’
- "
- `
- 支持字符串中直接回车换行
- 在`内使用${}
- U编码的表示方式
背诵9
-
正则的创建及其区别
- 字面量:const reg = /a/;
- 构造函数:const reg = new RegExp(“a”);
- 构造函数可以根据变量创建正则
-
哪些方法可以使用正则(分清字符和正则)
- str.match()
- str.search()
- str.replace()
- reg.test()
- reg.exec()
-
正则的转义符有哪些,分别是什么含义
- \d:数字
- \D:非数字
- \w:数字字母下划线
- \W:非数字字母下划线
- \s:空格
- \S:非空格
- \:将正则中有含义的符号转成普通字符
-
如何将json和对象进行转换
- JSON.parse(json) json_> 对象
- JSON.stringify(obj) 对象->json
-
函数的方法有哪些(ES5新增)
- fn.call()
- fn.apply()
- fn.bind()
- 都是用来改变this指向
-
this的绑定情况有哪些
- 默认绑定,window
- 隐式绑定:当前函数的执行对象
- 强制绑定:使用函数的方法,强行修改之后的对象
- new绑定:new出来的实例
-
ES6新增的声明关键字,哪些是声明变量的,和var有什么区别
- const,let,class,export,import
- const,let
- 没有提升
- 全局不会绑定到window
- 不允许重复声明
- 块级作用域
- 暂时性死区
- const不允许修改地址,可以修改值
-
ES6新增的字符的方法
- str.includes()
- str.startsWith()
- str.endsWith()
- str.repeat()
- str.codePointAt()
- String.fromCodePoint()
ES6新增的箭头函数
- 函数分类
- 有名函数:正常函数,直接使用
- function fn(){}
- var fn = function(){}
- 无名函数:非正常函数,不能直接使用,只能作为值使用
- 赋值式创建函数的值
- var fn = function(){}
- 作为函数的参数使用:回调函数
- function fn(a){ }
- fn( function(){} )
- 作为函数的返回值使用:闭包函数
- function fn(){ return function(){} }
- 作为事件处理函数:事件处理函数
- btn.onclick = function(){}
- 作为匿名函数的函数体使用
- (function(){})()
- 赋值式创建函数的值
- 匿名函数:会立即自动执行,作用是用来创建一个新的作用域
- (function(){})()
- 有名函数:正常函数,直接使用
- 箭头函数等同于无名函数,只是一种简写语法
- 完整语法:()=>{}
- 极简语法:=>
- 有且只有一个形参,可以省略小括号
- 有且直接设置了返回值,可以省略花括号和return
- 花括号和return必须同时省略
- 特点
- 没有自己的this,自动绑定外层函数的this
- 如果使用极简语法返回对象,那么需要将对象包裹在小括号内
- 不能作为构造函数使用,不能被new执行
- 因为语法极简,伤害了代码的可读性,类似于正则
- 最后
- 一般将箭头函数小范围使用,如回调函数,或返回值
- 尽量不要作为事件处理函数使用,否则this找不到事件源
ES6新增的解构赋值
- 解开结构进行赋值,一般用于操作数组或对象,字符也可以
- 数组的解构
- 按照数组内从左向右的顺序依次解构
- 对象的解构
- 根据对象的key一一对应
- 字符的解构
- 类似于数组,按照从左向右的顺序依次解构
// 数组:按照数组内从左向右的顺序依次解构
const arr = ["张三", 18, "男"];
const [age, sex, name] = arr;
console.log(name)
console.log(age)
console.log(sex)
// 对象:根据对象的key一一对应
const obj = {
name:"admin",
age:18,
sex:"女"
}
const {age, sex, name} = obj;
console.log(name)
console.log(age)
console.log(sex)
// 字符:类似于数组,按照从左向右的顺序依次解构
const str = "hello";
const [a,b,c,d,e,f] = str;
console.log(a)
console.log(b)
console.log(c)
console.log(d)
console.log(e)
console.log(f)
ES6新增的展开运算符
- 展开复杂数据的运算符:…
- 数组:不允许直接展开,必须在能够直接使用多个数据的位置展开
- 对象:不允许直接展开,必须在能够直接使用键值对的位置展开
ES6新增的Symbol类型
- Symbol类型类似于字符,用于标记某种不可改变的状态
- 创建Symbol
- const s = Symbol("");
- 特点
- 任何两个Symbol都不相等
- 自身等于自身
ES6新增的数据的集合
-
set
- 只有值,类似于数组,但是没有索引
- new Set()
const s = new Set(); s.add(3); s.add(4); s.add(5); s.add(6); // for-of类似于for-in // for-in遍历的是索引或key 但是for-of遍历的是值 for(let i in s){ console.log(i); } // for-of遍历的是值 for(let i of s){ console.log(i) }
-
map
- 值和值的对应,类似于对象,但是没有key
const m = new Map();
m.set("name","admin");
m.set("age",18);
m.set("sex","男");
let map = new Map();
map.set("name","zhangsan");
for (const item of map) {
console.log(item)
}
console.log(map.keys())
console.log(map.values())
console.log(map.entries())
背诵10
-
ES6新增的解构赋值的规则是什么
- 数组:按照从左向右的顺序依次解构,不存在的位置为undefined
- 对象:按照key一一对应解构,不存在的key为undefined
- 字符:同数组
-
ES6新增的展开运算符的使用场景
- 数组:只能在接收多个数据的位置展开
- 对象:只能在接收键值对的位置展开
-
ES6新增的箭头函数的语法和特点
- ()=>{}
- =>
- 有且只有一个形参,可以省略小括号
- 有且直接返回值,可以生路花括号和return(必须同时省略)
- 没有自己的this,自动绑定外层this
- 不能被new执行
-
ES6新增的set和map的创建和使用
- set
- const s = new Set()
- s.add(数据)
- for-of遍历获取数据
- 不允许出现重复的数据
- 是数组的映射
- const m = new Map()
- m.set(“名”,“值”)
- m.get(“名”)
- for-of遍历获取数据
- 是对象的映射
- set
-
js的数据类型有哪些(含ES6)
- string,number,boolean,function,undefined,null,object,
symbol
- string,number,boolean,function,undefined,null,object,
-
对象的分类
- 宿主对象:window,document
- 本地对象:String,Number,Boolean,Function,Object,Array,Date,RegExp
- 内置对象:Math
-
对象的本质,意义,特点
- 本质:键值对
- 意义:存储数据,编程
- 特点:提升了数据的查找和传输速度
-
对象的创建和使用
- const obj1 = {}
- const obj2 = new Object()
- 使用
- 点语法:对象的属性是具体的值
- 中括号语法:对象的属性是不具体的值(变量)
-
什么是this,分为哪些情况
- this,当前函数的执行上下文(对象)
- 分类:
- 默认绑定:window
- 隐式绑定:函数的执行对象
- 强制绑定:指定的数据
- new绑定:new出来的实例(对象)
面向对象
-
隐式原型:
- 每个对象数据,都默认有__proto__的对象属性,自身是一个指向,指向了创建了自身的构造函数的prototype
-
显式原型:
- 除了箭头函数外,所有函数都具有的prototype的对象属性,用来提供给将来通过自身所在的函数创建出来的对象的__proto__指向。可以实现,在函数的prototype身上添加的属性或方法,可以被自身的实例通过原型链访问到
-
原型链:
- 对象在访问属性或方法时,会先在自身查找,找到了就使用,并停止查找,没找到,顺着__proto__的指向,依次向上查找,任意一层找到了,都使用,并停止,直到顶层Object.prototype还没有找到,抛出undefined
-
new的原理:
- 创建一个新对象
- 将函数的this指向创建的新对象
- 改变了新对象的__proto__指向函数的prototype
- 检测函数是否主动返回对象,如果没有,那么返回这个新对象
-
为了能方便的批量创建同特点对象,使用工厂模式创建对象
- 将对象进行封装成函数,在函数内部对对象进行批量加工处理
- 利用了new关键字,自动进行原料的创建和出厂对象的设置,实现内置的工厂模式
- 结合类和规范的概念,利用原型的特点,将对象的方法,绑定到函数的prototype身上
- 将对象进行封装成函数,在函数内部对对象进行批量加工处理
-
面向对象的最终语法之一
- 将存储数据的属性,写在构造函数内的this身上(此时的this就是将来的实例)
- 将存储功能的方法,写在构造函数的prototype身上(可以被将来的实例通过原型链访问)
- 因为将来实例的方法的执行方式的原因:实例.方法(),所以,方法内的this也指向实例
// js 创建对象方便的做法 function Persion(name,age){ this.name = name; this.age = age; } // 我们通过new关键字来执行这个构造函数 var persion1 = new Persion("林冲", 34); var persion2 = new Persion("武松",24); console.log(persion1); console.log(persion2); // 书写规则,将属性写在构造函数之内,将方法写在显示原型中 Persion.prototype.fun = function(){ console.log("我是显示原型添加的方法"); } persion1.fun(); // __proto__:隐式原型,这个是每一个对象数据都有的内置属性,它本身是一个对象,表示一个指向 // 指向的是构造自身的构造函数的prototype(规范) // prototype: 显示原型,他是一个对象,除了箭头函数之外都有的属性,他是被当做当前构造函数实例化对象的__proto__的指向 // 访问规则:现在当前范围中寻找,找到了就使用,如果没有找到,就会顺着__proto__向上找,找到了就使用,到最后Object.protoype没找到就返回undiefied
ES6的class的使用
class Abc{
constructor(n){
// 对应的是老语法的构造函数部分
this.name = n;
}
// 在constructor之外的区域对应的是老语法的原型部分
show(){
console.log(this.name)
}
}
const a = new Abc("root");
console.log(a)
a.show();
本地存储
cookie
操作cookie的方式:
douncment.cookie = “name = zhangsan;expires = 2022-09-01;path-=/abc”;
- 通信协议:约束了通信双方以什么样的规则进行通信
- IP协议:规定了通信双方的唯一的身份信息,IP地址
- TCP协议:面向连接的协议,可靠的传输协议
- UDP协议:面向数据包的协议,不可靠的传输协议
- http协议:超文本传输协议,网页协议,无状态协议,每次连接结束后都无法记录状态。
- 为了方便上网操作,记住需要记住的状态,发明了一种会话跟踪技术:cookie
- cookie最大的特点:会自动跟随http协议发往服务器
- 为了方便上网操作,记住需要记住的状态,发明了一种会话跟踪技术:cookie
- cookie的特点
- 会自动跟随http协议发往服务器
- cookie必须运行在服务器环境下
- 有时间限制,默认会话级(关闭浏览器自动删除),可以修改
- 大小:4k~
- 数量:50条~
- cookie的使用
- 是属于document的属性:document.cookie,字符类型
- 删:设置cookie的有效期,为过去的日期
- 改:设置相同的cookie名,不同的值或配置信息
- 查:document.cookie
- 增:document.cookie = “cookie名=cookie值;配置信息”
storage
- 不依赖http环境,不会随着http发往服务器,纯本地存储
- 特点:
- 永久级存储
- 10M~
- localStorage是属于window的子对象
- 可以使用对象的语法进行操作
- localStorage的使用
- 对象语法
- 专属方法
- localStorage.setItem(“key”,“val”)
- localStorage.setItem(“key”,“val2”)
- localStorage.removeItem(“key”)
- localStorage.getItem(“key”)
- localStorage.clear()
localStorage.setItem("name","admin");
localStorage.getItem("name");
localStorage.removeItem("name");
localStorage.clear();
sessionStorage.setItem("name","admin");
sessionStorage.getItem("name");
sessionStorage.removeItem("name");
sessionStorage.clear();
sessionStorage
- 只能会话级存储
- sessionStorage的使用
- 对象语法
- 专属方法
- sessionStorage.setItem(“key”,“val”)
- sessionStorage.setItem(“key”,“val2”)
- sessionStorage.removeItem(“key”)
- sessionStorage.getItem(“key”)
- sessionStorage.clear()
Ajax
1.创建XMLHttpRequest对象
const xhr = new XMLHttpRequest();
2.准备请求方式和请求地址
xhr.open("get","http://localhost:3000/api");
3.监听状态onreadystatechange(废弃)现在用onload,xhr的load,会在xhr的readyState为4时,触发
xhr.onload=function(){
if(xhr.status === 200){
// 成功
}else{
// 失败
}
}
4.发送请求
xhr.send();
封装的ajax
function ajax(obj){
let {url, success, data={}, type="get", error, timeout=50} = obj;
// 连接地址
let str = "";
for(let i in data){
str +=`${i}=${data[i]}&`;
}
// 如果是get请求还要排除缓存,加一个时间戳
if(type ==="get"){
url += `?${str}_cbbgs=${Date.now()}`;
}
// 创建hrm
const xhr = new XMLHttpRequest();
// 打开
xhr.open(type,url,true);
// 监听事件
// xhr.onreadystatechange = function(){}
// xhr的load,会在xhr的readyState为4时,触发
xhr.onload = function(){
if(xhr.status ===200){
if(success){
success(xhr.responseText);
error=null;
}
}else{
if(error){
error(xhr.status);
}
}
}
// 发送 get请求直接发送,post请求发送路径
if(type === "get"){
xhr.send();
}else{
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(str.slice(0,str.length-1));
}
setTimeout(() => {
if(error){
error(error);
success = null;
}
}, timeout);
}
继承
改变this的指向继承(构造函数继承)
1.通过call() apply() bind() 方法来改变this的指向
2.只能继承构造函数内的属性和方法,不能继承原型上的方法
3.可以实现多继承
function Person(name){
this.name = name;
tis.fun = function(){
console.log(this.name)
}
}
function Student(name){
//改变了this的指向,实现继承
Person.call(this,name);
}
原型对象继承
1.原型对象继承只能继承prototype中的,不能继承构造函数中的内容,可以实现多继承
2.如果是浅拷贝会重写父类的方法,会覆盖父类的方法
3.深拷贝,不会影响父类的方法
function Person(name){
this.name = name;
}
person.prototype.show = function(){}
function Student(name){}
for(let i in Person.prototype){
Student.prototype[i] = Person.prototype[i]''
}
// 浅拷贝
Student.prototype = Person.prototype;
原型链的继承
1.构造函数的内容和原型的内容都可以继承。
2.只能实现单继承
3.会消耗性能
function Person(name){
this.name = name;
}
person.prototype.show = function(){}
function Student(name){}
//继承开始
Student.prototype = new Person();
//继承之后的指向问题
const s = new Student();
s的__proto__ 指向的是Student的prototype,而Student的prototype指向的是父类的实例,也就是Person实例的__proto__,然后erson实例的__proto__指向的是Person的prototype
s.__proto__ -->Student.prototype--->Person实例的__proto__-->Person.prototype-->Object
混合继承
混合继承就是构造函数继承+原型对象继承
// 混合继承就是 改变this继承+原型对象继承
function Persion(name){
this.name = name;
}
Persion.prototype.show = function(){
console.log("hello");
}
function Student(name){
// 改变this指向继承(构造函数继承)
Persion.call(this,name);
}
// 原型对象继承
for(let i in Persion.prototype){
Student.prototype[i] = Persion.prototype[i];
}
ES6中的class继承
这属于语法上的继承 extends 和super()
class Person{
constructor(name){
this.name = name
}
show(){
console.log("hello");
}
}
class Student extends Persion{
constructor(name){
super(name);
}
}
闭包
- 闭包:利用作用域的嵌套,将原本的局部变量,进化成私有变量的环境,叫闭包
- 原理:
- 计算机的垃圾回收机制:内存(运行空间)和硬盘(存储空间)
- 将原本要删除的数据,临时保存起来,方便再次使用
- 函数的作用域链:不管函数在何处执行,在函数内部,都可以使用函数定义作用域内的数据
- 计算机的垃圾回收机制:内存(运行空间)和硬盘(存储空间)
- 应用:
- 循环中绑定事件,事件处理函数内,拿不到循环每次的计数器
- 给不能传参的内置函数的回调函数传参
- 给事件处理函数传参
- 闭包的特点:
- 沟通了函数内外部的桥梁
- 占用更多的内存
- 低版本浏览器,内存泄漏
- 可以在函数外部控制函数内部的数据
jQuery
1.选择器
选择器 和css的选择器差不多,只有几个不一样
// 选择器 和css的选择器差不多,只有几个不一样
// 类选择器,有多少选中多少
$(".box").css("background","red");
// id选择器 只能选中第一个
$("#box").css("background","red");
// 标签选择器
$("div").css("background","red");
// 群组选择器
$("div,ul").css("background","red");
// 子代选择器
$("div span").css("background","red");
// 通配选择器
$("*").css("background","red");
// 亲儿子选择器
$(".box2>span").css("background","red");
// 下一个节点 当前节点.box1的下一个位div的节点
$(".box1+div").css("background","red");
// 下一个全部兄弟节点
$(".box1~div").css("background","red");
// 属性选择器
$("input[name]").css("background","red");
$("input[name]").css("background","red");
$("input[name=123 type]").css("background","red");
$("input[name=123][type=text]").css("background","red");
// 伪类选择器
// 第一个子元素 作用在子元素上
$("li:first").css("background","red");
// 最后一个
$("li:last").css("background","red");
// 排除选取
$("li:not(.red)").css("background","red");
// 偶数
$("li:even").css("background","red");
// 基数
$("li:odd").css("background","red");
// 选取对应的第几个 和nth对应
$("li:eq(1)").css("background","red");
// 内容包含的标签 内容包含1的标签
$("li:contains(1)").css("background","red");
// 选取空标签,空格都不能有
$("li:empty").css("background","red");
// 选择子元素包含has的父标签
$("ul:has(.red)").css("background","red");
// 不可见可见性
$("li:hidden").css("background","red");
// 可见
$("body:visible").css("background","red");
2.过滤器
// 过滤器 比选择器性能好。
// 子代选择器
// $(".div span").css("background","red");
$(".box2").find("span").css("background","red");
// 亲儿子选择器
// $(".box2>span").css("background","red");
$(".box2").children("span").css("background","red");
// 下一个节点 当前节点.box1的下一个位div的节点
// $(".box1+div").css("background","red");
$(".box1").next("div").css("background","red");
// 下一个全部兄弟节点
// $(".box1~div").css("background","red");
$(".box1").nextAll("div") .css("background","red");
// 伪类选择器
// 第一个子元素 作用在子元素上
// $("li:first").css("background","red");
$("li").first().css("background","red");
// 最后一个
// $("li:last").css("background","red");
$("li").last().css("background","red");
// 排除选取
// $("li:not(.red)").css("background","red");
$("li").not(".red").css("background","red");
// 选取对应的第几个 和nth对应
// $("li:eq(1)").css("background","red");
$("li").eq(1).css("background","red");
// 选择子元素包含has的父标签
// $("ul:has(.red)").css("background","red");
$("ul").has(".red").css("background","red");
// 判断选择器
console.log($("li").is("red"));
$('li').hasClass('red');
// 父元素
$(".red").parent().css("background","red");
// 所有父元素
$(".red").parents().css("background","red");
// 指定范围父元素
$(".red").parentsUntil(".list").css("background","red");
// 下一个兄弟 next nextAll nextUntil
// 上一个兄弟 prev prevAll prevUntil
// 兄弟元素 sliblings()
// 返回上一个正在操作的元素 end()
3.DOM操作
样式操作
用cs()方法来操作
//设置多个样式 传入一个对象
$("div").css({
width:"100px",
height:"100px",
color: "#cccc"
})
// 获取样式
$("div").css("width")
// 获取多个样式 就传入一个数组
$("div").css(["background","width","height"])
属性操作
用attr()方法
// 设置属性
$("div").attr("abc","123")
// 设置多个属性
$("div").attr({
"data":"2022",
"date":"333"
})
// 获取属性
$("div").attr("abc")
内容操作
有参数就是设置,没有就是获取
html()可以解析标签 text()不可以解析标签
$(“div”).html(“
111111
”);表单内容用val()
class操作
//添加calss
$("div").addClass("box2");
//删除calss
$("div").removeClass("box1 box4");
// 如果元素没有当前class那么添加,如果有那么删除toggleClass
$("div").toggleClass("box1");
尺寸获取
width() 内容宽度
innerWidth() padding + 内容宽度
outerWidth() padding + border + 内容宽度
offset() 获取某个元素相对于浏览器窗口(可视区域的距离)
scrollTop() 获取垂直滚动条的值
scrollLeft() 获取水平滚动条的值
4.事件
绑定方式
jquery 所有的事件绑定都是DOM2级绑定:可以重复绑定
1.常规绑定,将事件做成函数
$("div").click(function(){
})
2.one绑定:事件只执行一次
$("div").one("click",function(){
console.log(111)
})
3.on绑定 off方法删除绑定 可以起名字
$("div").on("click.aa",function(){
console.log("aa")
})
$("div").on("click.bb",function(){
console.log("bb")
})
$("div").off("click.bb")
on的事件委托 第二个就是需要点击的元素
$("div").on("click","p",function(){
console.log(this)
})
5.hover绑定 两个参数,第一个是进入的事件,第二个是离开的事件
$("div").hover(function(){},function(){})
6.ready() 页面加载事件
$(function(){})
绑定对象
jquery事件的事件对象是经过兼容封装的
javaScript事件对象是浏览器默认传入的,但是对于浏览器的兼容问题,我们需要对事件对象进行兼容。很烦!但是jQuery已经帮我们解决了所有兼容性的烦恼,并且给我们添加了很多有用的方法。
event.target 获取绑定事件的DOM元素
event.type 获取事件的类型
event.data 获取事件中传递的数据
event.pageX/pageY 获取根据页面原点的X,Y值
event.screenX/screenY 获取根据显示器窗口的X,Y值
event.offsetX/offsetY 获取根据父元素X,Y值
event.which 获取当前鼠标点击的键1,2,3
event.altKey/shiftKey/ctrlKey/ 返回 true、false
event.preventDefault() 阻止默认行为
event.stopPropagation() 取消事件冒泡
return false 阻止默认事件和事件冒泡,双层阻止,小心使用
5.ajax
jq的大部分的ajax功能的方法,都是$.xxx()的执行方式
jq提供了很多能实现ajax请求的方法
- $.getScript(); 发起jsonp的跨域请求
- $.getJSON() 发起JSON文件请求
- $().load() 发起html文件请求
- $.get() 发起get请求
- $.post() 发起post请求
- $.ajax() 发起所有的数据请求
1.$.get()
let abc= $.get("url",{
对象
},function(res,state,xhr){
},"text")
//最后一个为文本格式,一般不用修改或者省略不写
// 请求失败会执行的方法
abc.error(function(xhr, state, res){
console.log(xhr)
console.log(state)
console.log(res)
})
2.ajax()
// 请求json
$("#btn1").click(function(){
$.ajax({
url:"http://localhost:3000/data/test.json",
success:res=>{
console.log(res)
},
dataType:"json"
})
})
// 请求jsonp
$("#txt").on("input", function(){
$.ajax({
url:"https://suggest.taobao.com/sug",
data:{
code:"utf-8",
q:$(this).val(),
_ksTS:"1636342415828_460"
},
success:res=>{
let str = "";
res.result.forEach(val=>{
str += `<li>${val[0]}</li>`
})
$(".list").html(str);
},
dataType:"jsonp",
jsonp:"callback"
})
})
// html请求
$("#btn3").click(function(){
$.ajax({
url:"http://localhost:3000/data/hello.html",
success:res=>{
$(".box").html(res);
}
})
})
// 有loading效果的post请求
$("#btn4").click(function(){
$.ajax({
url:"http://localhost:3000/api",
type:"post",
data:{
type:"getGoods"
},
success:res=>{
console.log(res)
$(".img").hide();
},
beforeSend:()=>{
// alert("准备发起请求了")
$("<img class='img' src='./loading.jpg'>").appendTo($("body"))
}
})
})
// 有超时效果的请求
$("#btn5").click(function(){
console.log(1)
$.ajax({
url:"http://localhost:3000/api",
data:{
type:"getGoods"
},
success:res=>{
console.log(res)
},
error:(a,b,c)=>{
console.log(b)
console.log(c)
},
timeout:5
})
})
// 不会触发ajax的全局事件的请求
$("#btn6").click(function(){
$.ajax({
url:"http://localhost:3000/data/test.json",
success:res=>{
console.log(res)
},
dataType:"json",
global:false
})
})
3.$().load()
有公共的页面可以抽取出来。
在hello.html
<div id="top">
<div>我是标日
</div>
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
</ul>
</div>
<div id="foot">
<p>我是尾部</p>
</div>
在另一个页面
// 可以进行外部的引用,将公共的部分抽取出来,进行复用
$("input").click(function(){
$("div").load("http://localhost:3000/data/hello.html #top",function(){
$("div li").click(function(){
})
})
$("footer").load("http://localhost:3000/data/hello.html #foot",function(){
$("#foot").css("background","red");
})
})
6.工具类方法
// 循环
const obj = {
name:"zhangsan",
age:12,
height:"180cm"
}
$.each(obj,function(key,val){
console.log(val);
})
// 序列化(查询请求)
console.log($.param(obj));
7.Promise
异步函数,通过构造函数来创建一个异步函数.
const p = new Promise((resovle,reject)=>{
// padding 正在进行
// resovle() 成功执行的
// reject()失败执行的
resovle();
})
console.log(p)
p.then(()=>{
// 成功之后做的事情
},()=>{
// 失败之后做的事情
})
接下来看一个函数:
function getString(){
return new Promise( (resolve,reject) => {
setTimeout( () =>{
resolve("hello world");
},2000)
})
}
function hello(){
let strings = getString()
console.log(strings);
}
hello();
这段代码执行的结果很显然是一个Promise函数,因为这个getString这个函数的返回值就是一个Promise.
那我怎么才能得到这个getString执行成功给我返回的hello world呢,
function hello(){
let strings = getString().then( res=>{
console.log(res);
})
}
hello();
通过.then和.catch来获取异步函数执行的结果.还有其他方法吗?如果我想直接得到异步函数的返回值呢?
async function hello(){
let strings =await getString()
console.log(res);
}
hello();
首先在调用的函数上加上await关键子,等待函数的返回值,然后在这个函数上加上async关键字,同步,这样就可以i直接得到异步函数的返回值.