js 面试的坑

JavaScript事件属性event.target

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            #main {
                width: 200px;
                height: 100px;
                background: red;
            }
        </style>
        <script type="text/javascript">
            window.onload = function() {
                document.getElementById("main").onclick = function(e) {
                    console.log(e.target);
                    console.log(e.target.id);
                    console.log(e.target.tagName);
                    console.log(e.target.nodeName);
                    console.log(e.target.classList);
                    console.log(e.target.className);
                    console.log(e.target.innerHTML);
                    console.log(e.target.innerText);
                }
            }
        </script>
    </head>

    <body>
        <div id="main" class="sb js node"><span>我爱JavaScript</span></div>
    </body>

</html>

 

jquery检查元素存在性

javascript检查元素存在性:

即使这个元素被删除了,也不担心javascript代码报错;

jquery检查元素存在性:

代码如下:

if(!document.getElementById("preview")) return false;

 

 

jquery $(“#preview”)获取的永远是对象,即使网页上没有此元素。

不能使用以下代码:

if($("#preview"){
//do something
}

因此要用jquery检查某个元素在网页上是否存在时,应该根据获取到元素的长度来判断。

代码如下:

if($("#preview").length>0){
//do something
}

 

判断页面滚动方向(上下)

 <!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            body{
                height:1000px;
            }
        </style>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    </head>

    <body>
        <script type="text/javascript">
            $(function() {
                function scroll(fn) {
                    var beforeScrollTop = document.body.scrollTop,
                        fn = fn || function() {};
                    window.addEventListener("scroll", function() {
                        var afterScrollTop = document.body.scrollTop,
                            delta = afterScrollTop - beforeScrollTop;
                        if(delta === 0) return false;
                        fn(delta > 0 ? "down" : "up");
                        beforeScrollTop = afterScrollTop;
                    }, false);
                }
                scroll(function(direction) {
                    if(direction == "down") {
                        console.log("向下滚");
                    } else {
                        console.log("向上滚");
                    }
                });
            });
        </script>
    </body>

</html>

深入理解javascript 回调指针

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script type="text/javascript">
            window.onload = function() {
                var i=0;
                function test() {
                    document.getElementById('main').innerHTML=i++;
                }
                setInterval(test, 1000);//注意此处是test,不是test();
            }
        </script>
    </head>

    <body>
        <p id="main"></p>
    </body>

</html>

去掉字符串中所有空格

这里写图片描述

1、  去掉字符串前后所有空格:
代码如下:
         function Trim(str)
         { 
             return str.replace(/(^\s*)|(\s*$)/g, ""); 
     }
    说明:
    如果使用jQuery直接使用$.trim(str)方法即可,str表示要去掉前后所有空格的字符串。

2、 去掉字符串中所有空格(包括中间空格,需要设置第2个参数为:g)
代码如下:
        function Trim(str,is_global)
        {
            var result;
            result = str.replace(/(^\s+)|(\s+$)/g,"");
            if(is_global.toLowerCase()=="g")
            {
                result = result.replace(/\s/g,"");
             }
            return result;
}

JS获取div距离浏览器窗口的高度(重要)

这里写图片描述 
这里写图片描述

制作图片懒加载:http://www.cnblogs.com/libin-1/p/5851872.html

http://www.cnblogs.com/vajoy/p/4263291.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <style type="text/css">
            * {
                padding: 0px;
                margin: 0px;
            }

            #main {
                height: 2000px;
                background: red;
            }

            #java {
                height: 300px;
                background: blue;
            }
            #js{
                height: 300px;
                background: green;
            }
            #haha{
                height: 300px;
                background: yellow;
            }
        </style>
        <script type="text/javascript">
            $(function() {
                console.log('$("#java").offset().top : '+$("#java").offset().top);
                $("#java").offset({
                    top: 200
                });
                console.log('document.getElementById("js").getBoundingClientRect().top : '+document.getElementById('js').getBoundingClientRect().top);
                console.log('document.getElementById("js").getBoundingClientRect().bottom : '+document.getElementById('js').getBoundingClientRect().bottom);
            })
        </script>
    </head>

    <body>
        <div id="main">

        </div>
        <div id="java">

        </div>
        <div id="js">

        </div>
        <div id="haha">

        </div>
    </body>

</html>

点击div外面该div消失

http://www.cnblogs.com/libin-1/p/5746167.html

自定义a标签悬浮title样式

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style>
            #tooltip {
                border: 1px solid red;
                background: #FF6;
                position: absolute;
                padding: 1px;
                color: #333;
                display: none;
            }
        </style>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    </head>

    <body>

        <div id="link">
            <p>
                <a href="#" class="tooltip" title="这是我的超链接提示1">提示1</a>
            </p>
            <p>
                <a href="#" class="tooltip" title="这是我的超链接提示2">提示2</a>
            </p>
            <p>
                <a href="#" title="这是我的超链接提示1">自带提示1</a>
            </p>
            <p>
                <a href="#" title="这是我的超链接提示2">自带提示2</a>
            </p>
        </div>
        <script type="text/javascript">
            $(function() {
                var x = 10;
                var y = 20;
                $("a.tooltip").mouseover(function(e) {
                    this.myTitle = this.title;
                    this.title = "";
                    var tooltip = "<div id='tooltip'>" + this.myTitle + "</div>"; //创建DIV元素
                    $("#link").append(tooltip); //追加到文档中
                    $("#tooltip").css({
                        "top": (e.pageY + y) + "px",
                        "left": (e.pageX + x) + "px"
                    }).show(); //设置X  Y坐标, 并且显示
                }).mouseout(function() {
                    this.title = this.myTitle;
                    $("#tooltip").remove(); //移除
                }).mousemove(function(e) {
                    $("#tooltip").css({
                        "top": (e.pageY + y) + "px",
                        "left": (e.pageX + x) + "px"
                    });
                })
            })
        </script>
    </body>

</html>

回调函数是什么鬼?

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            function test(a, b, c) {
                setInterval(function() {
                    b(a);
                }, c)
            }
            test(10, function(i) {
                console.log(i);
            }, 2000);
        </script>
    </head>

    <body>
    </body>

</html>

js如何实现继承

http://blog.csdn.net/james521314/article/details/8645815

JS原型链简单图解

http://www.cnblogs.com/libin-1/p/5820550.html

http://blog.csdn.net/libin_1/article/details/52366524

http://www.cnblogs.com/myqianlan/p/4421950.html

http://www.cnblogs.com/shuiyi/p/5343399.html

http://www.cnblogs.com/shuiyi/p/5305435.html

this,都快忘了你了

