1

1、JavaScript数据类型有哪些?

基本数据类型:NumberStringBooleanNullUndefined

引用数据类型:ObjectArrayDateRegExpFunction

那么问题来了,如何判断某变量是否为数组数据类型?

  • 判断其是否具有“数组性质”,如slice()方法。可自己给该变量定义slice方法,故有时会失效
  • obj instanceof Array 在某些IE版本中不正确
  • obj.constructor === Array
  • ECMA Script5中定义了新方法Array.isArray(), 保证其兼容性,最好的方法如下:
function isArrayFn(o) {
    if(typeof Array.isArray === "function") {
        return Array.isArray(o);
    } else {
        return Object.prototype.toString.call(o) === "[object Array]"
    }
}
var o1 = [1,2,3,4,5];
var o2 = {a: 1, b: 2};
var o3 = [{a: 1, b: 2}];
isArrayFn(o1);    // true
isArrayFn(o2);    // false
isArrayFn(o3);    // true

2、JavaScript中事件流模型有哪些?

  • “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
  • “事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
  • “DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡

3、什么是Ajax和JSON,它们的优缺点。

Ajax是异步 JavaScriptXML,用于在Web页面中实现异步数据交互。

优点:

 - 可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量

 - 避免用户不断刷新或者跳转页面,提高用户体验

缺点:

 - 对搜索引擎不友好(

 - 要实现ajax下的前后退功能成本较大

 - 可能造成请求数的增加

 - 跨域问题限制

JSON是一种轻量级的数据交换格式,ECMA的一个子集

  • 优点:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)

4、已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”

var str = 'get-element-by-id';
var arr = str.split('-');
for (var i = 0; i < arr.length; i++) {
    arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1, arr[i].length - 1);
}
var res = arr.join('');
console.log(res)

5、var numberArray = [3,1,6,7,4,2];

  • 实现对该数组的倒排
  • 实现对该数组的降序排列
var numberArray = [3,1,6,7,4,2];
console.log(numberArray.reverse()); // 2,4,7,6,1,3

numberArray.sort(function(a, b) {
    return b - a;
})
console.log(numberArray) // 7,6,4,3,2,1

6、为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义

function escapeHtml(str) {
    return str.replace('/[<>"&]/g', function(match) {
        switch(match) {
            case "<":
                return "&lt;";
                break;
            case ">":
                return "&gt;";
                break;
            case "\\":
                return "&quot;";
                break;
            case "&":
                return  "&amp;"
                break;
        }
    });
}

7、用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。

var iArray = [];

function getRandom(istart, iend) {
    var iChoice = iend - istart + 1;
    return Math.floor(Math.random() * iChoice + istart);
}

for (var i = 0; i < 10; i++) {
    iArray.push(getRandom(10, 100));
}

console.log(iArray.sort());

8、有这样一个URL:http://item.taobao.com/item.h...,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:’1′, b:’2′, c:”, d:’xxx’, e:undefined}。

function getUrlParam(url) {
    var result = {};
    url = url.split('?')[1];
    var map = url.split('&');
    for (var i = 0; i < map.length; i++) {
        result[map[i].split('=')[0]] = map[i].split('=')[1];
    }
    return result;
}
var url = 'http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e';
var res = getUrlParam(url);
console.log(res);// {a: "1", b: "2", c: "", d: "xxx", e: undefined}

9、正则表达式构造函数var reg=new RegExp(“xxx”)与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?

当使用RegExp()构造函数的时候,不仅需要转义引号(即\”表示”),并且还需要双反斜杠(即\\表示一个\)。使用正则表达字面量的效率更高。

10、如何循环输出1、2、3?

for (var i = 0; i < 3; i++) {
    setTimeout((function() {
        console.log(i)
    })(i))
}

11、写一个function,清除字符串前后的空格。(兼容所有浏览器)

if (!String.prototype.trim) {
    String.prototype.trim = function () {
        return this.replace(/^\\s+/g, '').replace(/\\s+$/g, '');
    }
}
var str = ' this is a test string ';
alert(str.trim() == 'this is a test string') // true

12、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

  • 考察点1:对于基本数据类型和引用数据类型在内存中存放的是值还是指针这一区别是否清楚
  • 考察点2:是否知道如何判断一个变量是什么类型的
  • 考察点3:递归算法的设计
function clone (obj) {
    var res;
    if (obj instanceof Array) {
        res = [];
        var i = obj.length;
        while (i--) {
            res[i] = clone(obj[i]);
        }
        return res;
    }
    else if (obj instanceof Object) {
        res = {};
        for (var k in obj) {
            res[k] = clone(obj[k]);
        }
        return res;
    }
    else {
        return obj;
    }
}

13、小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:

function Dog () {
    this.wow = function () {
        console.log('wow')
    }
    this.yelp = function () {
        this.wow();
    }
}

小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实。(继承,原型,setInterval)

function MadDog () {
    this.yelp = function () {
        var self = this;
        setInterval(function () {
            self.wow();
        }, 500);
    }
}

MadDog.prototype = new Dog();
var dog = new Dog();
dog.yelp();
var madDog = new MadDog();
madDog.yelp();

14、下面这个ul,如何点击每一列的时候alert其index?(闭包)

<ul id="test">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

// 方法一
var lis = document.getElementById('test').getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
    lis[i].index = i;
    lis[i].onclick = (function (a) {
        return function () {
            alert(a)
        }
    })(i);
}

