[TOC]

1
(window.foo || (window.foo = “bar”));
document.write(foo);
//输出
//bar;
//括号优先级最高 先执行括号里面的内容(window.foo = “bar”) 此时foo为bar
//再执行window.foo 这个没什么意义 所以最终得到foo为bar
//这题如果这样写(window.foo || window.foo = “bar”) 会报错
//因为 || 运算级比 == 高

2 (阿里笔试题)
function test(a,b,c,d){
console.log(a+b+c+d);
}(1,2,3,4);
//按理说这样写会报错
//但是系统识别时 会让其尽量不报错
//所以系统是这样识别的
function test(a,b,c,d){
console.log(a+b+c+d);
}
(1,2,3,4);
//即把 函数 和 (1,2,3,4); 分开 所以此时函数也不执行 系统也不报错

*3(常见)
3.1

![@RY6Q6C(B29)({A4MYCR9W.png
))C$Z_K1_JTST_AZU}@%0N1.png
//注意这里只是把function装进了arr[i]中 系统并不管function中写了什么 只有当function执行时才会读里面的语句
//也就是函数定义时并不用看函数里面有什么 只有当函数执行时才知道里面是什么
//test执行完后 将arr返回出去给了myArr
//此时arr中共装有10个function 这10个function都产生了闭包
//遍历执行myArr[j]函数 即执行arr[j]函数
//但是arr[j]中装的是输出i 从作用域链上至下寻找变量i 此时i的值为10
//所以输出结果为10个10
//也就是说函数中的语句不是定义之后就执行的 是等到函数被调用时才会执行
//即上述的那个function里面的语句不是定义时就把i装进去了 而是等到被调用时才知道i是几
3.2
若想按顺序输出,解决方法:

//上述for循环产生了10个不同的立即执行函数 它们彼此独立
//每个arr[j]保存的是相对应的立即执行函数的劳动成果(即执行期上下文)
//然后arr被返回出去给了myArr 当myArrj执行时 即对应arr[j]执行
//然后arr[j]执行时需要找j 自己这没有 就找立即执行函数中的j 发现立即执行函数的j被i传参了
//比如 (function (j) {
arr[j] = function () {
console.log(j);
}
}(0))
//此时 i = 0传给了j 所以j = 0 以此类推 所以这时就可以按顺序输出了

4

//看括号 发现里面有逗号 那么把最后一个返回
//括号中只剩最后一个函数
//即 function g() {
return 2;
}
//所以结果为 var f = 2; 即为number类型

5

//if()的括号中写的是条件 而被认定为false的只有那六个 所以这里一定能执行
//(function f(){}) 括号把这个函数变为表达式了 那么这个就不是函数定义了
//既然不是函数定义 那么系统中就不存在这个函数f
//本来任何一个变量未经声明就使用会报错 但是typeof是个例外
//所以即使f不存在 也能返回string类型的undefined
//那么结果就是 1undefined

6

//输出
//string;
//undefined;

7
构造一个函数 计算字符串的字节长度 code码大于255之后是中文 中文占两个字节

8 区别对象和数组的三种方法
1 constructor
[].constructor —-> Array
var obj = {}; obj.constructor —-> Object
2 instanceof
[] ininstanceof Array —->true
obj ininstanceof Array —->false
*3 Object.prototype.toString.call( )
Object.prototype.toString.call( [] ) —-> “[object Array]”
Object.prototype.toString.call( {} ) —-> “[object Object]”

9
function test(){
test1.apply(null,arguments);
}
function test1(){
console.log(arguments);
}
test(1,2,3,4,5);
//结果输出一个数组 [1,2,3,4,5]

10 this

//结果为
// 222
// 111
// 222
// 333

11 this
11.1

//注意此时print是一个函数 不是对象 所以this指代的是window
//print函数自身没有foo 所以就上GO里面去找 this.foo就改变了window的foo
//所以输出 234
11.2

//注意此时print是一个对象 所以this指代就不是window了 指代的是print对象
//即 this.foo = 234; 就把 234 装到了这个this对象中
//那么此时访问的是foo 但不是this上的foo 但是print对象AO中没有foo 所以只能去全局中找
//输出 123
11.3

//输出 0 5 0 0 undefined 0
//对于new test(); 其AO为
// AO{
// a : 0
// this : { proto : test.prototype }
// }
//所以输出 this.a 时 因为this中没有a 所以输出 undefined

12

//haha没有定义直接使用 程序报错 error : haha is not defined