这里写图片描述 
参考:http://blog.csdn.net/libin_1/article/details/52337576 
http://www.cnblogs.com/libin-1/p/5814792.html 
http://www.cnblogs.com/beyond-succeed/p/5808290.html

 <!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>

        <script type="text/javascript">
            var name = "window1",
                lzh = {
                    name: "lzh",
                    sayName: function() {
                        function innerFunction() {
                            console.log(_this.name);
                        }
                        var _this=this;
                        innerFunction();
                        return function() {
                            console.log(_this.name);
                        }
                    }
                }
            lzh.sayName()();
        </script>
        <script type="text/javascript">
            var name1 = "window2",
                lzh1 = {
                    name: "lzh",
                    sayName: function() {
                        function innerFunction() {
                            console.log(this.name);
                        }
                        innerFunction();
                        return function() {
                            console.log(this.name);
                        }
                    }
                }
            lzh1.sayName()();
        </script>
    </head>

    <body>
    </body>

</html>

prototype,都快忘了你了

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function LIBIN(a, b) {
                this.a = a;
                this.b = b;
                this.fun = function() {
                    alert('真是日了dog了');
                    sb();
                }
                sb = function() {
                    alert("卧槽!");
                }
            }
            LIBIN.prototype = {
                dianzan: function() {
                    alert("点赞");
                },
                budianzan: function() {
                    alert("拒绝点赞");
                }
            }
            var libin = new LIBIN('小明', 18);
            libin.dianzan();
            alert(libin.a + ":" + libin.b);
            libin.fun();
        </script>
    </head>

    <body>

    </body>

</html>
<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function LIBIN(a, b) {
                this.a = a;
                this.b = b;
                this.fun = function() {
                    alert('真是日了dog了');
                    sb();
                }
                sb = function() {
                    alert("卧槽!");
                }
            };

            LIBIN.prototype = {
                sb:"是你",
                dianzan: function() {
                    alert("点赞");
                },
                budianzan: function() {
                    alert("拒绝点赞");
                }
            };
            LIBIN.prototype.x="zhangsan";
            LIBIN.prototype.saycao=function(){
                alert("卧槽");
            }
            var libin = new LIBIN('小明', 18);
            libin.dianzan();
            alert(libin.a + ":" + libin.b+":"+libin.x+":"+libin.sb);
            libin.fun();
            libin.saycao();
        </script>
    </head>

    <body>

    </body>

</html>

JavaScript和jQuery的类型判断

参考:http://www.cnblogs.com/likeFlyingFish/p/5840496.html

对于类型的判断,JavaScript用typeof来进行。

栗子:

复制代码
console.log(typeof null);            //object
console.log(typeof []);              //object
console.log(typeof {});              //object
console.log(typeof new Date());      //object
console.log(typeof new Object);      //object
console.log(typeof function(){});    //function
console.log(typeof alert);           //function
console.log(typeof 1);               //number
console.log(typeof "abc");           //string
console.log(typeof true);            //boolean
复制代码
可以看到,typeof并不能够准确的判断出每一种数据类型,比如null和数组等都是object类型。因此,JavaScript判断数据类型不推荐使用typeof。

那么要如何具体判断呢??看一下语法<( ̄3 ̄)> !

{}.toString.call(obj);
栗子:

复制代码
console.log({}.toString.call(null));            //[object Null]
console.log({}.toString.call([]));              //[object Array]
console.log({}.toString.call({}));              //[object Object]
console.log({}.toString.call(new Date()));      //[object Date]
console.log({}.toString.call(function(){}));    //[object Function]
console.log({}.toString.call(new Object));      //[object Object]
console.log({}.toString.call(alert));           //[object Function]
console.log({}.toString.call(1));               //[object Number]
console.log({}.toString.call('abc'));           //[object String]
console.log({}.toString.call(true));            //[object Boolean]
复制代码
哈哈,是不是一目了然呀!!

那如果你用的是jQuery,就不用这么麻烦喽,可以直接用工具方法$.type(),进行判断

栗子:

console.log($.type(null));                  //null
console.log($.type([]));                    //array
console.log($.type({}));                    //object
console.log($.type(1));                     //number
......不全写完了,结果和{}.toString.call(obj);是一样的
实际上{}.toString.call(obj);就是jQuery中$.type()这个工具方法的实现最重要的一段代码(⊙o⊙)哦,神奇吧!赶快去jQuery源码中找找看吧~~

如果哪里写的有问题,欢迎各路大神指正!

这里写图片描述

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            div {
                width: 200px;
                height: 200px;
                border: 3px solid red;
                padding: 17px;
                margin: 16px;
                color: blue;
            }
        </style>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script type="text/javascript">
            $(function() {
                console.log("width:" + $("div").width());
                console.log("width+padding:" + $("div").innerWidth());
                console.log("width+padding+border:" + $("div").outerWidth());
                console.log("width+padding+border+margin:" + $("div").outerWidth(true));
            })
        </script>
    </head>

    <body>
        <div>
            <p>width: 200px;</p>
            <p> height: 200px;</p>
            <p> border: 3px solid red;</p>
            <p> padding: 17px;</p>
            <p> margin: 16px;</p>
        </div>
    </body>

</html>

像素转为整数

这里写图片描述

禁止用户输入非数字

<input type="text" placeholder="只能输入数字" onkeyup="this.value = this.value.replace(/\D/,'')" > 

window.onload的jQuery写法

window.onload=function(){}           ===          或者$(window).load(function(){});

js判断终端是PC还是移动端

function IsPC()  { 
   var userAgentInfo = navigator.userAgent; 
   var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"); 
   var flag = true; 
   for (var v = 0; v < Agents.length; v++) { 
       if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; } 
   } 
   return flag;   }

最简单的排序

<script type="text/javascript">
            var a = [1, 18, 23, 9, 16, 10, 29, 17];
            var t = 0;
            for(var i = 0; i < a.length; i++) {
                for(var j = i + 1; j < a.length; j++) {
                    if(a[i] > a[j]) {
                        t = a[i];
                        a[i] = a[j];
                        a[j] = t;
                    }
                }
            }
            console.log(a);  //[1, 9, 10, 16, 17, 18, 23, 29]
        </script>

判断终端类型跳转

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script type="text/javascript">
            if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {  
                window.location.href = "http://www.baidu.com";
            } else {
                window.location.href = "https://wx.qq.com/";
            }
        </script>

    </head>

    <body>

    </body>

</html>

深入理解JavaScript中 fn() 和 return fn() 的区别

js中,经常会遇到在函数里调用其它函数的情况,这时候会有 fn() 这种调用方式,还有一种是 return fn() 这种调用方式,一些初学者经常会一脸萌逼地被这两种方式给绕晕了。这里用一个优雅的面试题来分析一下两种方式的不同之处。

