获取当前页面的宽度和高度

var width = document.documentElement.clientWidth||document.body.clientWidth
var height = document.documentElement.clientHeight||document.body.clientHeight

Math方法及应用

Math.abs();   // 取绝对值
Math.ceil();  // 向上取整(出现小数点就向上+1Math.floor(); // 向下取整
Math.round(); // 四舍五入
Math.max(val1,val2,val3...) // 取最大值
Math.min(val1,val2,val3...) // 取最小值
Math.random(); // 获取[0-1)之间的随机小数(不包含1Math.round(Math.random()*(m-n)+n); // 获取任意两个数之间的随机数
获取4个 0 - 40 之间随机整数
function getRound(n,m) {
        n=Number(n);
        m=Number(m);
        //n和m其中有一个不是数字的情况
        if(isNaN(n)||isNaN(m)){
            //如果传递进来的参数不是一个数字,就直接返回一个0-1之间的随机小数
            return Math.random();
        }
        //n和m都是数字的情况下
        if(n>m){
            var temp=n;
            n=m;
            m=temp;
        }
        var ary=[];
        for (var i=0;i<4;i++){
            var val=Math.round(Math.random()*(m-n)+n);
            ary.push(val);
        }
        return ary;
    }
    console.log(getRound(0,40));

字符串中大小写字转换

toLowerCase();  // 转化为小写
toUpperCase();  // 转换为大写

获取本地时间

var date = new Date(); // 获取当前电脑时间

// 将时间转换为 xxxx年xx月xx日.. 的格式
var str='2016/11/9 12:39:1';
    //20161109123901秒
    //空格分 ['2016/11/9','12:39:01']
    //'2016/11/9' 按照/分割 ['2016','11','9']
    //'12:39:01'  按照:分割['12','39','01']
    function getTime(str) {
        var ary=str.split(' ');//['2016/11/9','12:39:01']
        var ary1=ary[0].split('/');//["2016", "11", "9"]
        var ary2=ary[1].split(':');//['12','39','01']
        return ary1[0]+'年'+zero(ary1[1])+'月'+zero(ary1[2])+'日'+zero(ary2[0])+'时'+zero(ary2[1])+'分'+zero(ary2[2])+'秒';
    }
    console.log(getTime(str));
    
     function zero(num) {
        num=Number(num);//先将参数转为数字
        return num<10?'0'+num:num;
    }

Data应用

var year=time.getFullYear();//设置 Date 对象中的年份(四位数字)
var month=time.getMonth();//根据世界时设置 Date 对象中的月份 (0 ~ 11) 
var day=time.getDate();//从 Date 对象返回一个月中的某一天 (1 ~ 31)
var week=time.getDay();//从 Date 对象返回一周中的某一天 (0 ~ 6) 代表周日-周六
var hours=time.getHours();//返回 Date 对象的小时 (0 ~ 23)
var minutes=time.getMinutes();//返回 Date 对象的分钟 (0 ~ 59)
var seconds=time.getSeconds();//返回 Date 对象的秒数 (0 ~ 59)
var mSeconds=time.getMilliseconds();//返回 Date 对象的毫秒(0 ~ 999)

定时器

window.setInterval(fn,1000); // 每1秒执行一次
window.setTimeout(fn,1000); //1秒后执行一次,只执行一次

clerarTimeout();  //关闭定时器
cleraInterval();  //关闭定时器

闭包

函数执行的时候,产生了一个私有作用域,保护里面的私有变量不受外界干扰(外部获取不到也修改不了),我们将函数执行时候形成的这种保护机制叫做“闭包”。

数组

数组的增加、修改、删除

ary.push();  // 向数组末尾添加一项
ary.pop();   // 删除数组最后一项  (ary.length--)
ary.unshift();  // 向数组开头添加
ary.shift();   // 删除数组第一项

splice  // 删除、修改、增加
1)删除
- splice(n,m);  // 从索引n开始,删除m- splice(n);   // 从索引n开始,删除到最后
- splice(0)/splice();  // 清空原数组

2)修改
- splice(n,m,x);  // 从索引n开始,删除m项,x替换删除部分

3)增加
- splice(n,0,x);  // 从索引n开始,一个都不删除,返回空数组,将x增加到索引n的前面
- splice(ary.length,0,'增加项');  // 向数组末尾增加
- splice(ary.length-1)/splice(ary.length-1,1)  // 删除末尾项

数组的截取和拼接 -- slice

1) 数组的截取
 - slice(n,m);  // 从索引n开始找到索引m,(不包括m)
 - slice(n);  // 从索引n开始,找到末尾
 - slice(0)/slice();  // 克隆一份数组
 
2) 数组的拼接
 - concat(参数是另一个数组);  // 将两个数组拼接到一起 (可拼接多个数组,用逗号分隔)
 - concat();  // 将原数组克隆一份

将数组转换为字符串

toString();
join('符号'); // 将这个符号替换掉原数组的逗号,将其转换为字符串
eval()  // 将js中的字符串变成js表达式执行

数组的排序和排列

reverse();
sort();
sort(function(a,b){
    return a-b
})