// 方法二
var lis = document.getElementById('test').getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
    (function (i) {
        lis[i].addEventListener('click', function () {
            alert(i)
        })
    })(i)
}

15、给String对象添加一个方法,传入一个string类型的参数,然后将string的每个字符间价格空格返回,例如:

addSpace(“Hello World”) // -> ‘h e l l o  w o r l d’

String.prototype.space = function () {
    return this.split('').join(' ');
}

var str = 'hello world';
console.log(str);// hello world
console.log(str.space());// h e l l o   w o r l d

16、定义一个log方法,让它可以代理console.log的方法。

function log (str) {
    console.log(str);
}

如果需要满足多个参数?

function log () {
    console.log.apply(this, arguments);
}

log(111,222,333)// 111 222 333

callapply的区别?

对于applycall两者在作用上是相同的,即是调用一个对象的一个方法,以另一个对象替换当前对象。将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.speakname = function () {
        alert(this.name)
    }
    this.speakage = function () {
        alert(this.age)
    }
}

function Man (name, age, sex) {
    Person.call(this, name, age);    // 继承Person对象 this指向Person
    this.sex = sex;
    this.speaksex = function () {
        alert(this.sex)
    }
}

var person = new Man('ashin', 35, 'man');
person.speakname();
person.speakage();
person.speaksex();

17、在Javascript中什么是伪数组?如何将伪数组转化为标准数组?

伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的argument参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array对象。

var fakeArray = {0: 'a', 1: 'b', length: 2}; // 伪数组
var arr = Array.prototype.slice.call(fakeArray);

假设接第八题题干,我们要给每个log方法添加一个”app”前缀,比如’hello world!’ ->’app hello world!’

function log () {
    var args = Array.prototype.slice.call(arguments);
    args.unshift('hello nodejs');
    console.log.apply(this, args);
}

log(1,2);    // hello nodejs 1 2

18、Javascript中callee和caller的作用?

caller是返回一个对函数的引用,该函数调用了当前函数;

callee是返回正在被执行的function函数,也就是所指定的function对象的正文。

如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子?(使用callee完成)

var result = [];
function fn (n) {
    if (n == 1) {
        result = 1;
    }
    else if (n == 2) {
        result = 1;
    }
    else {
        if (result[n]) {
            return result[n];
        }
        else {
            // arguments.callee 表示 fn()
            result[n] = arguments.callee(n-1) + arguments.callee(n-2);
            return result[n];
        }
    }
}

19、原生JS的window.onload与Jquery的$(document).ready(function(){})有什么不同?如何用原生JS实现Jq的ready方法?

window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行。

$(document).ready()DOM结构绘制完毕后就执行,不必等到加载完毕。

function ready (fn) {
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', function () {
            // 注销事件 避免反复触发
            document.removeEventListener('DOMContentLoaded', arguments.callee, false);
            fn();// 执行函数
        }, false);
    }
    else if (document.attachEvent) {
        document.attachEvent('onreadystatechange', function () {
            if (readyState == 'complete') {
                document.detachEvent('onreadystatechange', arguments.callee);
                fn();
            }
        })
    }
}

20、(设计题)想实现一个对页面某个节点的拖曳?如何做?(使用原生JS)

给需要拖拽的节点绑定mousedown, mousemove, mouseup事件

mousedown事件触发后,开始拖拽

mousemove时,需要通过event.clientXclientY获取拖拽位置,并实时更新位置

mouseup时,拖拽结束

需要注意浏览器边界的情况

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
    *{
    margin: 0;
    padding: 0;
    }
    #drag{
    position: absolute;
    background-color: pink;
    width: 100px;
    height: 100px;
    cursor: move;
    }
</style>
</head>
<body>
    <div id="drag"></div>
    <script>
    var Drags = function (element, callback) {
        
        callback = callback || function () {};
        var params = {
              top: 0,
              left: 0,
              currentX: 0,
              currentY: 0,
              flag: false
        }
        
        function getCss(element, key) {
             return element.currentStyle ? element.currentStyle[key] : document.defaultView.getComputedStyle(element,null)[key];
             // ie用currentStyle
        }
        
        var lefts = getCss(element, "left"),
        tops = getCss(element, "top");
        params.left = lefts !== "auto" ? lefts : 0;
        params.top = tops !== "auto" ? tops : 0;
        element.onmousedown = function (event) {
              params.flag = true;
              event = event || window.event; // ie用后面
              params.currentX = event.clientX;
              params.currentY = event.clientY;
        }
        
        document.onmousemove = function (event) {
              event = event || window.event;
              if (params.flag) {
                    // 现在位置
                    var nowX = event.clientX,
                    nowY = event.clientY,
                    // 需要移动的距离  
                    disX = nowX - params.currentX,
                    disY = nowY - params.currentY;
                    element.style.left = parseInt(params.left) + disX + "px";
                    element.style.top = parseInt(params.top) + disY + "px";
              }
        }
        
        
        document.onmouseup = function () {
              params.flag = false;
                    var lefts = getCss(element, "left"),
                        tops = getCss(element, "top");
                    params.left = lefts !== "auto" ? lefts : 0;
                    params.top = tops !== "auto" ? tops : 0;
              }
       
        }(document.getElementById('drag'));
    </script>
</body>
</html>

五月的星空
239 声望5 粉丝