13 克隆 将一个对象克隆给另外一个对象 且两者之间没有关联
1 判断是不是原始值
2 判断是数组还是对象
3 建立对应的数组或对象

        var deepClone = function(origin,target){
              //如果没有传递target参数 那么我们就可以人为帮它创建一个空对象
            var target = target || {};
            toStr = Object.prototype.toString;
            arrStr = '[Object Array]';
            for(var value in origin){
                  //先判断属性是不是自己的
                if(origin.hasOwnProperty(value)){
                      //判断属性是不是原始值  若不是 且属性不为null(因为null的类型也是object)
                    if(origin[value]!=='null' && typeof(origin[value]) == 'object'){
                          //判断是数组还是对象
                          //这里也可以用三目运算符
                          //
                        if(toStr.call(origin[value]) == arrStr){
                              //数组
                            target[value] = [];
                        }else{
                              //对象
                            target[value] = {};
                        }
                          //递归执行数组或对象里面的克隆
                        deepClone(origin[value],target[value]);
                    }else{
                          //若属性是原始值 那么就可以直接赋值
                        target[value] = origin[value];
                    }
                }
            }
            return target;
        }

14 给定一个有序数组 让其乱序排列
var arr = [1,2,3,4,5,6,7];
arr.sort(function(){
return Math.random()-0.5;
});
//Math.random()产生的是(0,1)之间的数

15 封装typeof方法

    <script>
        var type = function(target){
            var template = {
                '[object Array]' : 'array',
                '[object Number]' : 'number-object',
                '[object Object]' : 'object',
                '[object Boolean]' : 'boolean-object',
                '[object String]' : 'string-object',
            }
            //判断target是否为null 注意这里是绝对等于 因为undefined==null 比较结果也是true
            if(target === null){
                return 'null';
            }
              //判断是否是原始值 或 引用
            if(typeof target == 'object'){
                var str = Object.prototype.toString.call(target);
                return template[str];
            }else{
                  //是原始值 或 函数 都直接返回
                return typeof target;
            }
        }
    </script>

16 数组去重

    <script>
        Array.prototype.unique = function(){
              //temp用来去重
              //finalArr用来存储最终去重后的数组
            var temp = {},
                finalArr = [],
                len = this.length;
                for(var i = 0; i<len; i++){
                      //
                    if(!temp[this[i]]){
                            //将数组的值作为temp对象的属性名 如果属性名已经存在了 就不往里存东西
                          //属性值这里取值为abc
                          //注意属性值不能取为false的值 以及this[i]
                          //因为执行判断时 会导致判断结果为true 就达不到去重的效果
                          //如 temp[this[i]] = this[i] 当存 0 时 判断if(!temp[this[i]])
                          //结果为true 执行finalArr.push(this[i]);
                          //那么后续存 0 时 仍然会把0装进finalArr数组中
                        temp[this[i]] = 'abc';
                        finalArr.push(this[i]);

                    }
                }
                return finalArr;
        }
    </script>

比如
var arr = [2,2,2,1,3,1,3,5,2,4,5,5,]
arr.unique();
//结果为[2, 1, 3, 5, 4]

17 返回元素e的第n层祖先元素节点

    <script>
        function retParent(elem,n){
            while(elem && n){
                elem = elem.parentElement;
                n--;
            }
            return elem;
        }
    </script>

18 封装myChildren功能 解决部分浏览器不兼容问题

    <script>
        Element.prototype.myChilden = function(){
            var child = this.childNodes,
                len = child.length,
                arr = [];
            for(var i = 0;i<len;i++){
                if(child[i].nodeType == 1){
                    arr.push(child[i])
                }
            }
            return arr;
        }
    </script>

19 封装函数 输入元素elem和位数n 若n为正数 返回元素elem后面的第n位兄弟元素
若n为负数 返回元素elem前面的第n位兄弟元素 若n为0 返回自己

    <script>
        function retSibling(elem, n) {
            while (elem && n) {
                if (n > 0) {
                      //这里是为了IE浏览器的兼容问题  不兼容就走下面的else
                    if (elem.nextElementSibling) {
                        elem = elem.nextElementSibling;
                    } else {
                        for (elem = elem.nextSibling; elem && elem.nodeType != 1; elem = elem.nextSibling) { };
                    }
                    n--;
                } else {
                    if (elem.previousElementSibling) {
                        elem = elem.previousElementSibling;
                    } else {
                        for (elem = elem.previousSibling; elem && elem.nodeType != 1; elem = elem.previousSibling) { };
                    }
                    n++;
                }
            }
            return elem;
        }
    </script>

20 模拟insertBefore函数 封装insertAfter函数

    //方式一
        <script>
        Element.prototype.insertAfter = function(newTag, tag) {
                this.replaceChild(newTag, tag);
                this.insertBefore(tag, newTag);
        }
    </script>
        //方式二
        <script>
        Element.prototype.insertAfter = function(targetNode, afterNode) {
                var beforeNode = afterNode.nextElementSibling;
                if(beforeNode == null){
                    this.appendChild(targetNode);
                }else{
                    this.insertBefore(targetNode,beforeNode);
                }
        }
    </script>