var i = 0;
function fn(){
    i++;
    if(i < 10){
        fn();
    }else{
        return i;
    }
}

var result = fn();
console.log(result);

这是一道隐藏了坑的面试题,看似很简单,大部分人可能想都不想就答出了10。而实际上运行可知打印出来的是 undefined。这道陷阱题很直观的体现出了前面所说的问题,当我们将执行fn的那一行修改为:

var i = 0;
function fn(){
    i++;
    if(i < 10){
        return fn();
    }else{
        return i;
    }
}

var result = fn();
console.log(result);

这时,会发现打印出来的结果终于不负众望的是 10 了。

为什么这里加不加return区别会这么大?

这里的主要原因很简单,JavaScript的函数都是有默认返回值的,如果函数结尾不写return,会默认返回undefined,这就是为什么在chrome的console控制台里,写代码经常下面会出现一行undefined的原因。

再仔细看看这个例子,当i自增到9的时候,也就是倒数第二次递归调用fn的那一次,如果没有return,这一次执行完fn,会默认return undefined,而不会继续下一次递归了。当加上了 return,在这里则会继续最后一次递归,即i=10的时候,跳入else里面返回得到正确的10。

说到这里,可以引申出一个更为经典的例子,著名的二分查

var midMath.floor((arr.length - 1) / 2);

function search(n, mid) {
 if (n > arr[mid]) {
  mid = Math.floor((mid + arr.length) / 2);
  return search(n, mid);
 } else if (n < arr[mid]) {
  mid = Math.floor((mid - 1) / 2);
  return search(n, mid);
 } else {
  return mid;
 }
}

var index = search(n, mid);
console.log(index);

也是需要多次递归调用,很多新手在第一次实现这个算法的时候经常会犯的一个错误就是忘记在递归的函数前加上return,最后导致返回结果是undefined,这里的道理也和前面是类似的,不加return,会导致递归后,直接返回undefined,不会继续下一次递归。

localStorage使用很简单

这里写图片描述 
这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script type="text/javascript">
            window.onload = function() {

                window.localStorage.clear(); //清除所有的变量和值
                window.localStorage.a = 100;
                window.localStorage["b"] = 200;
                window.localStorage.setItem("c", 300);;

                console.log("window.localStorage.a=" + window.localStorage.a);
                console.log("window.localStorage['b']=" + window.localStorage["b"]);
                console.log("window.localStorage.getItem('c')=" + window.localStorage.getItem("c"));

                console.log(window.localStorage);
                console.log(typeof window.localStorage);
                for (var i = 0; i < window.localStorage.length; i++) {
                    var key1 = window.localStorage.key(i);
                    var key2 = window.localStorage.getItem(key1);
                    console.log("字段名:" + key1 + "       值:" + key2);
                }

                console.log(typeof window.localStorage.a);
                console.log(typeof window.localStorage['b']);
                console.log(typeof window.localStorage.getItem('c'));


                console.log("空了:" + window.localStorage);
                window.localStorage.SB = "我是你大爷!";
                window.localStorage.aaa = "this is test!";
                window.localStorage.removeItem("aaa");

                console.log("-------------------------------------------------");
                var storage = window.localStorage;
                var data = {
                    name: 'xiecanyong',
                    sex: 'man',
                    hobby: 'program'
                };
                var d = JSON.stringify(data);
                console.log(typeof d);
                storage.setItem("data", d);
                console.log(storage.data);

                var json = storage.getItem("data");
                var jsonObj = JSON.parse(json);
                console.log(typeof jsonObj);
                console.log(storage.data);

            }
        </script>
    </head>

    <body>

    </body>

</html>

注意

这里写图片描述

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <script type="text/javascript">
            "use strict";
            var B = {
                "name": "SBSBSBS",
                "age": "32",
                say: function() {
                    console.log("不加this可能会报错:"+this.name+":"+this.age);
                }
            }
            B.say();
            var name="我是你大爷";
            function USR(name) {
                this.name = name;
                this.say = function() {
                    console.log("window下的: " + window.name);
                    console.log("USR 里面的:" + this.name);
                }
            };
            var a = new USR("我是谁?");
            a.say();

        </script>
        <style type="text/css">
            * {
                margin: 0px;
                padding: 0px;
            }

            div {
                width: 50%;
                height: 200px;
            }

            .demo {
                float: left;
                background: red;
            }

            .main {
                float: right;
                background: green;
            }
        </style>
    </head>
    <div class="demo">

    </div>
    <div class="main">

    </div>

    <body>
    </body>

</html>

深入理解变量提升和函数提升

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>

        <script type="text/javascript">
            console.log(x());
            console.log(x);
            var x = 10;
            console.log(x);
            x = 20;

            function x() {
                var a = new Array();
            }
            console.log(x);
            if (true) {
                var a = 1;

            } else {
                var b = true;

            }
            console.log(a);
            console.log(b);
        </script>
    </head>

    <body>

    </body>

</html>

constructor 和 instanceof

这里写图片描述

instanceof 用于判断一个变量是否某个对象的实例,或用于判断一个变量是否某个对象的实例;
constructor 用于判断一个变量的原型,constructor 属性返回对创建此对象的数组函数的引用。
Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。
<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            console.log("----------------Number---------------");
            var A = 123;
            console.log(A instanceof Number); //false
            console.log(A.constructor == Number); //true
            console.log(A.constructor);
            console.log("----------------String---------------");
            var B = "javascript";
            console.log(B instanceof String); //false
            console.log(B.constructor == String); //true
            console.log(B.constructor);
            console.log("----------------Boolean---------------");
            var C = true;
            console.log(C instanceof Boolean); //false
            console.log(C.constructor == Boolean); //true
            console.log(C.constructor);
            console.log("----------------null---------------");
            var D = null;
            console.log(D instanceof Object); //false
            //console.log(D.constructor == null); //报错
            //console.log(D.constructor); //报错
            console.log("----------------undefined---------------");
            var E = undefined;
            //console.log(E instanceof undefined); // //报错
            //console.log(E.constructor == undefined); //报错
            //console.log(E.constructor); //报错
            console.log("----------------function---------------");
            var F = function() {};
            console.log(F instanceof Function);
            console.log(F.constructor == Function);
            console.log(F.constructor);
            console.log("----------------new function---------------");
            function SB() {};
            var G = new SB();
            console.log(G instanceof SB);
            console.log(G.constructor == SB);
            console.log(G.constructor);
            console.log("----------------new Object---------------");
            var H = new Object;
            console.log(H instanceof Object);
            console.log(H.constructor == Object);
            console.log(H.constructor);
            console.log("-----------------Array--------------");
            var I = [];
            console.log(I instanceof Array);
            console.log(I.constructor == Array);
            console.log(I.constructor);
            console.log("-----------------JSON--------------");
            var J = {
                "sb": "javascript",
                "node": "very SB"
            };
            console.log(J instanceof Object);
            console.log(J.constructor == Object);
            console.log(J.constructor);
        </script>
    </head>

    <body>

    </body>

