【前端学习笔记】重要知识点积累

递归调用———————————————————————————

1.函数调用函数自身,开始执行递的动作。
2.最后一次给他一个判断终止的条件,开始回头执行归的动作
3.简单的递归实例
    //求阶乘
    function jieCheng(i){
        if(i<=1)
        //2.最后一次给他一个判断终止的条件,开始回头执行归的动作
        return 1;
        //1.函数调用函数自身,开始执行递的动作。
        return i*jieCheng(i-1);  
    }

快速排序———————————————————————————

1.找一个基准点
2.建立两个数组,分别存储左边和右边的数组
3.利用递归方式进行下
    function quickSort(arr){
        if(arr<=1){
            return arr; //空数组和单元素数组直接返回 。归
    }
    var num=Math.floor(arr.length/2);//先找到数组的中间位置

    var numValue=arr.splice(num,1);//用splice方法取出这个值

    var left = [];
    var right =[]; 
    //创建两个数组用于存放大于中间值和小于中间值的数。
    for(var i = 0;i<arr.length;i++)
    {
        if(arr[i]>numValue)
        {
            right.push(arr[i]);//大于中间值的放右边
        }
        if(arr[i]<=numValue)
        {
            left.push(arr[i]);//小于中间值的放左边
        }
    }

    //return left.concat(numValue,right);
    return quickSort(left).concat(numValue,quickSort(right));
    //将左和右数组继续快排然后同中间值拼接。 递
    }

表达式—————————————————————————-

函数声明:function 函数名(){}

函数表达式:function 函数名(可写可不写)(){} 命名/匿名函数表达式
function aaa(){};                   //函数声明
    var a=function a(){};              // 命名函数表达式
    var a=function(){};                 //匿名函数表达式


    (function aaa(){});                 //表达式
    ~function aaa(){};
    -function aaa(){};
    +function aaa(){};
    !function aaa(){};
函数声明和函数表达式的区别:
1.函数表达式在后面加()可以直接执行函数,而函数申明不行。
2.函数申明可以被预解析,而表达式要等预解析完毕后根据程序流程顺序去生效。
var a=function aaa(){
        alert(1);
        alert(typeOf aaa);//在内部是能找到的
}
a();           //任何浏览器都能兼容
aaa();         //标准浏览器在外面是找不到的,而IE8以下会将上面的函数表达式分为函数表达式和函数声明两个,所以会调用该函数。
( function aaa(){ alert(1) } );
aaa();
//标准浏览器会报错。
    function aaa(){
        return bbb();
    }
    var bbb = (function bbb(){
        return function(){
            debugger;
        }
    })();

    aaa();

事件委托—————————————————————————-

事件委托:利用事件冒泡的原理,把事件加到父级身上,触发执行效果

event对象-事件源:不管在那个事件中,你操作的那个对象就是事件源
    ie下:window.event.srcElement 
    标准下: event.target 
    var target = ev.target||ev.srcElement;
nodeName:找到当前元素的标签名

好处:1.提高性能
      2.新添加的元素还会有之前父级的委托事件

枚举算法—————————————————————————–

枚举算法,用for来从众多的候选答案中,用if找出正确的解。

经典实例:
            枚  举  算  法  题
        *                   枚
        ———————————————————————————
        题   题   题   题   题   题

求出每个字所代表的数字。

循环判断,从循环的候选答案中找到符合要求的解

布局:
<body>
    <p><span></span>
    <span></span>
    <span></span>
    <span></span>
    <span></span>
    </p>
    *
    <p><span></span></p>
    =
    <p>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </p>
</body>

枚举算法脚本:


window.onload=function(){
    var oP0=document.getElementsByTagName('p')[0];
    var oP1=document.getElementsByTagName('p')[1];
    var oP2=document.getElementsByTagName('p')[2];

    for(var i=1;i<=9;i++)
    {
        for(var j=0;j<=9;j++)
        {
            for(var k=0;k<=9;k++)
            {
                for(var m=0;m<=9;m++)
                {
                    for(var n=0;n<=9;n++)
                    {   
                        var a=i*10000+j*1000+k*100+m*10+n;
                        var b=i;
                        var c=n*100000+n*10000+n*1000+n*100+n*10+n;
                        if(a*b===c)
                        {
                            oP0.getElementsByTagName('span')[0].innerHTML=i;
                            oP0.getElementsByTagName('span')[1].innerHTML=j;
                            oP0.getElementsByTagName('span')[2].innerHTML=k;
                            oP0.getElementsByTagName('span')[3].innerHTML=m;
                            oP0.getElementsByTagName('span')[4].innerHTML=n;

                            oP1.getElementsByTagName('span')[0].innerHTML=i;

                            for(var x=0;x<oP2.getElementsByTagName('span').length;x++)
                            {
                                oP2.getElementsByTagName('span')[x].innerHTML=n;
                            }

                        }
                    }
                }
            }
        }
    }

}

