首先熟悉 location 地址信息:
<script>
// location对象
// 实现页面的点击跳转,类似超链接功能,比超链接功能强大(可以在跳转页面时 编写逻辑代码实现一些功能)
var _baidu = document.getElementById("baidu")
_baidu.onclick = function(){
// 跳转网页
location.href = "http://www.baidu.com/s?wd=明日战记"
}
// 实现当前网页刷新
var _refresh = document.getElementById("refresh")
_refresh.onclick = function() {
location.href = "#" // 一般这里写的都是当前网页网址
}
</script>
and history 历史访问记录:
<script>
// history对象
var _b = document.getElementById("b")
var _f = document.getElementById("f")
var _back = document.getElementById("back")
_b.onclick = function() {
// 访问上一条记录
history.back()
}
_f.onclick = function() {
// 访问下一条记录
history.foeward()
}
_back.onclick = function() {
// 访问上一条记录
history.go(-1)
}
</script>
- 两个函数都可以用于页面回到上一页, location.go() 需要插件支持*
- location.go(-1)回到上一页并且刷新页面
- history.go(-1) ,回到上一页
cookie 是网站应用开发中,服务器给浏览器客户端记录文本数据的一个对象;记录数据的时候有如下特点:
- 数据格式: key=value ,保存的数据只能是文本数据
- 有过期时间: expires=xxxx
- 不设置过期时间,称为临时 cookie ,会话结束数据删除
- 设置过期时间,称为永久 cookie ,过期时间一到立即删除
- 可以包含路径,给不同的路径保存不同的 cookie
- 一个网站,大部分浏览器限制最多保存50个 key=value 键值对
- 一个网站,大部分浏览器限制最多保存 4K 数据
- 缺点 存储量太小,只有4KB
- 缺点 每次HTTP请求都会发送到服务端,影响获取资源的效率
- 缺点 需要自己封装获取、设置、删除cookie的方法
- 缺点 当超过单个域名限制之后,再设置cookie,浏览器就会清除以前设置的cookie。IE和Opera 会清理近期最少使用的cookie,FF会随机清理cookie
cookie / sessionStorage / localStorage 都属于浏览器缓存数据的操作对象
cookie 是服务器存储在浏览器客户端的一段 key=value 格式的文本内容,包含过期时间、每个网站最多存储 4k 数据或者 50 个键值对数据;操作时如果需要删除数据可以选择清除浏览器缓存或者设置过期时间
sessionStorage 属于 H5 提供的会话缓存数据,在用户访问网站网页时建
立会话就可以存储数据,存储的数据在本次会话中可以访问,一旦会话结束存
储的数据就立即销毁;一般用于存储会话状态数据,如用户登录状态localStorage 属于 H5 提供的本地缓存数据,可以在任意访问情况下进行
数据存储,不受到会话限制,除非用户主动删除否则永久保存在用户本地;一
般用于存储一些提高用户体验的、没有保密性的数据,如用户视频播放进度等sessionStorage 和 localStorage 也受到浏览器的限制,最多存储 5M 的数据
回答思路:先说联系/共同点,然后说区别,最后说项目中的应用场景
call / apply / bind 都是辅助函数,可以用来修改正在执行的函数内部 this 指向
call 修改 this 指向,通过 数据序列 传递给函数实际参数,如tom.eat.call(jerry, ‘数据a’, ‘数据b’)
apply 修改 this 指向,通过 数组方式 传递个函数实际参数,如tom.eat.apply(jerry, [‘数据a’, ‘数据b’])
bind 修改 this 指向,通过 数据序列方式 传递给函数实际参数,同时返回函数的声明,让开发人员可以延迟或者立即调用,扩展了使用范围,如:tom.eat.bind(jerry, ‘数据a’, ‘数据b’)()
项目开发中这三个函数的作用一致,根据实际传递数据的情况确定使用哪种方式,
- 如项目中传递给函数的数据都是零散数据,就可以使用 call 进行函数的调用;
- 如果传递给函数的数据包含在一个数组中,就可以使用 apply 完成函数的调用;
- 如果将参数数据交给函数之后,需要做一些其他工作才能执行目标函数,可以使用 bind 交付参数,并且延迟执行函数
原生 JavaScript 中通过函数的方式模拟面向对象语法,主要的继承的实现方式有4种,分别是 原型继承、 冒充继承、组合继承、寄生组合继承
原型继承,基于原型对象的继承,子类和父类在原型链上就存在继承关系;存在的问题是子类在创建对象时无法直接修改父类的属性数据,必须在创建的对象上通过访问属性的方式进行修改,让编码变得复杂;开发中一般很少独立使用
<script> function Person() {} function Student() {} //原型继承 Student.prototype = new Person() </script> ``
冒充继承,基于 call() 辅助函数修改 this 指向的功能,在子类中通过调用父类构造函数的 call() 方法,完成子类可以使用父类构造函数内部属性和方法的使用;存在的问题是首先在原型链上没有真实继承关系,所以子类无法继承父类在原型对象上的数据和函数
<script> function Person(name) {} function Student(name, age) { // 冒充继承,可以直接修改父类属性 Person.call(this, name) this.age = age } </script>
组合继承,结合了原型继承和冒充继承,通过原型继承让子类可以使用父类原型对象上的属性和函数,通过冒充继承可以让子类直接访问父类属性,优化操作语法;存在的问题是两种继承方式都访问了父类的构造函数,继承过程中造成父类构造函数的多次调用存在一定的性能问题;如果性能没有太高要求的情况下,可以通过组合继承的方式进行实现
<script> function Person(name) {} function Student(name, age) { //冒充继承 Person.call(this, name) this.age = age } //原型继承 Student.prototype = new Person('') </script>
寄生组合继承,对组合继承的一种升级,将父类原型对象进行了复制得到一个空对象,子类在冒充继承的继承上,实现原型继承时继承这个空对象,就不需要让父类的构造函数再次调用,这个空对象的创建和调用性能消耗较低,对性能上有一定的优化提升;项目中如果出现了对继承关系的频繁使用,建议可以将寄生组合继承进行封装使用,优化项目性能
<script> function Person(name) {} function Student(name, age) { // 冒充继承 Person.call(this, name) this.age = age } // 寄生函数 function inherit(Parent, Child){ //寄生构造函数|空函数 var Temp = function() {} // 复制 原型对象 Temp.prototype = Parent.prototype // 原型继承(空构造函数,性能 优化) Child.prototype = new Temp() // 指定自己构造函数 Child.prototype.constructor = Child } // 寄生继承:让Student继承自Parent类型 inherit(Person, Student) </script>
``
问题:
var str = new String("hello")
- new 创建的对象,都是需要在堆内存中创建的
- 字符串作为一个项目中最常用的数据类型,编程语言为了提高字符串使用效率会将字符串存储到常量区,创建字符串对象时检查常量区中是否存在这个字符串(存在的话直接复制对象到堆内存;如果不存在的话创建对象并复制到堆内存)
答: 最终在内存中创建了3个对象 | 分配了3个空间
分析:这个问题归结于历史原因!
软件行业发展过程中,有一家公司 微软 开发了自己特立独行的浏览器:探险家/ IE ,内核中使用了大量和其他浏览器不同的程序,所以导致后续开发的很多应用都需要兼容 IE
JavaScript 中绑定事件的标准语法,为了兼容 IE6~IE11 ,事件绑定语法:
1.对象属性绑定的事件,取消
<script>
// 绑定事件
_btn.onclick = function() {}
// 取消事件
_btn.onclick = null
</script>
2.标准语法绑定事件,取消
<script>
function handler(){
// 事件处理函数
}
// 绑定事件
_btn.addEventListener("click", handler)
// 取消指定事件
_btn.removeEventListener("click", handler)
</script>
总- GET 请求和 POST 请求都是 HTTP 规范中定义的请求方式,描述了客户端向服务器发送请求完成后续操作的过程
分- GET 请求在规范中主要用于向服务器请求获取数据,也可以附带字符串参数,参数会拼接在 url 地址的后面,参数的长度收到服务器限制;请求效率非常高,浏览器地址栏、超链接、 Ajax 都可以发送 GET 请求
分- POST 请求在规范中主要用于向服务器新增数据,但是项目开发中我们一般对于给服务器提交比较敏感的数据时,会使用 POST 请求将参数包装在请求中进行传递,既可以传送字符串数据,也可以传送二进制数据,如实现文件上传等操作;传递参数的大小受到服务器的限制;请求效率相对 GET 没有那么优秀,但是数据安全性得到了一定的保障;一般网页中我们通过表单、 Ajax 发 送 POST 请求
总- 网页中实现页面跳转、请求一些不敏感的数据如搜索,这些都可以通过效率较高的 GET 完成数据的请求操作;网页中一些包含敏感数据的操作如登录、注册、转账等建议使用 POST 请求完成数据操作
详解 上一篇文章 get/post 详解
什么是拷贝?
拷贝:就是复制的意思,将数据再复制一份
什么是深浅拷贝?
深拷贝:将对象以及对象中包含的所有属性,全部独立的复制一份;两个对象之
间完全没有任何关系,都是独立的数据浅拷贝:将对象以及对象的属性赋值一份,但是对象的属性中如果包含内存地址
~只赋值地址数据,不复制内存地址中具体的数据备注:关于数据的复用,引用赋值、浅拷贝、深拷贝
3.如何实现
代码操作如下:
<script>
// 声明一个原数组
let arr = ['tom', 'jerry']
// 浅拷贝:属性独立的两个数组,两个数组的属性中保存的地址相同
// 直接修改属性数据,互相没有影响
// 修改属性/地址数据,互相产生影响
let arr2 = [...arr]
// 深拷贝:完全独立的两个数组
// 直接修改属性数据,互相没有影响
// 修改属性/地址数据,互相没有影响
let arr3 = JSON.parse(JSON.stringify(arr))
</script>
.
.
数组中的重复数据剔重
var arr = [1,2,2,2,3,4,5,5,5,6,7,8,8]
请将数组中的重复数据删除,所有的数据都保留唯一的一份?
代码如下 (笔试):
<script>
// 数组
var arr = [1, 2, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8, 8];
// 1、原始编码
var newArr = [];
for (var i = 0; i < arr.length; i++) {
// 每次循环的数据
var item = arr[i];
if (!newArr.includes(item)) {
// 如果没有包含,将数据添加进来
newArr.push(item);
}
}
console.log(newArr, "新数组");
// 2、Set集合,完成数组剔重
// 将数组转换成集合类型:集合中不能存放重复数据
var s = new Set(arr);
// 将集合转换回数组:数组的剔重,最终得到数组类型的数据
var arr2 = Array.from(s);
console.log(arr2);
</script>
考察ES6进阶 Map
Map
是ES6
中提供的一种映射、字典类型,可以包含多个key:value
键值对数据,其中key
可以是任意类型的、不能重复的数据;是对原生JSON
对象的扩展
观察下面的字符串,统计每个字符出现的次数
<script> var str = "sadasdsawffdsafsdfgp[d[]sds./dfskdfjsdasdajsfhuhkic/;x/c;ljfioqadpfsaodckljspdsadpiogvkjdsifepofasklxifep9opieio90" </script>
分析:
- 既然统计每个字符出现的次数,统计时的字符不能重复,可以作为 key 值
- 统计字符出现的次数,是一个整数数据,出现多次时数据累加,可以作 为 value 值
代码实现: 需手写
<script>
// 原始数据
var str =
"sadasdsawffdsafsdfgp[d[]sds./dfskdfjsdasdajsfhuhkic/;x/c;ljfioqadpfsaodckljspdsadpiogvkjdsifepofasklxifep9opieio90";
// 统计数据
// 记录每个字符出现次数的统计数据
const map = new Map();
for (var i = 0; i < str.length; i++) {
// 获取当前字符
const _c = str.charAt(i);
// 判断map中是否包含这个key
if (map.has(_c)) {
// 如果包含
let cnt = map.get(_c);
map.set(_c, ++cnt);
} else {
// 如果没有包含,包含进来 {_c: 1}
map.set(_c, 1);
}
}
console.log(map, "字符统计");
</script>
观察下面创建 Set 的代码,正确的是?( AB )
A: new Set()B: new Set([])
C: new set()
D: newset([])
观察下面创建 Map 的代码,正确的是?( A )
A: new Map()
B: new Map({})
C: new map()
D: newmap({})
回答思路:
总:箭头函数和普通函数,都是封装了多行代码实现了一定功能的代码
块,都可以提高代码的复用性分:和普通函数相比较,箭头函数内部的 this 指向 window 或者指向外
部函数的 this ,所以函数内部如果要使用 this 的情况下不建议使用箭头函
数替代普通函数,如对象内部的方法、事件处理函数等;另外箭头函数不能和普通函数一样作为构造函数使用总:箭头函数本质上就是 ES6 提供的在语法上和语义上对功能简单的普通
函数的优化方案,针对功能性函数进行编码效率和代码可读性提升,如数组的函数 filter(fn)/map(fn)/… 回调函数都可以使用箭头函数进行优化<script> const a = [1, 2, 3, 4, 5]; const a2 = a.map(function (item) { return item * item; }); // a2: [1,4,9,16,25] const a3 = a.map((item) => item * item); // a3: [1,4,9,16,25] </script>
注意:关于箭头函数内的 this ,某些资料会提到箭头函数没有 this 指
向(如果真的没有 this 指向,内部无法访问 this 引用);但是如果箭头函
数包含在其他有 this 指向的函数内部,箭头函数内的 this 就是外部函数的
this
小小练习题:
<script>
function fn() {
console.log(this); //window
}
const fn = function () {
console.log(this); //当前函数
};
const tom = {
name: "tom",
fn() {
console.log(); //当前对象tom
},
};
_btn.onclick = function () {
console.log(this); //当前对象_btn
};
_btn.onclick = () => {
console.log(this); //window
};
_btn.onclick = function () {
//this:_btn
const fx = () => {
// 箭头函数内部有this引用,和函数所在上下文环境this相同
console.log(this); //_btn
};
fx();
};
</script>
1.String 字符串类型
2.Number 数值类型
3.Boolean 布尔类型
4.Null 空值类型
5.Undefined 未定义类型
6.Object 对象类型
-var关键字存在变量的预解析,可以重复声明变量,存在全局作用域和局部作用域
-let关键字不存在变量的预解析,不可以重复声明变量,只存在块级作用域
在原生JavaScript中,用var声明的变量,再解释执行时,解释器会将变量的声明提升到代码的最前面,.赋值在原来的位置,保障了代码在运行的过程中程序不会出现错误导致程序崩溃退出的问题,解释器执行变量提升的过程就是变量的预解析
创建的操作函数
push() 末尾追加一个
pop() 末尾删除一个
ushift() 开头添加一个
shift()开头删除一个
forEach() 遍历数组
filter() 遍历条件过滤
map() 遍历数据转换
every() 遍历全部判断
some() 遍历部分判断
reduce() 遍历迭代输出
小括号:分组,包含的字符数据会被当成一个整体进行匹配
如:(abc)表示匹配整个abc一串整体数据
中括号:或者关系,包含的字符数据呈现或者条件;也可以包含范围内容
如:[abc]表示匹配一个a或者b或者c;[a-z]表示小写字母
大括号:量词,表示匹配前面的字符出现的次数
如:x{m,n}表示前面的x出现至少m次最多n次的匹配情况
构造函数指通过new函数名来实例化对象的函数叫构造函数,首字母一般大写
原生JS中有四种继承方式,分别为:原型继承,冒充继承,组合继承,寄生组合继承
-Get请求中的参数可见,通过拼接的方式拼接在url地址中.安全性较弱
-Post请求参数不可见,参数通过请求体传输,安全性较高
JavaScript中类型转换分为显式类型转换和隐式类型转换
-显式类型转换:指的是在编程过程中,开发人员通过指定的语法如parseInt(),parseFloat(),boolean()等将目标数据转换为指定类型的方式称为显示类型转换
-隐式类型转换:指的是在程序运行过程中,解释器自动匹配数据对应的数据类型,如乘除减法运算,toFixed()函数调用
*-某些算数运算符,如-, , /
-If()选择结构
-toFiex()函数
indexOf()
lastIndexOf()
includes()
trim()
trimLeft()
trimStart()
trimRight()
trimEnd()
toLowerCase()
toUpperCase()
split()
slice()
substr()
substring()
Min()
max()
ceil()
floor()
random()
pow()
log()
sin()
round()
trunc()
-apply():修改this指向,通过数据序列传递给函数实际参数
-call():修改this指向,通过数组方式传递个函数实际参数
函数递归指的是在函数内部调用自身的过程
递归 recursion ,函数的递归,描述了函数自己调用自己的一种执行方式
-Array.of()创建数组对象
-Array.from()将类数组转换为数组
-创建对象
-连接服务器
-发送请求
-处理响应数据
-Null一般用于表示空值,转换为数值类型为0
-Undefined一般用于表示无效数据,转换为数值类型为NaN
-形式参数:不表示具体数据,声明位置在函数声明的括号内,描述了内部代码执行需要的数据
-实际参数:传递给函数的具体数据,位置在函数调用执行时的函数括号内
-剩余参数只包含那些没有对应形参的实参,而 arguments 对象包含了传给函数的所有实参
-arguments对象不是一个真正的数组,而剩余参数是真正的 Array实例,也就是说你能够在它上面直接使用所有的数组方法,比如 sort,map,forEach或pop
1.函数闭包:描述了在函数内部声明函数的语法
2.使用场景
- return 回一个函数
1.2 函数作为参数
1.3 IIFE(自执行函数)
1.4 循环赋值
1.5 使用回调函数就是在使用闭包
3.使用闭包需要注意什么
容易导致内存泄漏。闭包会携带包含其它的函数作用域,因此会比其他函数占用更多的内存。过度使用闭包会导致内存占用过多,所以要谨慎使用闭包。
-X+:表示字符x出现了1次或者多次
-X:表示字符x出现了0次或者多次
-X?:表示字符x出现了0次或者1次*
-原型prototype:描述的是构造函数和原型对象之间的关联关系,描述了创建对象的构造函数的真实对象类型
-原型链__proto__:描述的是创建的对象和对应的原型对象之间的关联关系,描述了当前对象属于哪个真实类型对象
ES6中两个类型可以通过extends关键字实现继承关系
-数组中可以存储重复的数据,数组中的数据有顺序
-Set集合不可以存储重复数据,存储的数据是无顺序的
-BOM:浏览器对象模型,提供操作浏览器的相关方法
Window窗口对象
Location地址对象
History历史对象
Navigator版本信息对象
Screen屏幕独享
Document文档对象
-DOM:文档对象模型, 提供操作文档的相关方法
-Onclick:单击事件(鼠标左键)
-Onload:加载事件
-Onchange:内容改变事件
-Onscroll:滚动事件
-Onmouseenter / onmouseover:鼠标进入事件
-Onmouseleave / onmouseout:鼠标离开事件
-捕获阶段
-目标阶段
-冒泡阶段
-事件冒泡指的是目标阶段事件执行后,对应的标签向上级传递的过程
默认行为是网页标签自带的功能行为,如超链接跳转行为,阻止默认行为可以通过兼容语法阻止:e.preventDefault ? e.preventDefault : e.returnValue=false
-DOM读取宽度等数值时,在操作样式时后面需要加单位
-DOM操作未来标签的样式时,要将事件委托到当前标签的父标签上
程序运行过程中出现数据的相互影响,称为全局污染,可以使用函数的闭包解决全局污染
1、typeof 检测一些基本的数据类型
语法:typeof 后面加不加括号都是可以用的
注意:正则、{}、[]、null输出结果为object
console.log(typeof /\d/);//object
console.log(typeof {});//object
console.log(typeof []);//object
console.log(typeof (null));//object
console.log(typeof 123);//number
console.log(typeof true);//boolean
console.log(typeof function () {});//function
console.log(typeof (undefined));//undefined
1.2
NaN是数字类型的,但是它又可以用isNaN()检测,isNaN() 函数用于检查其参数是否是非数字值
isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字
Window窗口对象
Location地址对象
History历史对象
Navigator版本信息对象
Screen屏幕独享
Document文档对象
一、通过id属性值获取标签对象
document.getElementById(‘id属性值’)
//获取标签页中id为div1的标签对象
var oDiv1 = document.getElementById('div1');
//输出为id为id为div1的标签内容
console.log(oDiv1);
二、通过class属性值获取标签对象
document.getElementsByClassName(‘class属性值’)
elements后面有个s表示复数,可以选中所有的class,在js中class一律定义为classname,不能被forEach()循环
var oDiv2 = document.getElementsByClassName('div2');
//输出所有class是div2的数据
console.log(oDiv2);
//输出第一个div2的数据
console.log(oDiv2[0]);
//输出第二个div2的数据
console.log(oDiv2[1]);
三、通过标签名字获取标签对象
document.grtElementsByTagName('标签名字)
获取到的也是一个伪数组,不能被forEach()循环
var oDiv3 = document.getElementsByTagName('div');
//输出所有标签是div2的数据
console.log(oDiv3);
//输出第二个div的数据
console.log(oDiv3[1]);
四、通过neme标签获取标签对象
document.getElementByname
获取到的也是一个伪数组,不能被forEach()循环
var oDiv4 = document.getElementByname('s');
输出所有name标签是s的数据
console.log(oDiv4);
输出name标签是s的第二个数据
console.log(oDiv4[1]);
五、通过语法规范,获取标签对象
document.querySelector() //获取符合条件的第一个标签
document.querySelectorAll() //获取符合条件的所有标签
获取到的也是一个数组,可以被forEach()循环,但是低版本ie不兼容以上两种方式
//获取id为div1的标签内容
var oQuery1 = document.querySelector('#div1');
//输出为id为div1的标签内容
console.log(oQuery1);
//获取class为div2的标签内容
var oQuery2 = document.querySelector('.div2');
//输出为class为div1的标签内容
console.log(oQuery2);
//通过标签的标签名称来获取,只获取第一个div标签
var oQuery3 = document.querySelector('div');
//输出为标签为div的标签内容
console.log(oQuery3);
//获取所有标签为div的标签
var oQuery4 = document.querySelectorAll('div');
//输出所有标签为div的数组,
console.log(oQuery4);
//获取所有name属性值为s的标签
var oQuery5 = document.querySelectorAll('[name="s"]');
//输出name属性值的数组
console.log(oQuery5);
// 获取type属性值是text的标签
var oQuery6 = document.querySelectorAll('[type="text"]');
//输出type属性为text的数组
console.log(oQuery6);
//还可以通过标签结构获取ul下的li标签,
var oQuery7 = document.querySelectorAll('ul>li');
console.log(oQuery7);
三种
1.使用HTML标签的事件属性绑定处理程序
2.使用事件源的事件属性绑定处理程序
3.使用addEventListener()绑定处理程序
1.事件冒泡就是指父元素和子元素有相同的事件,当触发子元素事件时,会向上冒泡,同时也会触发父元素事件
解答什么是事件冒泡
1.2
阻止事件冒泡的几种方法
第一种:event.stopPropagation();
第二种:return false;
第三种:event.preventDefault();
第一步 创建对象
第二步 初始化
第三步 设置请求头
第四步 发送请求
第五步 监听状态码
第一步创建对象
var ajax = null;
try{ // 写一些调试代码,或者可能出现错误的代码,一旦发生错误,就会从这里面出去,进入到catch里面并把错误信息,当成参数传入到catch中
ajax=new XMLHttpRequest()
}catch{
ajax = new ActiveXobject('Microsoft.XMLHttp')
}
第二步初始化
ajax.open('post/get','1.txt');
第三步设置请求头
ajax.setRequestHeader('Content-type','application/x-www-form-urlencoded')
第四步发送请求
ajax.send('name=张三');
第五步监听状态码
ajax.onreadystatechange=funciton(e){
if(ajax.readystate==4 && ajax.status == 200){
console.log(ajax.response)
}
}
区别:
1、JavaScript是一种脚本语言,而jQuery是一个js库。
2、JS中查找元素的过程中方法太少且复杂;jQ中查找元素的方法有多种多样,非常灵活。
3、JS主要通过设置style来改变样式;jQ使用css()来改变样式。
4.JavaScript在遍历数组时重复使用大量for循环,而jQuery中拥有隐式迭代特性因此不再需要手写for循环了。
5.JavaScript有各种浏览器兼容问题,代码复杂冗余,而jQuery中完全没有兼容性问题
6.JavaScript实现简单的动画效果很复杂,代码量大,而jQuery中实现动画非常简单,而且功能更加的强大
7.入口函数的区别在JavaScript的入口函数要等到页面中所有资源(包括图片、文件)加载完成才开始执行。而在.jQuery的入口函数只会等待文档树加载完成就开始执行,并不会等待图片、文件的加载。
1. 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中,JavaScript 基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式、声明式、函数式编程范式
javascript是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;JavaScript基于原型编程、多范式的动态脚本语言,并且支持面向对象、命令式和声明式风格。
1.2
1、处理表单,检验用户输入,并提供反馈。比如一个表单需要输入电子邮箱而用户却输入手机号码,javascript就会提示输入错误的提醒。
2、与页面交互性,相应用户的点击,给用户提供更好的体验
3、根据用户操作,动态创建页面。比如用户发邮箱,店家附件操作
4、cookie设置,cookies是用来存储浏览器上的临时信息,比如网站地址,用户名等。
5、数据通讯,浏览器与服务器的数据通讯,比如ajax的异步传输;
6、丰富界面,使用JavaScript来放组件、滑块之类的项目,给网站提供更丰富的界面。
7、javascript可以有规律的重复html文段简化,减少下载的时间。
1、typeof 检测一些基本的数据类型
语法:typeof 后面加不加括号都是可以用的
注意:正则、{}、[]、null输出结果为object
console.log(typeof /\d/);//object
console.log(typeof {});//object
console.log(typeof []);//object
console.log(typeof (null));//object
console.log(typeof 123);//number
console.log(typeof true);//boolean
console.log(typeof function () {});//function
console.log(typeof (undefined));//undefined
1.2.Object.portotype.toString (最好的)
语法:Object.prototype.toString.call([value])
获取Object.portotype上的toString方法,让方法的this变为需要检测的数据类型值,并且让这个方法执行
在Number、String、Boolean、Array、Function、RegExp…这些类的原型上都有一个toString方法:这个方法就是把本身的值转化为字符串
例子:
(123).toString()//'123'
(true).toString()//'true'
[12,23].toString()//'12.23'
Object.prototype.toString执行的时候返回当前方法中的this的所属类信息,也就是,我想知道谁的所属类信息,我们就把这个toString方法执行,并且让this变为我们检测的这个数据值,那么方法返回的结果就是当前检测这个值得所属类信息
在使用自增和自减运算符时,自增运算符放在变量之前或者是之后,并且变量需要参与运算,就有区别了。
当运算符放在变量之后,先取变量的值进行运算,然后再对变量进行加1或者是减1。
如果运算符放在变量之前,先对变量进行加1或者是减1,然后再做运算。
for in可以循环数组和对象,得到是数组的下标或对象的键名
for of只能循环数组,得到的是数组对应的值
第一种方法:
使用arguments,函数所有的参数都会存入arguments数组离去,所以我们可以从中获取相应的参数然后赋值function example(a,b){ var a = arguments[0] ? arguments[0] : 1;//设置参数a的默认值为1 var b = arguments[1] ? arguments[1] : 2;//设置参数b的默认值为2 return a+b; }
第二种方法
使用运算符 ||,这个等同于if(a){a=xx}的写法function example(name,age){ name=name||'jason'; age=age||30; alert('你好!我是'+name+',今年'+age+'岁。'); }
第三种方法
使用jquery扩展,适合参数较多的情况下function example(setting){ var defaultSetting={ name:'jason', age:'30', sex:'男', phone:'100866', QQ:'100866', birthday:'1949.10.01' }; $.extend(defaultSetting,settings); var message='姓名:'+defaultSetting.name +',性别:'+defaultSetting.sex +',年龄:'+defaultSetting.age +',电话:'+defaultSetting.phone +',QQ:'+defaultSetting.QQ +',生日:'+defaultSetting.birthday +'。'; alert(message); }
自执行函数: 1、声明一个匿名函数 2、马上调用这个匿名函数。
作用:创建一个独立的作用域。
好处:防止变量弥散到全局,以免各种 js 库冲突。隔离作用域避免污染,或者截断作用域链,避免闭包造成引用变量无法释放。利用立即执行特性,返回需要的业务函数或对象,避免每次通过条件判断来处理
场景:一般用于框架、插件等场景
1、创建 XMLHTTPRequest 对象,也就是创建一个异步调用对象
2、创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息
3、设置响应 HTTP 请求状态变化的函数
4、发送 HTTP 请求
5、获取异步调用返回的数据
6、使用 JavaScript 和 DOM 实现局部刷新
type 发送
形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数。
形参就是函数声明时的变量,实参是我们调用该函数时传入的具体参数。
arguments参数
主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。
一.什么是原型和原型链?
1.原型:在js中,函数可以有属性。每个函数都有一个特殊的属性叫原型(prototype)
2.原型链:当调用某个函数的方法时,这个函数未定义这个方法,此时不会返回undefined,而是继续往原型链后面的原型去查找,只有查找不到,才返回undefined。
原理: 每个对象都有隐式原型(proto)和显式原型(prototype),对象的proto指向它原型对象上的prototype。原型链最终指向的是Object.prototype,他的__proto__为null
二.原型和原型链存在的意义是什么?
使得实例对象可以共享构造函数的原型属性和方法,可以节省内存,构造函数原型上的属性和方法越多,节省的内存就越大。
1、原型模式是用于创建重复的对象,同时又能保证性能,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式;
2、原型链是原型对象创建过程的历史记录,当访问一个对象的某个属性时,会先在这个对象本身属性上查找。
判断对象相等
考察运算符
==
===
NaN == NaN 执行结果是 false。JavaScript的规定,NaN表示的是非数字, 但是这个非数字也是不同的,因此,NaN 不等于 NaN,并且两个NaN永远不可能相等。
1、slice函数
Array.slice(),接收两个参数,起始位置(包含起始元素),结束位置,返回一个新数组const arr=[1,2,3,4,5,6,7,8,9,10]
const arr2=arr.slice(1,3)
console.log(arr2);
slice(1,3),从下标1的元素开始截取(包含该元素),截取到下标为3的元素(不包含该元素)
输出:[2, 3]
2、splice函数
该函数操作原数组,可以执行数组的删除和插入,返回一个新数组
用作删除的时候,接收两个参数:起始下标,删除的个数;函数返回删除的元素数组
用作插入的时候,接收两个以上参数:起始下标,删除的个数,插入的元素;函数返回删除的元素数组,插入的元素会在删除的元素的位置开始插入
const arr=[1,2,3,4,5,6,7,8,9,10]
const arr2=arr.splice(1,2)
console.log(arr2);
输出:[2,3]
number 1 => boolean true
number 0 => boolean false
一、typeof()
识别所有值类型;number,string,boolean
识别函数类型,typeof(函数a)会返回Function
识别引用类型,但是无法区分对象,数组以及 null,都会返回Object
NaN 会被识别为 number,尽管 NaN 是 Not-A-Number 的缩写,意思是"不是一个数字"。
parseInt(“10abc”) = 10
parseInt(“abc10”) = NaN
parseInt(111,2) = 7
parseInt(‘111’,2)就是将‘111’解析为2进制的整数,就是4+2+1=7.
详情parseInt
parseInt 详解
1.获取父节点
element.parentNode
Math.floor() | 向下取整 |
---|---|
Math.ceil | 向上取整 |
Math.trunc | 截取小数部分 |
Math.round | 四舍五入 |
Math.max | 获取一系列数据中的最大值 |
Math.min() | 获取一系列数据中的最小值 |
Math.pow(x,y) | 获取x数据的y次方 指数运算 |
Math.sprt(x) | 获取x数据的平方根 |
Math.random() | 获取一个0~1之间的随机数 |
是Not a Number的缩写,在IEEE浮点数算术标准(IEEE 754)中定义,表示一些特殊数值(无穷与非数值(NaN)),为许多CPU与浮点运算器所采用。
三种
1、构造函数继承
原理:利用call,apply,bind等方法,在构造函数内部去调用别的构造函数,为己所用.
缺点:原型对象的函数无法复用
2、原型链继承
优点:实现了原型对象内的函数复用.
缺点:虽然得到了属性值,但无法在实例对象内灵活的传参,根本不能用.
3、组合继承
原理:构造函数继承与原型链继承的组合使用.
优势:既实现了原型对象内的函数复用,又可以在实例对象内灵活的传参.
1.2
1.原型链继承
2.借助构造函数继承
3.组合式继承
4.原型式继承
5.寄生式继承
6.寄生组合式继承
[0] 是true 但是 [0]他只有一个元素。那么你取第一位他肯定是没有的 那不就是越界得undefined
然后undefined 隐式成false
undefined 隐式转换 false
JS获取鼠标位置的方法:
1、使用clientX和clientY属性
2、使用offsetX和offsetY属性;
3、使用pageX和pageY属性;
4、使用screenX和screenY属性;
5、使用layerX和layerY属性。
属性及其兼容性
属性 说明 兼容性
clientX 以浏览器窗口左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 Safari
clientY 以浏览器窗口左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 Safari
offsetX 以当前事件的目标对象左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 Mozilla
offsetY 以当前事件的目标对象左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 Mozilla
pageX 以 document 对象(即文档窗口)左上顶角为原点,定位 x 轴坐标 所有浏览器,不兼容 IE
pageY 以 document 对象(即文档窗口)左上顶角为原点,定位 y 轴坐标 所有浏览器,不兼容 IE
screenX 计算机屏幕左上顶角为原点,定位 x 轴坐标 所有浏览器
screenY 计算机屏幕左上顶角为原点,定位 y 轴坐标 所有浏览器
layerX 最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 x 轴坐标 Mozilla 和 Safari
layerY 最近的绝对定位的父元素(如果没有,则为 document 对象)左上顶角为元素,定位 y 轴坐标 Mozilla 和 Safari
input.value
JS页面跳转
reload() 方法
reload()方法用于刷新当前文档。
reload() 方法类似于你浏览器上的刷新页面按钮。location.reload();
在按钮中可以使用 onclick 事件:
<input type="button" onclick="javascript:location.reload();" value="刷新当前页面">
事件委托也称之为事件代理(Event Delegation)。是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
举个通俗的例子:比如一个宿舍的同学同时快递到了,一种方法就是他们一个个去领取,还有一种方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一 一分发给每个宿舍同学;
在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM 元素,而出去统一领取快递的宿舍长就是代理的元素,所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。
一个事件触发后,会在子元素和父元素之间传播(propagation)。这种传播分成三个阶段。
(1)捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
(2)目标阶段:在目标节点上触发,称为“目标阶段”
(3)冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层。
事件委托的优点:
【1】可以大量节省内存占用,减少事件注册,比如在ul上代理所有li的click事件就非常棒
ul id=“list”>
li>item 1
【2】可以实现当新增子对象时无需再次对其绑定(动态绑定事件)
假设上述的例子中列表项li就几个,我们给每个列表项都绑定了事件;
在很多时候,我们需要通过 AJAX 或者用户操作动态的增加或者删除列表项li元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件;
如果用了事件委托就没有这种麻烦了,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的;所以使用事件在动态绑定事件的情况下是可以减少很多重复工作的。
使用事件委托注意事项:使用“事件委托”时,并不是说把事件委托给的元素越靠近顶层就越好。事件冒泡的过程也需要耗时,越靠近顶层,事件的”事件传播链”越长,也就越耗时。如果DOM嵌套结构很深,事件冒泡通过大量祖先元素会导致性能损失。
2.怎么阻止默认动作?
有一些html元素默认的行为,比如说a标签,点击后有跳转动作;form表单中的submit类型的input有一个默认提交跳转事件;reset类型的input有重置表单行为。
如果你想阻止这些浏览器默认行为,JavaScript为你提供了方法。
var $a = document.getElementsByTagName("a")[0];
$a.onclick = function(e){
alert("跳转动作被我阻止了")
e.preventDefault();
//return false;//也可以
}
默认事件没有了
既然return false 和 e.preventDefault()都是一样的效果,那它们有区别吗?当然有。
仅仅是在HTML事件属性 和 DOM0级事件处理方法中,才能通过返回 return false 的形式组织事件宿主的默认行为。