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) }]
);
};