从指定字符中查找不重复的随机数

 var box=document.getElementById('box');
    var str='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';//索引0-61 长度62
    var tem=null;
    function getRound(n,m) {
        n=Number(n);m=Number(m);
        if(isNaN(n)||isNaN(m))
            return Math.random();
        if(n>m){
            var temp=n;
            n=m;
            m=temp;
        }
        return Math.round(Math.random()*(m-n)+n)
    }
    function change() {
        var str2='';
        for(var i=0;;i++){
            var eg=getRound(0,61);//得到了四个索引
            var val=str.charAt(eg);//得到字符串中四个索引代表的字符
            if(str2.indexOf(val)===-1){//如果这个字符没有在新的字符串中出现过,就添加到新的字符串中
                str2+=val;
            }
            if(str2.length==4){
                break;
            }//如果这个字符串的长度为4,停止循环

        }
        box.innerHTML=str2;
        return str2;
    }
    change();
    box.onclick=change;

继承

原型继承:B.prototype = new A();

  • 子类的原型指向父类一个实例,父类的公有和私有方法和属性,都是子类的公有方法
function A(){
    this.x = 100;
}
A.prototype.getX = fnction(){
    console.log(this.x);
}
function B(){ }
B.prototype = new A();
B.prototype.constructor = B;

var a = new A();
var b = new B();

call继承 C.call(this);

  • 在子类的构造函数中,把父类的私有方法继承到子类的私有方法
  function C(){
        this.x = 100; // this.x = 100 => d.x = 100 => 给d添加一个100私有属性
        this.y = 200;
    }
    C.prototype.getX = function (){
        console.log(this.x);
    }
    function D(){
        //this => d
        C.call(this);  // 核心代码
        // 把C类中的this修改成d
    }
    var c = new C();
    var d = new D();

冒充对象继承 this[key] = e[key];

  • 在子类的构造函数中遍历父类实例,把父类的公有和私有都变成子类的私有
function E(){
        this.x = 100;
    }
    E.prototype.getX = function (){ // xxxfff000
        console.log(this.x);
    }
    function F(){
        var e = new E();
        for(var key in e){
            // key : x, getX
            //if(e.propertyIsEnumerable) 可枚举
            if(e.hasOwnProperty(key)){
                // 这个判断可以把getX这个公有属性过滤
            }
            this[key] = e[key]; // 核心代码
            // f.x = e.x => f.x = 100;
            // f.getX = e.getX  => f.getX = E.prototype.getX;
        }
    }
    var f = new F();
    console.dir(f); // x : 100, getX : funciton
    console.log(f.getX === E.prototype.getX); // true

组合继承

  • 原型 + call,无论是私有还是公有全部继承到。原来是私有的通过call继承仍然是私有,原来是公有的,通过原型继承仍然是公有
  function G(){
        this.x = 100;
    }
    G.prototype.getX = function () {
        console.log(this.x);
    }

    function H(){
        G.call(this);
    }
    H.prototype = new G();
    H.prototype.constructor = H;

中间件继承 K.prototype.proto = J.prototype;

  • 让子类原型上的__proto__属性,本来应该指向Object.prototype;现在指向父类原型。父类的公有属性变成子类的公有属性
function J(){
        this.x = 100;
    }
    J.prototype.getX = function (){
        console.log(this.x);
    }
    function K(){}
    K.prototype.__proto__ = J.prototype; // 核心代码

JSONP 跨域实现原理

ajax受浏览器同源策略的影响,不允许进行跨域请求,而script标签的src属性中的链接可以进行跨域访问,利用这个特性,服务端不返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行调用,就实现了跨域。

Jquery实现跨域。

    $(document).ready(function(){
        $.ajax({
            type : "get",
            async: false,
            url : "http://www.practice-zhao.com/student.php?id=1",
            dataType: "jsonp",
            jsonp:"callback", //请求php的参数名
            jsonpCallback: "jsonhandle",//要执行的回调函数
            success : function(data) {
                alert("age:" + data.age + "name:" + data.name);
            }

        });
    });

cors实现跨域的原理是,把所有的代码放在服务器端做,客户端只需要发送正常的ajax请求就可以了,服务器端根据需要配置不同的头信息。

数组去重

var arr = [1,2,3,4,1,6,3,2];
var obj = {};
for(var i=0;i<arr.length;i++;){
    var cur = arr[i];
    if(cur == obj[cur]){
        arr.splice(i,1);
        i--;
    }
    obj[cur] = cur;
}
console.log(arr);

如何找出字符串中串中出现最多的字符

 var str = "zhaochucichuzuiduodezifu";
    var o = {};
    for (var i = 0, length = str.length; i < length; i++) {
//        var char = str[i];
        var char = str.charAt(i);
        if (o[char]) {  //char就是对象o的一个属性,o[char]是属性值,o[char]控制出现的次数
            o[char]++;  //次数加1
        } else {
            o[char] = 1;    //若第一次出现,次数记为1
        }
    }
    console.log(o);   //输出的是完整的对象,记录着每一个字符及其出现的次数
    //遍历对象,找到出现次数最多的字符和次数
    var max = 0;
    var maxChar = null;
    for (var key in o) {
        if (max < o[key]) {
            max = o[key];   //max始终储存次数最大的那个
            maxChar = key;  //那么对应的字符就是当前的key
        }
    }
    console.log("最多的字符是" + maxChar);
    console.log("出现的次数是" + max);