</html>
<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            var A = new Array();
            var B = new Boolean();
            console.log(A instanceof Array); // true
            console.log(A instanceof Boolean); // false
            console.log(B.constructor == Array); // false
            console.log(B.constructor == Boolean); // true
        </script>
    </head>

    <body>

    </body>

</html>
<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            function sb(name, age) {
                this.name = name;
                this.age = age;
                this.sbs = function() {
                    console.log(this.name + "," + this.age);
                }
            }
            var A = new Array();
            var B = new Boolean();
            var C=new sb("libin",28);
            document.writeln(A.constructor + "<br />");  //function Array() { [native code] }
            document.writeln(B.constructor + "<br />");  //function Boolean() { [native code] }
            document.writeln(C.constructor + "<br />");  //function sb(name, age) { this.name = name; this.age = age; this.sbs = function() { console.log(this.name + "," + this.age); } }
            C.name="李斌";
            C.sbs();   //李斌,28
        </script>
    </head>

    <body>

    </body>

</html>

注意

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            function aaa(){
                alert(a);    //报错:a is not defined
            }
            function bbb(){
                var a=10;
                aaa();
            }
            bbb();
        </script>
    </head>
    <body>
    </body>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            var a=100;
            function aaa(){
                alert(a);    //100
            }
            function bbb(){
                var a=10;
                aaa();
            }
            bbb();
        </script>
    </head>
    <body>
    </body>
</html>

数组去重

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script type="text/javascript">
            var a = [1, 2, 5, 5, 7, 9];
            Array.prototype.unique = function() {
                var b = [];
                for (var i = 0; i < this.length; i++) {
                    if (b.indexOf(this[i]) == -1) {
                        b.push(this[i]);
                    }
                }
                return b;
            }
            document.writeln(a.unique());
        </script>
    </head>

    <body>

    </body>

</html>

可恶的forEach

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>

        <script type="text/javascript">
            var a = ["a", "b", "c", "d", "e"];
            a.forEach(function(i, j) {   //注意参数i,j对应关系相反
                console.log(i + ":" + j);  //妈的个巴子,j居然是索引
            })
        </script>
    </head>

    <body>

    </body>

</html>

call 和 apply 是为了动态改变 this 而出现的

这里写图片描述

<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script type="text/javascript">
//apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
//apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
//apply 、 call 、bind 三者都可以利用后续参数传参;
//bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。
            var xw = {
                name: "小王",
                gender: "男",
                age: 24,
                say: function(school, grade) {
                    console.log(this.name + " , " + this.gender + " ,今年" + this.age + " ,在" + school + "上" + grade);
                }
            }
            var xh = {
                name: "小红",
                gender: "女",
                age: 18
            }
            xw.say("清华大学","本科");
            xw.say.call(xh,"北京大学","研究僧");  //call后面的参数与say方法中是一一对应的
            xw.say.apply(xh,["新东方","电气焊"]);  //而apply的第二个参数是一个数组,数组中的元素是和say方法中一一对应的
            xw.say.bind(xh)("蓝翔技校","挖掘机");  //bind返回的仍然是一个函数,所以我们还可以在调用的时候再进行传参
        </script>
    </head>

    <body>

    </body>

</html>

js计算div 宽高等(面试常问)

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">
            * {
                padding: 0px;
                margin: 0px;
            }



            #main {
                width: 200px;
                height: 300px;
                padding: 3px;
                margin: 7px;
                background: green;
                border: 5px solid red;
                position: absolute;
                top: 100px;
                left: 200px;
            }
            span{
                color: red;
            }
        </style>
        <script type="text/javascript">
            function G(a) {
                return document.getElementById(a);
            }
            window.onload = function() {
                document.onmousemove = function(e) {
                    document.getElementsByTagName('span')[0].innerText = e.clientX + "," + e.clientY;
                };
                G("main").onmousemove = function(e) {
                    document.getElementsByTagName('span')[1].innerText = e.offsetX + "," + e.offsetY;
                }
                console.log("屏幕宽高:" + window.screen.width+","+window.screen.height);
                console.log("body宽高:" +document.body.clientWidth +","+ document.body.clientHeight);
                console.log("offsetWidth包含width,padding,border:" + G('main').offsetWidth);
                console.log("offsetHeight包含height,padding,border:" + G('main').offsetHeight);
                console.log("offsetTop包含top,margin:" + G('main').offsetTop);
                console.log("offsetLeft包含left,margin:" + G('main').offsetLeft);
            }
        </script>

    </head>

    <body>
        <div id="main">

        </div>
        <p>相对窗口的座标:e.clientX,e.clientY:(<span>0,0</span>)</p>
        <p>相对容器的坐标:e.offsetX,e.offsetY:(<span>0,0</span>)</p>
    </body>

</html>

回到顶部回到底部

$("#dwn").click(function() {
                $('html,body').animate({
                    scrollTop: $(document).height()
                }, 600)
            });
$(".logo2").click(function() {
                $('html,body').animate({
                    scrollTop: 0
                }, 600)
            });

js数据类型判断和数组判断

var a = [];
console.log(a instanceof Array) //返回true
var b = {};
console.log(b instanceof Object) //返回true
这么基础的东西实在不应该再记录了,不过嘛,温故知新~就先从数据类型开始吧



js六大数据类型:number、string、object、Boolean、null、undefined

string: 由单引号或双引号来说明,如"string"

number:什么整数啊浮点数啊都叫数字,你懂的~

Boolean: 就是true和false啦

undefined:未定义,就是你创建一个变量后却没给它赋值~

null: 故名思久,null就是没有,什么也不表示

object: 这个我也很难解释的说。就是除了上面五种之外的类型



--------------------上面的都是浮云,下面的才是神马------------------------------

数据类型判断之 typeof

typeof可以解决大部分的数据类型判断,是一个一元运算,放在一个运算值之前,其返回值为一个字符串,该字符串说明运算数的类型,所以判断某个是否为String类型,可以直接 if(typeof(你的值) == "string"){}

以下是各种数据类型返回结果:

复制代码
var a="string"; console.log(a); //string
var a=1; console.log(a); //number
var a=false; console.log(a); //boolean
var a; console.log(typeof a); //undfined

