1.面向对象
- 工厂模式:很多功能或对象需要重复使用时,需要封装成函数
- 构造函数:当用new去调用一个函数的时候,这个函数就是构造函数
// 工厂函数
function createPerson(name.sex){
var obj=new Object();
obj.name=name;
obj.sex=sex;
obj,show=function(){};
return obj;
}
// 构造函数
function createPerson(name.sex){
this.name=name;
this.sex=sex;
this.show=function(){};
}
// 复制对象
function extend(obj1,obj2){
for(var i in obj1){
obj2[i]=obj1[i];
}
}
2.原型
- 原型:可以去改写对象下面共用的方法或属性,让共用的方法或属性在内存中也存在一份(提高性能)
function 构造函数(属性1,属性2){
this.属性1=属性1;
this.属性2=属性2;
}
构造函数.prototype.方法=function(){}
- hasOwnProperty:查看是否是对象下面自身的属性(永远不会去原型里寻找的属性)
- constructor:查看构造函数,返回
- instanceof:查看对象和构造函数在原型链上是否有关系
3.继承
var a={
name:'zhangsan'
};
var b=cloneObj(a); //没有用到new
function cloneObj(obj){
//创建一个代理函数
var F=function(){
}
F.prototype=obj; //用代理函数接受要被继承的对象
return new F(); //返回的是代理函数的实例
}
alert(b.name);
b.name='李四';
alert(a.name);
function CreatePerson(name,sex){
this.name = name;
this.sex = sex;
}
CreatePerson.prototype.showName = function(){
alert(this.name);
}
var p1 = new CreatePerson("zhangsan","男");
//p1.showName();
//现在来一个学生类 属性:name,sex,address
//分析:一个学生类:属性和方法 分开继
function Student(name,sex,address){
//继承父类,人类 name,sex this==>学生
CreatePerson.call(this,name,sex);
//name,sex继承成功,把CreatePerson的th指向指向到当前student类
this.address = address;
}
extend(CreatePerson.prototype,Student.prototype);
function extend(obj1,obj2){
for(var attr in obj1){
obj2[attr] = obj1[attr];
}
}
var s1 = new Student("lisi","女","武汉");
s1.showName();
4.事件
e.stopPropagation()/return false(只能使用在jq中)
阻止默认事件:return false
function (obj, eventType, fn) {
if (obj.attachEvent) {
obj.attachEvent('on' + eventType, fn);
} else {
obj.addEventListener(eventType, fn, false);
}
}
oUl.onmouseover = function (event) {
var event = event || window.event;
var target = event.target||event.srcElement;
var nodeName=target.nodeName;
if(nodeName.toLowerCase()=='li'){
target.style.background = 'green';
}
}
5.原生ajax
// 实例化,配置请求信息,发送请求,设置回调函数
// 分析:
// 期望:ajax(method,url,data,success)
/**
* ajax封装
* @param {*} method get/post
* @param {*} url 请求资源路径
* @param {*} data 请求参数
* @param {*} success 回调函数
*/
function ajax(method, url, data, success) {
// 1.实例化对象
var xhr = null; // 实例化一个对象,初始值为空 new XMLHttpRequest();
if (window.ActiveXObject) { //IE5IE6是以ActiveXObject的方式引入XMLHttpRequest
xhr = new ActiveXObject('Microsoft.XMLHTTP');
} else if (window.XMLHttpRequest) { //除IE5 IE6以外的浏览器XMLHttpRequest
xhr = new XMLHttpRequest(); //实例化一个XMLHttpRequest
}
// 2.配置信息 open()
if (method == 'GET' && data) { //判断data存在并且是GET方式
url += '?' + data;
}
xhr.open(method, url, true);
// 3.发送请求 send(),如果是POST方式,参数写在括号里
if (method == 'GET') {
xhr.send();
} else if (method == 'POST') {
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(data);
}
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 如果回调函数不为空,就执行这个回调函数,该函数有一个参数xhr.responseText就是返回的内容
success && success(xhr.responseText);
}
}
}
}
6.跨域
- 跨域:同源策略的影响,解决方式
动态创建script标签(jsonp)只能解决get方式的跨域
var oBtn=document.getElementById('btn');
oBtn.onclick=function(){
// 点击的瞬间,创建scrpt标签
var oScript=document.createElement('script');
oScript.src='1.txt';
document.body.appendChild(oScript);
}
--------------------------------------------------------------------
// fn相当于回调函数,请求成功执行的事件
function fn(data){
// data就是获取过来的数据
// alert(data);
for(var i=0;i<data.length;i++){
var oDiv=document.createElement('div');
oDiv.innerHTML=data[i];
document.body.appendChild(oDiv);
}
}
7.封装tab选项卡
function Tab(id){
//this=>实例对象 这个实例对象下面有三个属性
this.oParent = document.getElementById(id);
this.aInput = this.oParent.getElementsByTagName("input");
this.aDiv = this.oParent.getElementsByTagName("div");
}
Tab.prototype.init=function(){
var This = this;//存储tab实例对象
for(var i = 0; i<this.aInput.length; i++){
this.aInput[i].index = i;//添加自定义属性
this.aInput[i].onclick = function(){
//this==>btn,期望实例对象去掉用change
This.change(this);
}
}
}
Tab.prototype.change = function(obj){
for(var j = 0; j<this.aInput.length; j++){
//aInput[j] aDiv[j]
this.aInput[j].className="";
this.aDiv[j].style.display = "none";
}
obj.className = "active";//这里的this期望指的是btn
//当this发生冲突的时候,保大对象
this.aDiv[obj.index].style.display = "block";
}
window.onload = function(){
var t1 = new Tab("div1");
t1.init();
var t2 = new Tab("div2");
t2.init();
var t3 = new Tab("div3");
t3.init();
}
8.闭包
- 闭包不会产生垃圾回收,函数在执行完毕之后会去查看这个函数在其他地方有没有被引用如果有,就不会GC产生垃圾回收,如果没有就会自动垃圾回收
- 本来一个函数内部是无法访问外部函数的变量的。闭包就是在这个外部函数里面定义一个内部函数,通过这个内部函数使用变量,进而给外部函数使用
- 表现形式:全局变量,return,传参
- 闭包使用不当会产生内存泄漏
// 第一种方式 return
function fn1(){
var a=2;
return function (){
console.log(a); //内部函数可以访问a
} //返回的结果是f函数
}
fn1()();
// 第二种方式 传参
function fn1(){
var a=5;
function f(){
console.log(a);
}
bar(f);
}
//定义bar,也要定义一个形参,传进一个函数,就去执行一个函数
function bar(fn){
fn();
}
fn1();
// 第三种方式 全局变量
var fn;
function fn1(){
var a=1;
function f(){
console.log(a);
}
fn=f; //把函数赋值给全局,这里产生了闭包
}
fn1();
fn();
9.封装cookie
/**
*
* @param {*} key 键
* @param {*} value 值
* @param {*} day 过期的天数
*/
// 设置cookie
function setCookie(key, value, day) {
var oDate = new Date();
oDate.setDate(oDate.getDate() + day);
document.cookie=key+'='+value+';expires='+oDate.toGMTString();
}
// setCookie('class','aaa',10);
/**
*
* @param {*} key 键
*/
// 获取cookie
function getVal(key){
var str=document.cookie;
var a=str.split('; '); // 注意这里有一个空格
console.log(a);
for(let i=0;i<a.length;i++){
var b=a[i];
var c=b.split('=');
console.log(c);
if(c[0]==key){
return decodeURI(c[1]);
}
}
}
// getVal('class');
// alert(getVal('class'));