基本数据类型: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>