var a = null; console.log(typeof a); //object
var a = document; console.log(typeof a); //object
var a = []; console.log(a); //object

var a = function(){}; console.log(typeof a) //function   除了可以判断数据类型还可以判断function类型
复制代码
这样一来就很明显了,除了前四个类型外,null、对象、数组返回的都是object类型;

对于函数类型返回的则是function,再比如typeof(Date),typeof(eval)等。

然后这里就可以再引申出另一个灰常热门并且解决方法已普遍存在的问题,如何判断数据是个数组类型?

---------------------------------------其实这才是我的目的,咩~----------------------------------------------

js判断数组类型的方法

 方法一之 instanceof

instance,故名思义,实例,例子,所以instanceof 用于判断一个变量是否某个对象的实例,是一个三目运算式---和typeof最实质上的区别

a instanceof b?alert("true"):alert("false")  //注意b值是你想要判断的那种数据类型,不是一个字符串,比如Array

举个栗子:

var a=[];
console.log(a instanceof Array) //返回true 
方法二之 constructor

在W3C定义中的定义:constructor 属性返回对创建此对象的数组函数的引用

就是返回对象相对应的构造函数。从定义上来说跟instanceof不太一致,但效果都是一样的

如: (a instanceof Array)   //a是否Array的实例?true or false

   (a.constructor == Array)  // a实例所对应的构造函数是否为Array? true or false

举个栗子:

复制代码
function employee(name,job,born){
    this.name=name;
    this.job=job;
    this.born=born;
}

var bill=new employee("Bill Gates","Engineer",1985);
console.log(bill.constructor); //输出function employee(name, jobtitle, born){this.name = name; this.jobtitle = job; this.born = born;}
复制代码
那么判断各种类型的方法就是:

console.log([].constructor == Array);
console.log({}.constructor == Object);
console.log("string".constructor == String);
console.log((123).constructor == Number);
console.log(true.constructor == Boolean);


-------------------------------------以下不是原创--------------------------------------

较为严谨并且通用的方法:

function isArray(object){
    return object && typeof object==='object' &&
            Array == object.constructor;
}
!!注意:

使用instaceof和construcor,被判断的array必须是在当前页面声明的!比如,一个页面(父页面)有一个框架,框架中引用了一个页面(子页面),在子页面中声明了一个array,并将其赋值给父页面的一个变量,这时判断该变量,Array == object.constructor;会返回false;
原因:
1、array属于引用型数据,在传递过程中,仅仅是引用地址的传递。
2、每个页面的Array原生对象所引用的地址是不一样的,在子页面声明的array,所对应的构造函数,是子页面的Array对象;父页面来进行判断,使用的Array并不等于子页面的Array;切记,不然很难跟踪问题!

方法三之 特性判断法

以上方法均有一定的缺陷,但要相信人民大众的智慧是无所不能及的,我们可根据数组的一些特性来判断其类型 

复制代码
function isArray(object){
    return  object && typeof object==='object' &&    
            typeof object.length==='number' &&  
            typeof object.splice==='function' &&    
             //判断length属性是否是可枚举的 对于数组 将得到false  
            !(object.propertyIsEnumerable('length'));
}
复制代码
有length和splice并不一定是数组,因为可以为对象添加属性,而不能枚举length属性,才是最重要的判断因子。

ps: 在这里普及下 propertyIsEnumerable 方法:

object. propertyIsEnumerable(proName)
判断指定的属性是否可列举

备注:如果 proName 存在于 object 中且可以使用一个 For…In 循环穷举出来,那么 propertyIsEnumerable 属性返回 true。如果 object 不具有所指定的属性或者所指定的属性不是可列举的,那么 propertyIsEnumerable 属性返回 false。

propertyIsEnumerable 属性不考虑原型链中的对象。

示例:

var a = new Array("apple", "banana", "cactus");
document.write(a.propertyIsEnumerable(1));
方法四之 最简单的方法

 对于这种方法,以下有几个链接可供参考解释:

http://blog.csdn.net/zhangw428/article/details/4171630

http://my.oschina.net/sfm/blog/33197

http://openxtiger.iteye.com/blog/1893378

function isArray(o) {
    return Object.prototype.toString.call(o) === ‘[object Array]‘;
}


当然,你知道啦,这篇东西不完全是出自我手的啦,

全局和局部变量

这里写图片描述

这里写代码片
<!DOCTYPE HTML>
<html>

    <head>
        <script type="text/javascript">
        //只要函数里不管什么时候只要定义var ,变量就是局部变量
            var a = 100;
            function test() {
                console.log("a=" + a);     //100
                a = 10;
                console.log("a=" + a);     //10
            }
            test();
            console.log("a=" + a);         //10
            console.log("---------------------------------------");
            var b = 100;
            function test1() {
                console.log("b=" + b);     //undefined
                var b = 10;
                console.log("b=" + b);     //10
            }
            test1();
            console.log("b=" + b);         //100
            console.log("---------------------------------------");
            var c = 10;
            function test2() {
                c = 100;
                console.log("c=" + c);    //100
                console.log("this.c=" + this.c);    //10
                var c;   //c 就是局部变量
                console.log("c=" + c);    //100
            }
            test2();
            console.log("c=" + c);   //10
        </script>
    </head>

    <body>
        <div id="sse">

        </div>
    </body>

</html>

反转字符串

<script type="text/javascript">
    var a = "hello"   
    document.writeln(a.split("").reverse().join(""));   //olleh
</script>

js倒计时

 <!Doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>下班倒计时</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }

            body {
                font-size: 16px;
                text-align: center;
                font-family: arial;
            }

            .time {
                margin-top: 10px;
                border: 1px solid red;
                height: 30px;
                padding: 2px;
                line-height: 30px;
            }
        </style>
    </head>

    <body>
        <div class="time">
            <span id="t_d">00天</span>
            <span id="t_h">00时</span>
            <span id="t_m">00分</span>
            <span id="t_s">00秒</span>
        </div>
        <script>
            setInterval(function() {
                var EndTime = new Date('2016/06/13 00:00:00');
                var NowTime = new Date();
                var t = EndTime.getTime() - NowTime.getTime();
                var d = 0;
                var h = 0;
                var m = 0;
                var s = 0;
                if (t >= 0) {
                    d = Math.floor(t / 1000 / 60 / 60 / 24);
                    h = Math.floor(t / 1000 / 60 / 60 % 24);
                    m = Math.floor(t / 1000 / 60 % 60);
                    s = Math.floor(t / 1000 % 60);
                }
                document.getElementById("t_d").innerHTML = d + "天";
                document.getElementById("t_h").innerHTML = h + "时";
                document.getElementById("t_m").innerHTML = m + "分";
                document.getElementById("t_s").innerHTML = s + "秒";
            }, 10);
        </script>

    </body>

