基本數據類型:Number
、String
、Boolean
、Null
、Undefined
css
引用數據類型:Object
(Array
、Date
、RegExp
、Function
)html
那麼問題來了,如何判斷某變量是否爲數組數據類型?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
Ajax
是異步 JavaScript
和 XML
,用於在Web頁面中實現異步數據交互。ajax
優勢:正則表達式
- 可使得頁面不重載所有內容的狀況下加載局部內容,下降數據傳輸量算法
- 避免用戶不斷刷新或者跳轉頁面,提升用戶體驗json
缺點:跨域
- 對搜索引擎不友好(數組
- 要實現ajax下的先後退功能成本較大瀏覽器
- 可能形成請求數的增長
- 跨域問題限制
JSON
是一種輕量級的數據交換格式,ECMA的一個子集
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]; 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
function escapeHtml(str) { return str.replace('/[<>"&]/g', function(match) { switch(match) { case "<": return "<"; break; case ">": return ">"; break; case "\\": return """; break; case "&": return "&" break; } }); }
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());
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}
當使用RegExp()
構造函數的時候,不只須要轉義引號(即\」表示」),而且還須要雙反斜槓(即\\表示一個\)。使用正則表達字面量的效率更高。
for (var i = 0; i < 3; i++) { setTimeout((function() { console.log(i) })(i)) }
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
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; } }
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();
<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) }
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
function log (str) { console.log(str); }
若是須要知足多個參數?
function log () { console.log.apply(this, arguments); } log(111,222,333)// 111 222 333
call
和apply
的區別?
對於apply
和call
二者在做用上是相同的,便是調用一個對象的一個方法,以另外一個對象替換當前對象。將一個函數的對象上下文從初始的上下文改變爲由 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();
僞數組(類數組):沒法直接調用數組方法或指望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
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]; } } }
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(); } }) } }
給須要拖拽的節點綁定mousedown
, mousemove
, mouseup
事件
mousedown
事件觸發後,開始拖拽
mousemove
時,須要經過event.clientX
和clientY
獲取拖拽位置,並實時更新位置
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>