21 使用JS的addEventListener 给每一个li绑定一个click事件 要求输出他们的次序


  • a

  • a

  • a

  • a


即点击第一个li输出1 点第二个li输出2 以此类推

    <script>
        var li = document.getElementsByTagName('li');
        len = li.length;
        for (var i = 0; i < len; i++) {
              //注意闭包就要用到这个立即执行函数
            (function(j){
                li[j].addEventListener('click',function(){
                console.log(j+1);
            },false)
            }(i))
        }
    </script>

22 ** 应用 mousedown mousemove mouseup 实现鼠标拖拽应用 可以随机移动方块**

<body>
      //注意要写为行间样式 若写为外部样式 那么不好用
    <div style=" width: 100px;height: 100px;background-color: green;position: absolute;
    left: 0;top: 0;"></div>
    <script>
        var div = document.getElementsByTagName('div')[0];
         var disX,
             disY;
        div.onmousemove = function (e) {
            disX = e.pageX - parseInt(div.style.left),
            disY = e.pageY - parseInt(div.style.top);
            document.onmousemove = function (e) {
                div.style.left = e.pageX - disX + 'px';
                div.style.top = e.pageY - disY + 'px';
            }
            document.onmouseup = function(){
                div.onmousemove = null;
            }
        }
    </script>
</body>

封装后的drag函数 可以拖拽任意元素

<body>
    <div style=" width: 100px;height: 100px;background-color: green;position: absolute;
    left: 0;top: 0;"></div>
    <script>
        var div = document.getElementsByTagName('div')[0];
        drag(div);
        function drag(elem) {
            var disX,
                disY;
            addEvent(elem, 'mousedown', function (e) {
                var event = e || window.event;
                //disX和disY表示鼠标位置距离元素区域左侧和上侧的距离
                disX = event.pageX - parseInt(getStyle(elem, 'left')),
                disY = event.pageY - parseInt(getStyle(elem, 'top'));
                //mousemove和mouseup如果绑定在元素身上 那么当鼠标移动过快导致移出元素区域时
                //那么因为监听事件间隔时间可能没那么快 就会导致元素定着不动 即使我们没有松开鼠标按键
                //所以事件可以绑定在document身上 这时无论鼠标怎么移动 元素都会跟着
                addEvent(document, 'mousemove', mouseMove);
                addEvent(document,'mouseup',mouseUp);
            });
            function mouseMove(e) {
                var event = e || window.event;
                //要想元素随鼠标移动 就需要改变其坐标
                elem.style.left = event.pageX - disX + 'px';
                elem.style.top = event.pageY - disY + 'px';
            }
            function mouseUp(e){
                document.removeEventListener('mousemove',mouseMove,false);
            }
        }

        function addEvent(elem, type, handleFunc) {
            if (elem.addEventListener) {
                elem.addEventListener(type, handleFunc, false);
            } else if (elem.attachEvent) {
                elem.attachEvent('on' + type, function () {
                    handleFunc.call(elem);
                })
            } else {
                elem['on' + type] = handleFunc;
            }
        }

        function getStyle(elem, prop) {
            if (window.getComputedStyle) {
                return window.getComputedStyle(elem, null)[prop];
            } else {
                return elem.currentStyle[prop];
            }
        }
    </script>
</body>

23 检测字符串是否首尾是否含有数字
即判断首或尾是否有数字
var reg = /^\d|\d$/g;
若判断首尾都是否有数字
var reg = /^\d[\s\S]\d$/g; 这里中间些什么区间都行 不过要写成全集的这种形式

24 (百度笔试)
让一个数从后往前 每隔三个位置写一个小数点
如 100000000 —-> 100.000.000

    <script>
        //首先要从尾部开始往前找 所以用到了$
        //三位数字为一组 所以用到了(\d{3})
        //每三位数字一组 往前匹配 所以是(\d{3})+$)
        //如果匹配完前面刚好剩三个 那么最前面也会加上小数点. 所以我们要加上非单词边界\B
        //即匹配的三位数 要是非单词边界 才会加小数点.
        //其中 (?=n)前面未写 那么就为空 即匹配空后紧接指定字符串 n 的字符串
        //所以 (?=(\B)(\d{3})+$) 就表示 匹配空后 紧接指定的 非单词边界 且 从后往前每三位数字一组的 字符串
        var reg = /(?=(\B)(\d{3})+$)/g;
        var str = "100000000";
        console.log(str.replace(reg,"."));
    </script>