</html>

检测PC端和移动端的方法总结

 <!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
        <title>Document</title>

        <script type="text/javascript">
            $(function() {
                if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {  
                    console.log(1);
                }
            })
        </script>
    </head>

    <body>
        <div></div>
    </body>

</html>

## 其他办法: ##

正在苦逼的实习中,昨天公司让做一个页面,涉及到检测终端的问题,如果是手机设备,就跳转到指定的网页上,以前写响应式布局的时候都是用的同一套代码,然后通过css的@media screen来实现布局的差异化适应,but现在情景不一样了,所以看了点资料,做个总结

方法一、还是用@media screen
思路:css使用媒体查询,当屏幕小于760px时,使某个元素的样式发生改变,然后通过js检测到这个改变,就可以知道现在切换到移动端了

css代码:

1
2
3
4
/* 检测小屏幕- */
@media only screen and (max-width: 760px) {
  #some-element { display: none; }
}
 js代码:

1
2
3
4
5
6
7
8
9
$( document ).ready(function() {     
  var isMobile = false;//默认是pc端
  if( $('#some-element').css('display')=='none') {
    is_mobile = true;      
  }
  if (isMobile == true) {
    //对移动端进行处理
  }
});
方法二、通过navigator.userAgent字符串检测
思路:Navigator对象包含有关浏览器的信息,通过检测userAgent字符串,然后使用正则表达式进行匹配,我们自然就能知道用户是否在使用移动端的浏览器啦

先上个简化版的,意思意思下

1
2
3
4
5
6
7
8
var isMobile = false;
// 检测userAgent
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
  isMobile = true;
}
if(isMobile){
  //移动端的处理逻辑
}
 其实还可以用jQuery,but jQuery 从 1.9 版开始,移除了 $.browser 和 $.browser.version:

1
$.browser.device = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
通过上面那段代码基本就能检测到我们能常用的移动终端了,但是后来我在stackoverflow发现一哥们检测得更加全面牛逼:

1
2
3
4
5
6
7
8
var isMobile = false;//默认PC端
// 检测userAgent
if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
    || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4)))
{
  isMobile = true;
}
if(isMobile){<br>  //移动端的处理逻辑<br>}
方法三、通过Window.matchMedia()检测
思路:Window.matchMedia()用来检查mediaquery语句,扔个MDN的传送门。它返回一个MediaQueryList对象。该对象有两个属性
media:查询语句的内容。
matches:如果查询结果为真,值为true,否则为false

代码实现如下:

1
2
3
4
5
var isMobile = false;//默认PC端
var result = window.matchMedia("<code>only screen and</code> (max-width: 760px)");
if (result.matches){
  isMobile = true;
}
如果在PC端上使用Window.matchMedia()的话IE10以下是不支持的,但是我们只是用来检测终端哈,IE不支持就算了,移动端上安卓3.0以上都没有问题,so~~

方法四、检测移动端的TouchEvent事件
思路:使用document.createEvent()创建TouchEvent事件,如果成功那就是移动端了,返回true,pc端是没有TouchEvent事件的,所以会出错,返回false

代码实现:

1
2
3
4
5
6
7
8
9
10
11
var isMobile = false;//默认PC端
function mobile() {
    try{
        document.createEvent("TouchEvent");
        return true;
    }
    catch(e){
        return false;
    }
}
isMobile=mobile();
 简洁方便~~

方法五、使用Device.js库
这个库就没啥好讲的了,自己跟着套代码就OK

arguments是对象,不是数组

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="utf-8" />
        <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
        <title>document</title>

        <script type="text/javascript">
            function fun1() {
                //              if (arguments.length == 0) {
                //                  return 0;
                //              };
                //              if (arguments.length == 1) {
                //                  return arguments[0];
                //              };
                //              if (arguments.length == 2) {
                //                  return arguments[0] + arguments[1];
                //              }
                console.log(typeof arguments);
                console.log(arguments);
                switch (arguments.length) {
                    case 0:
                        return 0;
                        break;
                    case 1:
                        return arguments[0];
                        break;
                    case 2:
                        return arguments[0] + arguments[1];
                        break;
                    default:
                        break;
                }
            }
            console.log(fun1());
            console.log(fun1(275));
            console.log(fun1(275,25));
        </script>

    </head>

    <body>

    </body>

</html>

JavaScript 函数重载

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="utf-8" />
        <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
        <title>document</title>

        <script type="text/javascript">
            function fun1() {
                //              if (arguments.length == 0) {
                //                  return 0;
                //              };
                //              if (arguments.length == 1) {
                //                  return arguments[0];
                //              };
                //              if (arguments.length == 2) {
                //                  return arguments[0] + arguments[1];
                //              }
                switch (arguments.length) {
                    case 0:
                        return 0;   //arguments是对象,不是数组
                        break;
                    case 1:
                        return arguments[0];
                        break;
                    case 2:
                        return arguments[0] + arguments[1];
                        break;
                    default:
                        break;
                }
            }
            console.log(fun1());
            console.log(fun1(275));
            console.log(fun1(275,25));
        </script>

    </head>

    <body>

    </body>

</html>

apply、call 是什么?

在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
先来一个栗子:
1
2
3
4
5
6
7
8
9
10
11
function fruits() {}

fruits.prototype = {
    color: "red",
    say: function() {
        console.log("My color is " + this.color);
    }
}

var apple = new fruits;
apple.say();    //My color is red
 但是如果我们有一个对象banana= {color : "yellow"} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:

1
2
3
4
5
banana = {
    color: "yellow"
}
apple.say.call(banana);     //My color is yellow
apple.say.apply(banana);    //My color is yellow
所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(本栗子中apple有say方法),我们可以借助call或apply用其它对象的方法来操作。



   apply、call 的区别

 对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:

1
2
3
var func = function(arg1, arg2) {

};
就可以通过如下方式来调用:

1
2
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。  

JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call 。
而不确定的时候用 apply,然后把参数 push 进数组传递进去。当参数数量不确定时,函数内部也可以通过 arguments 这个数组来遍历所有的参数。

为了巩固加深记忆,下面列举一些常用用法:
1、数组之间追加
1
2
3
4
var array1 = [12 , "foo" , {name "Joe"} , -2458]; 
var array2 = ["Doe" , 555 , 100]; 
Array.prototype.push.apply(array1, array2); 
/* array1 值为  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
2、获取数组中的最大值和最小值

1
2
3
var  numbers = [5, 458 , 120 , -215 ]; 
var maxInNumbers = Math.max.apply(Math, numbers),   //458
    maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458
number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法。

3、验证是否是数组(前提是toString()方法没有被重写过)

1
2
3
functionisArray(obj){ 
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}
4、类(伪)数组使用数组方法

1
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
Javascript中存在一种名为伪数组的对象结构。比较特别的是 arguments 对象,还有像调用 getElementsByTagName , document.childNodes 之类的,它们返回NodeList对象都属于伪数组。不能应用 Array下的 push , pop 等方法。
但是我们能通过 Array.prototype.slice.call 转换为真正的数组的带有 length 属性的对象,这样 domNodes 就可以应用 Array 下的所有方法了。


   深入理解运用apply、call

下面就借用一道面试题,来更深入的去理解下 apply 和 call 。

定义一个 log 方法,让它可以代理 console.log 方法,常见的解决方法是:

1
2
3
4
5
function log(msg) {
  console.log(msg);
}
log(1);    //1
log(1,2);    //1
上面方法可以解决最基本的需求,但是当传入参数的个数是不确定的时候,上面的方法就失效了,这个时候就可以考虑使用 apply 或者 call,注意这里传入多少个参数是不确定的,所以使用apply是最好的,方法如下:

1
2
3
4
5
function log(){
  console.log.apply(console, arguments);
};
log(1);    //1
log(1,2);    //1 2
接下来的要求是给每一个 log 消息添加一个"(app)"的前辍,比如:

1
log("hello world");    //(app)hello world
该怎么做比较优雅呢?这个时候需要想到arguments参数是个伪数组,通过 Array.prototype.slice.call 转化为标准数组,再使用数组方法unshift,像这样:

1
2
3
4
5
6
function log(){
  var args = Array.prototype.slice.call(arguments);
  args.unshift('(app)');

  console.log.apply(console, args);
};


   bind

说完了 apply 和 call ,再来说说bind。bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。

MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑 定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时 本身的参数按照顺序作为原函数的参数来调用原函数。

直接来看看具体如何使用,在常见的单体模式中,通常我们会使用 _this , that , self 等保存 this ,这样我们可以在改变了上下文之后继续引用到它。 像这样:

1
2
3
4
5
6
7
8
9
10
var foo = {
    bar : 1,
    eventBind: function(){
        var _this = this;
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(_this.bar);     //1
        });
    }
}
由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $('.someClass').on('click',function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:

1
2
3
4
5
6
7
8
9
var foo = {
    bar : 1,
    eventBind: function(){
        $('.someClass').on('click',function(event) {
            /* Act on the event */
            console.log(this.bar);      //1
        }.bind(this));
    }
}
在上述代码里,bind() 创建了一个函数,当这个click事件绑定在被调用的时候,它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的参数)。因此,这里我们传入想要的上下文 this(其实就是 foo ),到 bind() 函数中。然后,当回调函数被执行的时候, this 便指向 foo 对象。再来一个简单的栗子:

