1.18
js为执行队列,其为轮转时间片,单线程
页面级js
<script>
</script>
外联式js
<script type="text/javascript" src="practice.js">
</script>
变量类型
原始值(Stack)number boolean string undefined null
引用值(heap)array object function(相当于为全局变量,heap堆存储的是相应变量的地址)
js分两种错误
1.语法解析错误
2.逻辑错误
一个代码块的错误不会影响其他的代码块
NaN(not a number)
type of()
分辨变量的类型
typeof(a)//"undefined"
typeof(null)//"Object"
number string bollean object undefined function
显式类型转换
Boolean()"" ->false " "->true
Number() null -> 0 | undefined ->NAN | [ ]->0 | {} ->NAN转化为数字
parseInt() 转化为整形可以截断数字(parseInt(2,8))看是否可以为8进制,若不行,则输出NaN;
parseFloat()转化为浮点型
String()转化为字符串
ToString()不能用的 undefined null
isNaN()隐式转化为Number()再和NaN进行比较返回true或faulse
a++ 和 +/-a调用Number()进行转化
"+"两边若有一个为string类型,则调用string()
“%” "- " “*” "\ == 调用Number()
=== !==绝对,不发生类型转换
被认为false的值:undefined null NaN " " 0 false
num.tofixed(3)//保留三位有效数字
var demo = 1;
num = demo.TOString(8);//将十进制转化为8进制
1.20
函数
函数声明
function test(){
console.log("a");
}
驼峰命名法
匿名函数
var test = function ab(){
}//表达式函数名会没用
test.name = ab
立即执行函数
(function () {
alert("我是一个匿名函数");
})();
(function(){
alert();
}())//w3c建议使用
只有表达式才能被执行符号执行
表达式被执行时会自动忽略函数名
arguments 实参列表
function.length 形参长度
系统中有映射规则
function sum(a,b){
var a = 2;
arguments[0] = 3;
console.log(a);
}
sum(3);
会打印出3
只有当arguments上有值才会映射
function sum(a,b){
arguments[1] = 3;
console.log(b);
}
sum(2);
值为undefined
函数作用域
1.全局变量
在全局上定义的是全局变量,函数内部可以访问全局变量
2.局部变量
函数内定义的是局部变量
闭包
js三部曲
1.语法分析
2.预编译
3.解释执行
预编译:
imply global(暗示全局变量)
若有个变量未经声明就赋值,此变量为全局对象(window)所有
全局上的任何变量即使声明了也归window所有
var a = 3 -> window.a = 3;
window就是全局的域(domain)
四部曲:
1.创建AO对象(active object)执行期上下文
2.找形参和变量声明,将变量和形参名作为AO对象的属性名,值为undefined
3.将实参和形参相统一
4.在函数中找函数声明,值赋予函数体
GO(golbal Object)= window
先生成GO再生成AO
函数是一种特殊的对象
1.21
[[scope]]就是我们所说的作用域,是执行期上下文的集合
仅供javascript引擎使用
AO是作为即时的空间内,当函数执行完毕,他的执行期上下文被销毁
作用域链:[[scope]]中存在作用域链
查找变量:从该函数的作用域链的顶端开始查找
内部函数被保存到了外部,称为闭包
闭包会造成原有作用域链不释放,会造成内存泄漏
对象
对象的创建办法
1.var obj ={} plainObject 对象字变量、对象直接量
2.构造函数
1.系统自带
var obj = new Object();
2.自定义
包装类
给原始值加属性会调用包装类
var num = new Number(123);
var str = new String('add');
var bol = new Boolean();
上述为包装类
var num = 4;
num.len = 3;
//new Number(4).len = 3 delete
console.log(num.len);
//new Number(4).len
打印出来为undefined
var str = 'abcd';
str.length = 2;
//new String('abcd').length = 2
console.log(str)
打印出来为abcd
1.22
原型,原型链,call/apply
原型是构造函数的一个属性,是公有祖先
function Person(){
}
Person.prototype.lastName = "jiang";
var person = new Person();
将共有部放在原型中,即提取公有属性
constructor查询对象的构造函数
proto:person:prototype;隐式的,人为加上的的系统不会读,自然也不能继承
Person.prototype.name="sunny";
function Person(){
}
var person = new Person();
Person.prototype={
name:'cherry'
}
console.log(person.name);
打印sunny
Person.prototype.name="sunny";
function Person(){
}
var person = new Person();
Person.prototype.name = "cherry";
console.log(person.name);
打印cherry
原型链
Grand.prototype.Lastname = "jiang";
function Grand(){
}
var grand = new Grand();
function Farther(){
this.name = "xiaoming";
}
Farther.prototype=grand;
var father = new Farther();
function Son(){
this.hobbit = "smoke";
}
Son.prototype = father;
var son = new Son();
this谁调用this就指向谁
var obj1={name:"jeh"};
var obj= Object.create(obj1);//var obj = Object.create(原型)
绝大多数对象的最终都会继承自Object.prototype
var obj1 = Object.create(null);
上述为唯一的没有原型的情况
docment.write()会隐式调用内容的toString方法
var obj = Object.create(null);
obj.toString= function(){ return "jth";};
document.write(obj);
可正常计算的范围 小数点前十六位和后十六位
call
function Person(name,age){
this.name = name;
this.age = age;
}
var obj = {}
Person.call(obj,"jth",20);
利用别人的方法实现自己的功能
改变this的指向,即将this改为obj(call里面的第一个参数)
apply
后面只能传数组
function Person(name,age){
this.name = name;
this.age = age;
}
var obj = {}
Person.apply (obj,["jth",20]);
继承模式,命名空间,对象枚举
1.传统模式:原型链
过多的继承了没用的属性
2.借用构造函数
call/apply
不能借用构造函数的原型
效率低下
3.共享原型
不能随便改变自己的原型
Father.prototype.lastName = "jiang";
function Father(){
}
function Son(){
}
function inherit(origin,target){
origin.prototype=target.prototype;
}
inherit(Son,Father);
var son = new Son();
var father = new Father();
4.圣杯模式
Father.prototype.lastName = "jiang";
function Father(){
}
function Son(){
}
function inherit(origin,target){
function F(){
}
F.prototype = target.prototype;
origin.prototype= new F();
orgin.prototype.constructor=orgin;
orgin.prototype.uber=target.prototype;
}
inherit(Son,Father);
var son = new Son();
var father = new Father();
命名空间
管理变量,防止污染全局,适用于模块开发
this.a = this[“a”];
this[“wife” + num]
for in循环
var obj{}
for(var prop in obj){
console.log(obj.prop+""+typeof(prop));//遍历类
}
即for(varin)
hasOwnProperty
var obj{}
for(var prop in obj){
if(obj.hasOwnProperty(prop))
console.log(obj.prop+""+typeof(prop));//遍历类
}
过滤不属于自己的属性
in
"height" in obj;//返回true or false会查找到原型上
instanceof
A对像是不是B函数构造出来的
A的原型链上有没有B
function Person(){
}
var person = new Person();
person instanceof Object;
区分[] 和 {}
1.
var num = [];
var obj = {};
num.constructor;//ƒ Array() { [native code] }
obj.constructor;//ƒ Object() { [native code] }
var num = [];
var obj = {};
num instanceof Array;//true
obj instanceof Array;//false
var num = [];
var obj = {};
Object.prototype.toString.call([])//'[object Array]'
Object.prototype.toString.call({})//'[object Object]'
1.23
克隆,arguments
1.判断是不是原始值
2.判断是数组还是对象
3.建立相应的数组或者对象
var obj = {
}
var obj1 = {
}
function deepClone(orgin,target){
var target = target || {};
toStr = Object.prototype.toString;
arrStr ="[Object Array]";
for(var prop in origin){
if(origin.hasOwnProperty(prop)){
if(typeof(orgin[prop])=='Object'&& orgin[prop] !== 'null')
{
if(toStr.call(orgin[prop]) == arrStr)
{
target[prop] = orgin[prop];
}
else{
target[prop] = {};
}
deepClone(orgin[prop],target[prop]);
}
else
{
target[prop] = orgin[prop];
}
}
}
return target;
}
三目运算符
var num = 1 > 0 ? 2 + 2 : 1 + 1
数组
//数组的定义
var num = new Array(3);
字变量
数组的和写
可以溢出写
不可溢出读//undefined
改变原数组
var arr = [];
arr.push(10);//加在数组的最后面
arr.pop();//去掉最后的一个
arr.shift(1);
arr.unshift(0)//加在数组的最前面
arr.sort(function(a,b){
return a>b?1:-1})//必须写两个形参 看返回值(当返回值为负值时,那么前面的数放在前面) 为0,不动 为正,后面的放前面
arr.revorse();//反转
var arr = [1,2,3,4,5]
arr.splice(1,2,4)//从第几位开始,截取多少长度的数据,在切口添加新的数据
arr.splice(-1)//splice = function(start){
//start += start>0?0:this.length;
//}
不改变原数组
var arr = [1];
var arr1 = [1,3];
arr2.concat(arr,arr1);
arr.toString();
var newArr = arr.slice();//从该位截取到该位 不写为整个截取
var newStr = arr.join("")//按传送的参数进行连接
newStr.split("")//按参数拆解
类数组
属性为索引(数字)属性,必须有length属性,最好有push属性
var obj = {
"0" : 1,
"1" : 3,
"length":2,
"push":Array.prototype.push,
"splce":Array.prototype.splice
}
Array.prototype.push = function(target){
obj[obj.length] = target;
obj.length++;
try…catch
try{
}catch(e){
}
es5.0严格模式
es3.0 es5.0 es6.0
es5.0严格模式, 那么es5.0和es3.0冲突的部分则使用es5.0的
两种用法
全局
"use strict";//启用方法
局部内部的严格模式(推荐)
function test(){
"use strict"
cosole.log(arguments.callee);
}//reference error
with() 会改变作用域链的顺序,将参数作为最顶端的AO
caller()
变量赋值前必须声明,预编译时this不在指向window
重复的参数和属性名会报错
eval("console.log(“a”)会将字符串中的代码执行 eval是魔鬼 会改变作用域
DOM
docment object model
是操作html和xml的接口
var div = document.getElementsByTagName('div')[0];
div.onlick = function(){
this.style.backgroundColor = red;
}
1.24
接受的成组的基本上为类数组
var div1 = document.getElementById('only');//选择ID
var div1 = document.getElementsByTagName('div');//选择标签名
var div1 = document.getElementsByClassName('demo');//ie8及以下的不能使用
var div1 = document.getElementsByName('demo');//选择name为参数的标签,只有部分标签可以使用(form,img,iframe,form属性的)
var div = document.querySelector('div > span strong.demo');
var div = document.querySelectorAll('div > span strong.demo');//一般不用,ie7及以下不可用,不是实时的
遍历结点树
div.parentNode//父节点
div.childNodes//所有子节点
div.firstChild//第一个子节点
div.lastChild//最后一个子节点
div.nextSibling//下一个兄弟节点
div.prevousSibling//上一个兄弟结点
遍历元素节点树
div.parentElement//元素父节点
div.children//元素子节点
div.firstElementChild
div.lastElementChid//IE不兼容 ie9以下
div.nextElementSlibing
结点类型
元素结点-1
属性结点-2
文本结点-3
注释结点-8
document-9
DocumentFragment-11
获取结点类型 nodeType 返回数
结点的四个属性
1.nodeName 只能读,标签大写
2.nodeValue 只有文本结点和注释结点text comment可读写
3.nodeType 返回结点类型所对应数字
4.attributes elment 结点的集合
5.Node.hasChildNodes 是否有子节点
dom基本操作
增
var div = document.createElement('div');
document.body.appendChild(div);
var a = document.createElement('');//创建元素结点
var text = document.createTextNode('');//创建text结点
var comment = document.createComment('');//创建注释结点
插入
appendChild()//插入
insertbefore(a,b)//insert a before b
删除
parent.removeChild()//剪切出来剪切子节点
child.remove()//销毁自己,
更换
parent.replaceChild(new,orgin);
Element的一些属性
innerHtml改变内容
innerText firefox不兼容
textContent
setAttribute(“class”,“demo”)加属性
getAttribute(‘id’)
1.25
日期对象date
var date = new Date();
date.getTime();//获取时间戳
var timer = interval(fnction(){},1000);//定时循环器
clearInterval(timer);
var timer2 = setTimeout(function(){},1000)//定时执行器//只执行一次
clearTimeout(timer2);
内部this中指向window,window上面的函数
事件
var div = document.getElementsByTagName('div')[0];
div.onclick = function(){
this.backgroundcolor = 'red';
}
<div onclick = "console.log('a')">123</div>
div.addEventListener('type',function,false);//IE9以下不执行 this指向dom本身
div.addEventListener('click',function(){},false);
div.attachEvent('on' + type,function(){});//iE9专用this指向window
经典题
var liList = document.getElementsByTagName('li');
length = liList.length;
for(var i = 0; i < length;i++)
{
(function(i){
liList[i].addEventListener('click',function(){console.log(i)},false);
}(i))
}
闭包问题
自己封装的函数(封装兼容性)
function addEvent(elem,type,handle){
if(elem.addEventListener){
elem.addEventListener(type,handle,false);
}
else if(elem.attachEvent){
elem.attachEvent('on' + type,function(){
handle.call(elem);
})
}
else
{
elem['on'+type] = handle;
}
}
解除事件
ele.onclick = null;
ele.removeEventListener('click',handle,false);
ele.detachEvent('on'+type,fn);
事件处理模型
事件冒泡:结构上嵌套的自子元素会冒泡到父元素(存在与结构上,视觉上不是),自底向上
事件捕获:将false改为true 自上向下,从父级到该子级
一个对象只有一种模型(先捕获后冒泡)
focus blur change submit reset select等事件不冒泡
取消冒泡
w3c标准
div.onclick = function(e){
e.stopPropagation();
e.cancleBubble(true);
}
封装函数
function stopBuble(event){
if(event.stopPropagation){event.stopPropagation()}
else{event.cancleBubble(true);}
}
阻止默认事件
document.oncontextmenu = function(e){
return false;//以对象属性的方式注册的事件才有效
e.preventDefault();//w3c
e.returnValue = false
}
封装成函数
function cancleHandler(event){
if(event.preventDefault){
e.preventDefault();
}
else{event.returnValue = false;}
}
事件对象
var event = e || window.event;
var eventOrgin = event.target || event.srcElement
事件委托
1.26
click.mousedown.mousemove.mouseup.contextmenu.mouseover.mouseout.mouseenter.mouseleave
button:0(left) 1 2(right)
click事件只能监听左键,只有mouseup and mousedown
区分onclick
var firstime = 0;
var lastime = 0;
var key = false;
var div = document.getElementsByTagName('div')[0];
div.onmousedown = function(){
firstime = new Date().getTime();
}
div.onmouseup = function(){
lastime = new Date().getTime();
if(lastime = firstime < 300){
key = true;
}
}
div.onclick = function(){
if(key){
console.log('click');
key = false;
}
}
键盘类事件
keypress != keydown + keyup
keydown>keypress>keyup
按住之后连续触发
keydown:可以监听所有的数据
keypress:监听字符类以及其大小写
文本类操作事件
oninput:只要有改变就会触发 change:鼠标聚焦和失去焦点时才会触发
focus: blur
窗体操作类
onscroll: onload
regExp正则表达式
1.字面量(最常用)
var str = 'mjj';
var p = /mjj/g;
p.test(str);
2.构造函数
var str = 'alex';
var p = new RegExp('alex','g');
p.test(str);
test()校验匹配的规则是否匹配(元字符)
元字符
/./g;//匹配所有字符
/^/g;//匹配字符串开始的位置
/$/g;//匹配结束的字符
var str = 'hello world';
var p = /^hello/g;
var p1 = /world$/g;
console.log(p.test(str));
console.log(p1.test(str));
匹配数字和字母(\w \W)
\w匹配数字和字母
\W匹配非字母和数字
只匹配数字和非数(\d \D)
\d匹配数字
\D匹配非数
匹配空白字符(\s \S)
\s匹配空格
\S匹配非空格
[a-f A-Z0-9]匹配[]之间的字符
[\u4e00-\u9fa5]匹配中文unicode码
[^a-z]不在a到z之间的
匹配重复字符
/mj+/+可以匹配一次或着多次
/[mM][jJ]/m or M j or J
- 匹配重复0次或者多次
?0次或者是1次
分组匹配
| 或者
()分组
RegExp.$1:捕获
/(http|https):\/{2}w{3}/g//捕获
console.log(RegExp.$2);
/(?:http|https):\/{2}w{3}/g//$不捕获
正向预查
/\d+(?=元)/g//正向肯定预查 一定是元,但不匹配
/\d+(?!元|\d)/g//正向否定预查 肯定不是元,不匹配
反向预查
/(?<=$)\d+/g
/(?<!$|\d)\d+/g
重复类
/\d{4,8}/g最少四位,最多八位
test() and exec()
exec()返回匹配的结果,发现匹配,返回一个数组,为匹配的字串,没匹配,为null
match():返回匹配的结果,参数为匹配模式
search()返回匹配到的位置,若没有则为-1
repalce()
var timeStr = '2022.1.25';
console.log(timeStr.replace(/\./g,'-'));