对象引用—————————————————————————–

对象和函数都是引用的关系
例如:
    var a=[1,2,3];
        var b=a;
        b=[1,2,3,4];
        alert(b);  //1234 因为b是[1,2,3,4]的地址
        alert(a);  //123 因为第三行的引用将第二行的引用覆盖了,
    b的指向从原本指向a([1,2,3])变为了指向[1,2,3,4],
    而a并没有改变指向,所以还是指向[1,2,3]

再如:
var obj={ a:10 };
        var obj2=obj;
        obj2.a=20;
        alert(obj.a); //弹出 20
        //因为obj2指向obj指向的地址,
        //修改的也是该地址内容,而不是拷贝一份
    如果要做到拷贝一份,修改obj2不会影响obj的地址内容,要使用自定义方法
function copy(obj){
            var newObj={};
            for(var attr in obj)
            {
                newObj[attr]=obj[attr];
            }
            return newObj;
        }
        obj2=copy(obj);  //这样对obj2的修改就不会影响到之前obj的内容
    这种方法叫做浅拷贝。

    浅拷贝的问题:

    将上面例子的 a的值改为一个json。
var obj={ 
            a:{
                b:10
            }
        };
        var obj2=copy(obj);
        obj2.a.b=20;
        alert(obj.a.b); //弹出的值为20,说明原址内容还是被修改了
    原因是copy方法进行到newObj[attr]=obj[attr];的时候。
    obj只是将其属性a的索引赋值给了newObj的a属性,也就是说
    obj.a和newObj.a还是指向同一个地址,所以对新对象a属性的修改
    还是会影响到之前对象的属性a。这和之前的 var obj2=obj; 是一个道理

    这样就要用到深拷贝
function deepCopy(obj){

            if(typeof obj !='object')         
            // 当传进来的值已经不是对象,开始归
            {
                return obj;
            }

            var newObj={};
            for(var attr in obj)
            {
                newObj[attr]=deepCopy(obj[attr]);  
                //递归调用,确保赋值的是一个新的对象
            }
            return newObj;
        }

操作iFrame—————————————————————————–

1.操作本页的iframe中的元素,要用到contentWindow属性,这个属性所有浏览器都支持。
而在非IE下时,由于安全限制,只有部署在服务器上才能使用这个属性。

除了在IE6-7下,我们可以用contentDocument来代替contentWindow.document

oIframe.contentWindow.document.getElementsByTagName('div')[0];
或
oIframe.contentDocument.getElementsByTagName('div')[0];
//得到iframe中的div元素

2.在iframe中操作本页元素,用window.parent。支持和限制性能同contentWindow

3.在嵌套iframe中操作最外层元素,用window.top

4.和window.onload一样,iframe也能用oIframe.onload,ie下要使用oIframe.attachEvent来绑定onload事件

5.网站的防iframe嵌套处理
if(window!=window.top)
        {
            window.top.location.href=window.location.href;
        }
6.让iframe高度与其内容自适应
oIframe.height=oIframe.contentWindow.document.body.offsetHeight;

js闭包—————————————————————————–

1.什么是闭包

    函数嵌套函数,内部函数可以引用外部的参数和变量,参数和变量不会被
    垃圾回收机制所收回,外部函数最终返回内部函数的函数名。
    从垃圾回收机制来看,一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
    例如:
function test(num){
            var sum=5;
            function alertSum(){
                sum+=num;
                alert(sum);
            }
            return alertSum;
        }

        var a=test(5);
        a();//10
2.闭包的作用,应用在哪里
    好处
      1.希望一个变量长期驻扎在内存中
      2.避免全局变量的污染
      3.私有成员的存在,保护内部变量不被外部调用

    用法
      1.模块化代码,减少全局变量污染。
      2.在循环中直接找到对应元素的索引。

3.闭包需要注意的地方

    IE避免内存泄漏
    例如:
function closureTest(){
            var testDiv=document.getElementById('div1');
            testDiv.onclick=function(){
                testDiv.style.left=100+'px';
            }
        }
    closureTest方法创建了一个内部匿名函数,由于testDiv的onclick
    属性引用了该匿名函数,testDiv是一个外部对象,所以该匿名函数会在
    内存中保存。而该函数所要用的testDiv对象也一直保存在内存中。
    (本来的意愿是不希望testDiv长久保留的)
    这样就形成了内存泄漏。

    解决办法:利用window.onunload=function(){ testDiv.onclick=null; }
    结束循环引用。