1
2
3
4
5
6
7
8
9
var bar = function(){
console.log(this.x);
}
var foo = {
x:3
}
bar(); // undefined
var func = bar.bind(foo);
func(); // 3
这里我们创建了一个新的函数 func,当使用 bind() 创建一个绑定函数之后,它被执行的时候,它的 this 会被设置成 foo , 而不是像我们调用 bar() 时的全局作用域。

有个有趣的问题,如果连续 bind() 两次,亦或者是连续 bind() 三次那么输出的值是什么呢?像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var bar = function(){
    console.log(this.x);
}
var foo = {
    x:3
}
var sed = {
    x:4
}
var func = bar.bind(foo).bind(sed);
func(); //?

var fiv = {
    x:5
}
var func = bar.bind(foo).bind(sed).bind(fiv);
func(); //?
答案是,两次都仍将输出 3 ,而非期待中的 4 和 5 。原因是,在Javascript中,多次 bind() 是无效的。更深层次的原因, bind() 的实现,相当于使用函数在内部包了一个 call / apply ,第二次 bind() 相当于再包住第一次 bind() ,故第二次以后的 bind 是无法生效的。

  

   apply、call、bind比较

那么 apply、call、bind 三者相比较,之间又有什么异同呢?何时使用 apply、call,何时使用 bind 呢。简单的一个栗子:

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {
    x: 81,
};

var foo = {
    getX: function() {
        return this.x;
    }
}

console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81
三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。

也就是说,区别是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法。而 apply/call 则会立即执行函数。



再总结一下:

apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
apply 、 call 、bind 三者都可以利用后续参数传参;
bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。

href=”#”与href=”javascript:void(0)”的区别

"#"包含了一个位置信息
默认的锚点是#top 也就是网页的上端
而javascript:void(0) 仅仅表示一个死链接
这就是为什么有的时候页面很长浏览链接明明是#可是跳动到了页首
而javascript:void(0) 则不是如此
所以调用脚本的时候最好用void(0)

全选,全不选,反选

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <title>全选,不全选,反选</title>
        <meta charset="UTF-8" />
        <script type="text/javascript" src="js/jquery-2.2.4.min.js"></script>
        <script language="javascript" type="text/javascript">
            $(function() {
                $("#selectAll").click(function() { //全选  
                    $(":checkbox").prop("checked", true);
                });
                $("#unSelect").click(function() { //全不选  
                    $(":checkbox").prop("checked", false);
                });
                $("#reverse").click(function() { //反选  
                    $(":checkbox").each(function() {
                        $(this).prop("checked", !$(this).prop("checked"));
                    });
                });
            });
        </script>
    </head>

    <body>
        <div id="playList">
            <input type="checkbox" value="歌曲1" />歌曲1<br />
            <input type="checkbox" value="歌曲2" />歌曲2<br />
            <input type="checkbox" value="歌曲3" />歌曲3<br />
            <input type="checkbox" value="歌曲4" />歌曲4<br />
            <input type="checkbox" value="歌曲5" />歌曲5<br />
            <input type="checkbox" value="歌曲6" />歌曲6
        </div>
        <input type="button" value="全选" id="selectAll" />
        <input type="button" value="全不选" id="unSelect" />
        <input type="button" value="反选" id="reverse" />
    </body>

</html>

三种匿名自执行写法

如果你发现有些人写函数这样搞,不要惊慌,也不要觉得他高大上鸟不起

+function(ROOT, Struct, undefined) {
    ... 
}(window, function() {
    function Person() {}
})
()(), !function() {}() +function() {}() 三种函数自执行的方式^_^

