1、闭包:希望保护一个可以反复使用的局部变量的一种词法结构:
全局:容易被污染
局部:一次性的
缺陷:用多了会导致内层泄漏,性能会出问题
语法:
function outer(){
受保护的变量
return function(){
操作受保护的变量
}
}
场景:防抖节流:elem.onmousemove、input.oninput、window.onresize
2、面向对象:
封装:创建
1、直接量:
var obj={
"属性名":属性值,
...
"方法名":function(){},
...
}
2、预定义构造函数:var obj=new Object();//空对象
obj.属性名=属性值;
obj.方法名=function(){}
3、多个对象:自定义构造函数
function h52201(name,age,hobby){
this.name=name;
this.age=age;
this.hobby=hobby;
}
var dls=new h52201("代老湿",18,"发飙");
4、*****this的指向:
1、事件中,单个元素绑定事件this->单个/这个元素
2、事件中,多个元素绑定事件this->当前触发事件的元素
3、构造函数中this->正在创建的对象
4、定时器中this->window
5、函数中出现了this->当前函数的调用者
6、箭头函数中this->外部的对象
继承:多个子对象共用的属性和方法,应该集中定义在父对象中 为什么:代码重用
如何找原型对象:
1、对象名.__proto__
2、构造函数名.prototype
设置共有属性和共有方法:
原型对象.属性名=属性值;
原型对象.方法名=function(){}
原型链:每个对象都有一个.proto,不断的一层一层的找到原型,形成的一条链式结构,称之为叫做原型链
作用:找到共有属性和共有方法
笔试题:
1、判断自有共有没有
if(obj.hasOwnProperty("属性名")){
自有
}else{
if("属性名" in obj){
共有
}else{
没有
}
}
2、设置/删除属性和方法
自有:obj.属性名=属性值;
delete obj.属性名;
共有:obj.__proto__.属性名=属性值;
delete obj.__proto__.属性名;
3、为一类人添加共有方法
if(Array.prototype.indexOf===undefined){
Array.prototype.indexOf=function(){
//原理
}
}
4、判断x是不是数组:
1、是不是继承自Array的原型
Array.prototype.isPrototypeOf(x);
2、是不是由Array构造函数创建的
x instanceof Array
3、Array.isArray(x);
4、Object.prototype.toString.apply(x)==="[object Array]"
多态:同一个函数,但是不同的人来使用,效果完全不同,其实根本不是同一个函数
子对象觉得父对象的成员不好用,在本地定义了一个同名成员,覆盖父对象的
5、自定义继承:
两个对象之间:子对象.__proto__=父对象;
多个对象之间:构造函数名.prototype=父对象;//时机
1、ES5:
1、保护对象:
1、四大特性:
Object.defineProperties(obj,{
"属性名":{
value:实际保存值的地方,
writable: true/false,//是否可以被修改
enumerable: true/false,//是否可以被 for in遍历到
configurable: true/false,//是否可以被删除
},
...
})
2、三个级别:
防扩展:Object.preventExtensions(obj);
密封:Object.seal(obj);
冻结:Object.freeze(obj);
2、数组的新的API:
1、判断:
arr.every/some((val,i,arr)=>判断条件);
2、遍历:
arr.forEach((val,i,arr)=>操作)
var newArr=arr.map((val,i,arr)=>操作)
3、过滤:var newArr=arr.filter((val,i,arr)=>判断条件);
汇总:var sum=arr.reduce((prev,val,i,arr)=>prev+val);
底层都是for循环
3、创造
var 子对象=Object.create(父对象{
"属性名":{
value:实际保存值的地方,
writable: true/false,//是否可以被修改
enumerable: true/false,//是否可以被 for in遍历到
configurable: true/false,//是否可以被删除
},
...
})
4、严格模式:"use strict";
特点:1、禁止全局污染
2、静默失败升级为错误
5、call/apply - 借用:临时替换了函数中的this
函数名.call(借用的人,实参1,实参2,...)
函数名.apply(借用的人,arr) - 悄悄的将数组打散
借用会立刻执行
bind - 买:永久替换了函数中的this
var 新函数=函数名.bind(买的人,永久固定的实参) - 不会立刻执行,需要时自己调用
2、ES6
1、模板字符串:`我的名字叫${name}`
2、let关键字:let 变量名=值
特点:
1、禁止声明提前
2、添加了块级作用域,{}
3、记录着当前触发事件的元素的下标
3、箭头函数:
function省略,()和{}之间添加=>,形参只有一个省略(),函数体只有一句话,省略{}
函数体只有一句话并且有return,return和{}要同时省略
4、for(var v of arr){
v;//当前值
}
查找元素:
1、直接找到某个/某些元素:
标签名/class/Name:var elems=document.getElementsByTagName/ClassName/Name("标签名/class/Name");
css选择器:var elem=document.querySelector("任意css选择器");
var elems=document.querySelectorAll("任意css选择器");
动态集合:每一次修改DOM树,都会悄悄的再次查找,保证页面跟数据同步
静态集合:每一次修改DOM树,数据都不会变化,但是支持forEach
2、关系找元素:前提:先找到某个人
父:xx.parentNode
子:xx.children - 集合:只能找到儿子,不能找到后代
第一个儿子:xx.firstElementChild;
最后一个儿子:xx.lastElementChild;
前一个兄弟:xx.previousElementSibling;
后一个兄弟:xx.nextElementSibling;
3、层级不明确的时候:更推荐使用递归
1、递归:函数中再一次调用了函数自己,但传入的实参一直在不断的变化,而且总有一天会停止
function 函数名(根){
第一层要做什么
判断有没有下一层有的话再次调用此方法,传入下一层的实参
}
函数名(根元素/根数据)
2、TreeWalker:
1、创建tw:
var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT);
2、反复调用tw的nextNode方法
while((node=tw.nextNode())!=null){
node要做什么操作
}
1、创建元素:2步
1、创建空标签:var elem=document.createElement("标签名");
比如:var a=document.createElement("a");
2、添加必要的属性 和 事件
elem.属性名="属性值"
elem.on事件名=function(){操作}
以上两步只是在js内存中创建出了元素,还需要渲染到DOM树上
2、渲染页面方式:3种
*1、父元素.appendChild(新);//新元素会追加到父元素中当最后一个儿子
2、父元素.insertBefore(新,已有子元素);//新元素会追加到父元素中当儿子,会插到已有子元素的前面
3、父元素.replaceChild(新,已有子元素);//新元素会替换到父元素中当儿子,会替换已有子元素
3、删除元素:elem.remove();
核心DOM已经全部学习完毕了:总结一句话说完:增删改查DOM(元素、内容、属性、样式)
3、HTML DOM常用对象:HTML DOM就是对核心DOM进行了简化:
1、Image对象:图片对象:
简化了创建方式:var img=new Image();
不是人人都能简化创建,只有个别可以
2、Form对象:表单对象:
简化了查找元素:var form=document.forms[i];//获取页面上的第i个form元素
简化了查找表单控件元素:var inp=form.elements[i]//获取此form表单中的第i个表单空间元素
3、*Select对象:
属性:1、select.options === select.children 获取到select下面的所有option
2、*select.selectedIndex;//获取到选中项的下标
方法:1、*select.add(option);//将option上树
2、select.remove(i);//删除下标为i的option
*专属事件:onchange - 选中项发生改变后才会触发
4、*Option对象:
简化了创建方式:var opt=new Option("innerHTML","value");
建议你,如果以后希望创建出opt并且放到select中:一句话完成4个操作
select.add(new Option("innerHTML","value"))
一阶段常识:
表单控件元素必须添加name,才能传到服务器端/后端
有的表单控件还要添加value,用户不能输入只能选择的,我们程序员就要把value提前写好,供用户选择