Web前端 基礎知識總結(Javascript篇)
1.類型判斷
typeof 檢測基本數據類型
如下實例:
typeof 2 輸出 number
typeof null 輸出 object
typeof {} 輸出 object
typeof [] 輸出 object
typeof (function(){}) 輸出 function
typeof undefined 輸出 undefined
typeof ‘222’ 輸出 string
typeof true 輸出 boolean
這裏麪包含了js裏面的五種數據類型 number , string , boolean ,undefined,object和函數類型 functioninstanceof 根據原型鏈判斷是否爲某類型實例
var c= [1,2,3];
var d = new Date();
var f = function(){this.name=”22”;};
alert(c instanceof Array) —————> true
alert(d instanceof Date) —————> true
alert(f instanceof Function) ————> true
alert(f instanceof function) ————> false
alert(f instanceof Object) ————> true //原型鏈向上爲Object的實例constructor 根據對象的constructor構造函數類型判斷
//接上例
alert(c.constructor === Array) ———-> true
alert(d.constructor === Date) ———–> true
alert(f.constructor === Function) ——-> true
alert(f.constructor === Object) ——-> false //可用來區分數組和對象Object.prototype.toString 基類Object的原型方法打印具體類型的字符串
var gettype=Object.prototype.toString
gettype.call(‘aaaa’)輸出 [object String]
gettype.call(2222) 輸出 [object Number]
gettype.call(true) 輸出 [object Boolean]
gettype.call(undefined) 輸出 [object Undefined]
gettype.call(null) 輸出 [object Null]
gettype.call({}) 輸出 [object Object]
gettype.call([]) 輸出 [object Array]
gettype.call(function(){}) 輸出 [object Function]
//同樣可以精確區分數組和對象
2.對象繼承
想要了解對象繼承的原理,要先弄清楚js對象的原型鏈關係,推薦博文http://www.cnblogs.com/wangfupeng1988/p/4001284.html
寫得非常詳細且易於理解。
繼承方法例:
function Animal(name) {
this.name = name;
}
Animal.prototype.eat = function () {
console.log(this.name + ' is eating');
}
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype.__proto__= Animal.prototype;
var cat = new Cat('hello kitty');
console.log(cat instanceof Cat);
console.log(cat instanceof Animal);
console.log(cat.constructor);
console.log(cat);
cat.eat();
//打印結果:
true
true
Cat(name) {
Animal.call(this, name);
}
Cat {name: "hello kitty"}
hello kitty is eating
3.對象複製
- 淺拷貝
var myobj = {
name: 'kitty',
property: {
like: 'eat',
unlike: 'others'
}
};
function shallowCopy(obj) {
var copy = {};
for (var i in obj) {
copy[i] = obj[i];
}
return copy;
}
var shallowcopy = shallowCopy(myobj);
shallowcopy.property.like = 'exercise';
console.log(shallowcopy.property.like);
console.log(myobj.property.like);
//打印結果:
exercise
exercise
淺拷貝存在的問題:如果父對象的屬性等於數組或另一個對象,那麼實際上,子對象獲得的只是一個內存地址,而不是真正拷貝,因此存在父對象被篡改的可能。
- 深拷貝
function deepCloneObj(obj) {
var objCopy = obj.constructor == Array ? [] : {};
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
objCopy[i] = typeof obj[i] == 'object' ? deepCloneObj(obj[i]) : obj[i];
}
}
return objCopy;
}
var deepcopy = deepCloneObj(myobj);
console.log(deepcopy .property.like);
console.log(myobj.property.like);
//打印結果:
exercise
eat
深拷貝真正實現對象的複製,修改複製的對象不影響原始對象的值。
jQuery中有直接的api可以調用,實現淺拷貝和深拷貝:
var copy=$.extend( true, [], obj); //深度複製數組
4.事件代理
w3c標準事件模型,分爲三個階段:捕獲、在目標節點、冒泡。
IE8以下版本,不支持此事件模型,只有冒泡階段。
利用事件捕獲階段,可以提前捕獲目標節點的事件進行處理,對應的應用場景是事件代理,例:
/*alert任意標籤名稱(兼容性)*/
/*IE低版本事件函數沒有傳參事件對象,只有全局window.event對象,且事件對象沒有target屬性只有srcElement屬性。*/
function elementName(evt) {
var evt = evt || window.event;
var selected = evt.target || evt.srcElement;
alert(selected.tagName);
}
window.onload = function () {
document.body.onclick = elementName;
}
使用事件代理可以有效減少綁定的事件個數,節省資源,且可滿足動態添加子元素後子元素無需重複綁定事件。
5.閉包
模仿塊級作用域&&保留外部函數作用域
實現alert列表中不同項的索引值,例:
/*閉包*/
//立即執行函數,擁有不與外界衝突的獨立作用域
(function () {
var index = 0;
var ul = document.getElementById("test");
var obj = {};
for (var i = 0, l = ul.childNodes.length; i < l; i++) {
if (ul.childNodes[i].nodeName.toLowerCase() == "li") {
var li = ul.childNodes[i];
index++;
//li綁定事件保留外部index變量值
li.onclick = (function (inner) {
return function () {
alert(inner);
}
})(index)
}
}
})();
閉包特性例子:
for(var i=0;i<5;i++){
setTimeout(function(){
console.log(i);
},1000*i);
}
//結果:
一開始輸出一個5,然後每隔一秒輸出一個5,一共5個5
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){
console.log(i);
},1000*i);
})(i);
}
//結果:
輸出0到4
for(var i=0;i<5;i++){
setTimeout(function(i){
console.log(i);
})(i),1000*i);
}
//結果:
立馬輸出0到4
//相當於setTimeout(undefined,...);
- 單例模式&&封裝
var singleton = (function () {
var privateNum = 10;
return {
publicGet: function () {
console.log(privateNum);
},
publicSet: function (newNum) {
privateNum = newNum;
}
}
})();
6.監聽對象變化
var my = {};
Object.defineProperty(my, 'hobby', {
set: function (value) {
hobby = value;
console.log('set hobby to ' + hobby);
},
get: function () {
console.log('get ' + hobby);
return hobby;
}
});
my.hobby = 'basketball';
my.hobby = 'football';
var myhobby = my.hobby;
//打印結果:
set hobby to basketball
set hobby to football
get football
7.事件延遲觸發
應用場景:鼠標滑過控件,希望觸發某事件,但有時候用戶會頻繁或無意地滑過,希望延遲觸發事件,懸浮一段時間後才觸發
封裝鼠標懸浮延遲觸發函數:
var delay = function (t, fn) {
_this = this,
//解決this綁定問題,所以調用delay函數的時候,請處理好this指向本身對象
d = setTimeout(function () {
fn.apply(_this);
}, t * 1000);
_this.onmouseout = function () {
clearTimeout(d);
};
}
應用:
//鼠標懸浮在按鈕上1秒才彈出按鈕id,一秒以內滑出則取消定時器,不彈出
var button = document.getElementById('button');
button.onmouseover = function () {
delay.apply(this,
[1, function () { alert(this.id) }]
);
};