jquery 一个容易问的考点

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <script type="text/javascript" src="js/jquery-2.2.4.min.js"></script>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">

        </style>
        <script type="text/javascript">
            $(function() {
                $("#id0>li:not(:has(ul))").css('border', '1px solid red');
            })
        </script>
    </head>

    <body>
        <ul id="id0">
            <li>list item 1</li>
            <li>list item 2
                <ul>
                    <li>list item 2-a</li>
                    <li>list item 2-b</li>
                </ul>
            </li>
            <li>list item 3</li>
            <li>list item 4</li>
        </ul>
    </body>

</html>

jquery position()和offset()

这里写图片描述

 <!doctype html>
<html lang="en">

    <head>
        <script type="text/javascript" src="js/jquery-2.2.4.min.js"></script>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">
            html {
                padding: 0px;
                margin: 0px;
            }

            body {
                margin: 3px;
                padding: 6px;
            }

            div#main_1 {
                width: 200px;
                height: 200px;
                background: red;
                position: relative;
            }

            div#main_2 {
                width: 50px;
                height: 50px;
                background: green;
                position: absolute;
                left: 30px;
                top: 10px;
            }
        </style>
        <script type="text/javascript">
            $(function() {
                console.log($("#main_2").position().left); //获取匹配元素相对父元素的偏移。
                console.log($("#main_2").position().top);
                console.log($("#main_2").offset().left);  //获取匹配元素在当前视口的相对偏移。
                console.log($("#main_2").offset().top);
                console.log($("#main_2").css('left'));
                console.log($("#main_2").css('top'));
            })
        </script>
    </head>

    <body>
        <div id="main_1">
            <div id="main_2">

            </div>
        </div>
    </body>

</html>

js 实现继承

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title></title>
        <script type="text/javascript">
            function Base(name, base) {
                this.name = name;
                this.base = base;
                this.sayHello = function() {
                    alert('Hello ' + this.name);
                };
            }

            function Ase(name, base) {
                this.stu = Base;     //重要
                this.stu(name, base);    //重要
                this.sayHelloTo = function() {
                    alert('Hello ' + this.name+this.base*2);
                };
            }
            var a = new Base('李四',28);
            var b = new Ase('张三',55);
            a.sayHello();

            b.sayHello();
            b.sayHelloTo();
        </script>
    </head>

    <body>

    </body>

</html>
<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
        <script type="text/javascript">
            function sty() {
            }
            sty.prototype = function() {
                add = function(x, y) {
                        return x + y;
                    },
                subtract = function(x, y) {
                        return x - y;
                    }
                return {
                    add: add,
                    subtract: subtract
                }
            }();
            set
            var aa = new sty();
            alert(aa.add(1, 2));
            alert(aa.subtract(1, 2));
        </script>
    </head>

    <body>

    </body>

</html>

<!--
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script type="text/javascript">
        var test=[1,2,3,4,5,6,7,8,9,10];
        window.onload=function(){
             combination(test, 4);
        }      



        function combination(array, NumberCount){
            var NUMBER_N=NumberCount;                 
            var LENGTH=array.length;
            var numberN=1;//当前填入N的是数字编号  
            var arrayN=[];//N个数的数组
            var arrayResult=[];//组合数的二维数组
            select(array.slice(0,LENGTH),arrayN,arrayResult,LENGTH,numberN,NUMBER_N);
        }


        function select(array,arrayN,arrayResult,LENGTH,numberN,NUMBER_N){          
            var length=array.length;
            var disFlag=NUMBER_N-numberN + 1 - length;
            if(disFlag==0){
                var index=arrayN.length-1;
                var focus=arrayN[index];
                arrayN=arrayN.concat(array);                                    
                arrayResult.push(arrayN);
                numberN--;
                arrayN=arrayN.slice(0,index);
                var array_next=test.slice(0,LENGTH);                    
                for(var j =0;j<LENGTH;j++){
                    var target=array_next.shift();
                    if(target==focus){break;}                                               
                }               
                select(array_next,arrayN,arrayResult,LENGTH,numberN,NUMBER_N);
            }else if(disFlag<0){
                if(numberN<NUMBER_N){
                    numberN++;              
                    arrayN.push(array[0]);
                    var arrayNew=array;
                    arrayNew.splice(0,1);
                    select(arrayNew,arrayN,arrayResult,LENGTH,numberN,NUMBER_N);
                }else{
                    numberN--;                      
                    for(var i in array){
                        var arrayN_new=arrayN.slice(0,arrayN.length);
                        arrayN_new.push(array[i]);
                        arrayResult.push(arrayN_new);                       
                    }               
                    arrayN.splice(arrayN.length-1,arrayN.length)
                    select(array,arrayN,arrayResult,LENGTH,numberN,NUMBER_N);
                }            
            }else{
                for(key in arrayResult){
                    var p = document.createElement("p");
                    p.innerText=arrayResult[key];               
                    document.body.appendChild(p);
                }               
                return;
            }            

        }

    </script>
</head>
<body>

</body>
</html>-->

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

这里写图片描述

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script type="text/javascript">
        (function(n){
            for (var i = 0; i <n; i++) {
                 setTimeout(function(){
                    console.log(i);
                 },1)
            }
        })(6)
    </script>
</head>
<body>

</body>
</html>

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    <script type="text/javascript">
        function add(n){
            this.n=n;
            this.m=function(){
                return this.n/2;
            }
        }
        var A=new add(20);
        alert(A.n+"  "+A.m());    //20   10
        A.n=40;
        alert(A.n+"  "+A.m());    //40   20
    </script>

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script>
        <title>Document</title>
        <style type="text/css">

        </style>
        <script type="text/javascript">
            var a;
            console.log("1:" + typeof a);
            var b = null;
            console.log("2:" + typeof b);
            var c = undefined;
            console.log("3:" + typeof c);
            var d = new Object;
            console.log("4:" + typeof d);
            var e = function() {};
            console.log("5:" + typeof e);
            var f = {};
            console.log("6:" + typeof f);
            var g = '';
            console.log("7:" + typeof g);
            var h = [];
            console.log("8:" + typeof h);
            var i = true;
            console.log("9:" + typeof i);
            var j = 123;
            console.log("10:" + typeof j);
            var k = NaN;
            console.log("11:" + typeof k);
            var l = /^[-+]?\d+$/;
            console.log("12:" + typeof l);
        </script>

    </head>

    <body>

    </body>

</html>

这里写图片描述

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
        <style type="text/css">
            #main {
                width: 200px;
                height: 200px;
                border-bottom-left-radius: 100%;
                background: red;
            }
        </style>
    </head>

    <body>
        <div id="main">

        </div>

    </body>

</html>
posted @ 2016-09-12 17:42  最骚的就是你  阅读(2899)  评论(0编辑  收藏  举报