</script>

window.onload 和 ready() 的区别

  • window.onload 是在页面中包括图片的所有元素加载完成后执行的
  • ready方法是在DOM结构加载完成后执行的
  • onload方法不能同时编写多个,如果有多个,只会执行一个
  • ready可以同时编写多个,并且都可以执行

this和$(this)的区别

  • this是DOM(javascript)对象,$(this)是Jquery对象,可以使用jquery原型上的所有方法。
  • this加上 $()包起来可以转换为jquery对象。 $(this)转DOM对象在小括号后面加上[0]即可。

移动端适配,设置meta标签

    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
    <!--
    //为了在各个设备上都兼容
    width=device-width 布局视口的宽度 = 设备的宽度
    initial-scale 起始缩放值
    user-scalable:no|yes 是否允许用户去缩放
    maximum-scale 最大缩放倍数
    minimum-scale 最小缩放倍数
    -->

如何设置rem

<script>
        // 各个设备宽度比例  = 各个设备根元素字体大小的比例
        var desW = 640; /*设计稿的宽度*/
        var winW = document.documentElement.clientWidth;//设备的宽度
        //desW / winW = 100/fs;
        //fs = winW/desW*100;
        document.documentElement.style.fontSize = winW/desW*100+"px";
    </script>

检测数据类型

typeof 返回一个字符串,不能清晰的判断引用数据类型 instanceof 判断一个实例是否属于这个类,返回值的true/false constructor 直接打印自己是哪个类的实例,这个属性是可以被修改的 object.prototype.toString.call()

call apply bind

  call方法:
              1、fn通过自己的 __proto__ 属性找到定义在 Function.prototype 上的call方法
              2、把fn函数中的this修改成了call的第一个参数
              3、最后fn执行
              PS:无论哪个函数实例调用call方法都已经执行结束(修改了this之后就立刻执行了)
              PScall的第一个参数的确是用来修改this的。从第二个参数开始是传给调用call方法的那个函数实例的
              ps:如果是多个call方法连用,那么是最后一个call方法的第一个参数执行,如果这个参数不是函数会报错


apply方法:
                相同点:用法和call基本相同。都是用来修改this关键字的
                不同点:传给调用apply的那个函数实例参数不同,apply第二个参数是一个数组。是把数组里的每一项当做参数传给调用apply的函数的。


 bind方法  :不兼容低版本ie
                  用法:都是用来修改this关键字的
                             1、区别于 call 和 apply ,bind 是返回一个处理好 this 的新函数
                             2、返回值函数需要通过自来执行。在执行的时候再传参数 res()

字符串转数组

  • split()

数组转字符串

  • toString()
  • join('')

本地存储

  • 存储大小有限制,一般只能4KB大小
  • 有过期时间,一般不超过一个月
  • 不稳定,可以用安全卫士清理。不安全,可以被修改,是问号传参
localStorage
  • 是H5提供的方法,不谦容IE6-8
  • 大小限制,最多只能存5M大小
  • 没有过期时间,永久保存到本地,只要我们不手动清除的话
  • 和服务器没有半点关系
localStorage.setItem([key],[val]); 设置本地的存储信息 
localStorage.getItem([key],[val]); 获取本地的存储信息 
localStorage.removeItem([key]); 删除指定key对应的本地的存储信息 
localStorage.clear();//清除所有的本地存储信息 
localStorage.key[index]//使用localStorage存储的信息是一个Storage集合,会把所有的属性名key放在集合中,这个方法就是通过索引获取指定位置的属性名信息

ajax

//->创建一个AJAX对象
var xhr=new XMLHttpRequest();
//->打开请求的URL,配置一些基本的参数信息
xhr.open('get','',false);//false同步,true异步(默认)
//->监听AJAX状态的改变,在不同的状态中做不同的事情
xhr.onreadystatechange=function(){
if(xhr.readyState===4 && /^2\d{2}$/.test(xhr.status)){
var data=xhr.responseText;
}
};
//->向服务器发送请求
xhr.send(null);

事件冒泡的典型案例 --- 事件委托

事件委托:如果一个容器下的很多元素,都要发生某个行为,我们可以把这个行为委托他们共同的父级来做,然后通过事件源来做不同的区分; 事件触发的顺序:先捕获(从外向里),再冒泡(从里向外)

  e = e || window.event; 
  e.target : e.srcElement 事件源 => 真正触发事件的元素
  e.stopPropagation : e.cancelBubble = true; 阻止事件传播
  e.preventDefault : e.returnValue = false; 阻止默认行为

前端模块化开发的理解

  • 主要考察的是你对OPO(面向对象编程)的理解,即类的封装、继承、多态。
  • 所谓模块化开发就是封装细节,提供接口使用,每个模块都是实现某一特定的功能,最基础的就是函数。
  • es6 一个模块通过export声明来导出多个,然后在需要用的地方使用import导入。