JavaScript基礎知識整理(1)

一、JavaScript數據類型有哪些?

基本數據類型:NumberStringBooleanNullUndefinedcss

引用數據類型:ObjectArrayDateRegExpFunctionhtml

那麼問題來了,如何判斷某變量是否爲數組數據類型?node

  • 判斷其是否具備「數組性質」,如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

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

  • 「事件冒泡」:事件開始由最具體的元素接受,而後逐級向上傳播
  • 「事件捕捉」:事件由最不具體的節點先接收,而後逐級向下,一直到最具體的
  • 「DOM事件流」:三個階段:事件捕捉,目標階段,事件冒泡

三、什麼是Ajax和JSON,它們的優缺點。

Ajax是異步 JavaScriptXML,用於在Web頁面中實現異步數據交互。ajax

優勢:正則表達式

 - 可使得頁面不重載所有內容的狀況下加載局部內容,下降數據傳輸量算法

 - 避免用戶不斷刷新或者跳轉頁面,提升用戶體驗json

缺點:跨域

 - 對搜索引擎不友好(數組

 - 要實現ajax下的先後退功能成本較大瀏覽器

 - 可能形成請求數的增長

 - 跨域問題限制

JSON是一種輕量級的數據交換格式,ECMA的一個子集

  • 優勢:輕量級、易於人的閱讀和編寫,便於機器(JavaScript)解析,支持複合數據類型(數組、對象、字符串、數字)

四、已知有字符串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)

五、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

六、爲了保證頁面輸出安全,咱們常常須要對一些特殊的字符進行轉義,請寫一個函數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;
        }
    });
}

七、用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());

八、有這樣一個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}

九、正則表達式構造函數var reg=new RegExp(「xxx」)與正則表達字面量var reg=//有什麼不一樣?匹配郵箱的正則表達式?

當使用RegExp()構造函數的時候,不只須要轉義引號(即\」表示」),而且還須要雙反斜槓(即\\表示一個\)。使用正則表達字面量的效率更高。

十、如何循環輸出一、二、3?

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

十一、寫一個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

十二、實現一個函數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;
    }
}

1三、小賢是一條可愛的小狗(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();

1四、下面這個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)
}

1五、給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

1六、定義一個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();

1七、在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

1八、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];
        }
    }
}

1九、原生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>
相關文章
相關標籤/搜索