JS跨域———————————————————————————

    www.a.com/a.js
    www.a.com/c/b.js  //同域名下不存在跨域问题

    www.a.com
    b.a.com         //子域名下存在跨域问题

    www.a.com
    www.b.com       //不同域名存在跨域问题


    ajax : XMLHttpRequest(); //不能跨域
跨域解决方法
1.主域和子域跨域的时候,主域和子域同时设置document.domain='a.com';
    这里的a.com指的是主域名
2.不同域名下,通过服务器代理。在服务器那边做一个XMLHttpRequest代理文件。
3.用script标签:jsonp的形式(script标签不存在跨域问题)
    jsonp: json+padding(把json内填充到一个盒子中)
    将一个script动态填充到head标签的最后,
    而这个script中的src就是调用函数的文件地址
4.location.hash
5.window.name
6.flash
7.html5 postMessage

firebug————————————————————————-

console.log();//打印信息
    console.warn();//警告信息
    console.error();//错误信息

    console.group();//分组打印信息
    console.log();
    console.log();
    console.groupEnd();

    console.dir(cat);//输出对象所有信息
    console.dirxml(oDiv);//输出元素对象代码结构

    console.assert(false);//断言,断言失败会有信息显示
    console.trace(); //显示函数调用情况

    console.time('计时器名');//测试代码运行时间
        ...
    console.timeEnd('计时器名');

    console.profile();//显示其中的函数调用情况、性能
        ...
    console.profileEnd();

    firebuglite 给其他浏览器使用firebug

JS性能DOM优化—————————————————————————-

JS:DOM+ECMA+BOM+EVENT 
DOM:xml/html文档对象模型 例如document 
ECMA:JS语法 例如if else switch
BOM:浏览器对象模型 例如window location open()
EVENT:事件  例如 ev.attachEvent

用console.time-console.timeEnd
可以测得代码运行时间,同样效果的代码运行时间越少效率越高,
性能越好

【DOM与javascript】
DOM与javascript在浏览器下为两个独立的文件夹

js操作dom需要消耗性能,减少性能消耗可以优化dom
要循环操作oDiv.innerHTML时,先把操作结果存在str变量中,
最后赋值给innerHTML

dom createElement方法(循环创建)和oDiv.innerHTML(先用str循环再赋值)的对比

    chrome(-webkit-) : dom方法要比innerHTML性能好??

    (实测为innerHTML性能更好)

    火狐和IE :  dom方法要比innerHTML性能要差

dom createElement方法( 循环创建 )和oLi.cloneNode( true );

    ( 循环内创建,循环外克隆 )性能对比

    克隆的性能略好。

aLis.length也是dom操作,最好先把其存为一个变量再循环。


document.getElementById(''); 当多次进行这个操作时应该把document存为一个局部变量doc,
减少dom操作数

获取元素时,尽量只用纯获取元素节点的方法。如使用children方法代替childNode方法

获取元素时,可以用新的方法,例如document.querySelectorAll('#ul li');来减少dom操作
不过IE8及该版本以下不支持

【DOM与浏览器】
重排:改变页面内容
重绘:浏览器显示内容
重排和重绘都会对性能产生很大影响,所以要减少该过程。

方法:
1.最好在appendChild之前操作好元素。可以一次性到位。减少重排重绘。

2.合并dom操作,如使用style.cssText代替 style.width[height][background]等一系列的
dom操作。减少重绘

3.缓存布局信息:
    将oDiv.offsetLeft等需要dom操作的布局信息转为变量left保存起来,
然后操作变量。

4.文档碎片。
    每次oUl.appendChild(oLi)会重排重绘。
    可以先var oFrag = document.createDocumentFragment();
    然后每次先添加到oFrag最后再一次性添加到oUl里,一次性到位。
【DOM与事件】
    用事件委托机制,不但减少dom操作,还能动态地给新增的内容绑定事件

【DOM与前端模版】
    MVC基础

HTML5历史管理—————————————————————————-

1.用window.location.hash来记录。
然后点击前进后退时,用window.onhashchange来判断hash值改变
然后通过hash值来获取历史值

2.history:
    history.pushState():三个参数:数据 标题(浏览器都没实现) 地址(可选)
    window.onpopstate
    popstate事件:读取数据 even.state

    注意:当给了第三个参数时,当onpopstate发生的时候,网址是虚假的,
    需要在服务器指定对应页面,不然刷新找不到页面
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值