前端知识总结

1、Javascript中null和undefined的区别

总所周知:null == undefined //true
          null !== undefined //false

null:是JavaScript的关键字,用于描述“空值”,对其执行typeof操作返回“object”,即为一个特殊的对象值,可以表示数字、字符串和对象是“无值”。

null参与数值运算时其值会自动转换为0,因此,下列表达式计算后会得到正确的数值。

123 + null //123

123 * null // 0 

undefined:是预定义的全局变量,其值为“未定义”,typeof(undefined)返回“undefined”,它是变量的一种取值,表示变量没有初始化。当查询对象属性、数组元素的值时,如果返回undefined则表示属性或者元素不存在;如果函数没有任何返回值,也返回“undefined”

alert('undefined' in window);//输出:true 
var obj= {}; 
alert('undefined' in obj); //输出:false
由上可知:undefined是window对象中的一个属性,但不属于object对象。

注意:undefined有特殊的含义,但却不是JavaScript的保留字。

undefined参与任何数组计算时,其结果一定是NaN(Not a number);

By the way: NaN是全局对象的另一个特殊属性,Infinity也是,这行特殊属性都不是JavaScript的保留字!

null == 0; // <span style="color:#cc0000;">false </span>
undefined == ""; // <span style="color:#cc0000;">false </span>
null == false; //<span style="color:#cc0000;"> false </span>
undefined == false; // <span style="color:#cc0000;">false</span> 
null == undefined; // <span style="color:#cc0000;">true</span>


2、对象声明提前的思考:

如下代码:

var a = 0;
function a(){}; 
console.log(a); // 0 

function a(){};
var a = 0; 
console.log(a); // 0

function a(){};
var a; 
console.log(a); //function a() {};

var a; 
function a(){} 
console.log(a); //function a() {};
注意:函数的声明提前是整个提前,var的提前只是变量的提前,赋值位置不变,由此第一个JS解析器会解析为:

var a;
function a(){};
a = 0;
console.log(a); //0


3、JavaScript中的数据类型(原始类型)

js中共有五种基础数据类型:Null、Undefined、String、Number、Boolean

原始类型和引用类型有着根本的区别。

原始类型的值是不可更改的,引用类型的值是赋值的引用是可变的:

var a = [1,2];
var b = a;
b.push(3);
console.log(a);//[1,2,3]
上面就是引用类型的理解,var b = a;其实是把a值得引用交给b,这时候他们共享同一个引用,如果对b进行修改则a也会受影响。


4、如何判断是否为数组:

function isArray(data){
  if(Array.isArray){//如果存在ES5方法isArray直接调用
    return Array.isArray(data);
  }else{
    return Object.prototype.toString.call(data) === "[object Array]";
  }
}

具体详解: http://blog.csdn.net/u013084331/article/details/51150387


5、如何将伪数组转为数组:

无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们。典型的是函数的 arguments 参数,还有像调用getElementsByTagName,document.childNodes之类的,它们都返回 NodeList对象都属于伪数组。可以使用Array.prototype.slice.call(fakeArray)将数组转化为真正的Array 对象;

总结:类数组A,A.length能正常返回长度,但不能进行a.push(1)!

var toArray = function(s){  
    try{  
        return Array.prototype.slice.call(s);  
    } catch(e){  
            var arr = [];  
            for(var i = 0,len = s.length; i < len; i++){  
                //arr.push(s[i]);  
                 arr[i] = s[i]; //据说这样比push快  
            }  
             return arr;  
    }  
具体详解: http://blog.csdn.net/u013084331/article/details/51210444

6、数组去重:

一个数组中的去重

	function noRepeat(arr){
		var result = [];
		result[0] = arr[0];
		for(var i=1,len=arr.length;i<len;i++){
			if(result.indexOf(arr[i]) == -1){
				result.push(arr[i]);
			}
		}
		return result;
	}
	var a1 = [1,2,2,3,3,3,4,4,4,4,5,5,5,5,5];
	console.log(noRepeat(a1)); //[1,2,3,4,5]

两个数组去重(一个数组去除另一数组已存在的值)

  function noRepeatFilter(arr1,arr2){
	return arr1.filter(function(arr1Value){
		return arr2.indexOf(arr1Value) == -1;
	})
  }
  var a1 = [1,2,3,4,5];
  var a2 = [3,4,5,6,7];
  console.log(noRepeatFilter(a1,a2));//[1, 2]

7、定义一个log方法,让它可以代理console.log的方法:

方法一:

function log(msg) {
    console.log(msg);
}
log("hello world!") // hello world!
方法二:

function log(){
    console.log.apply(console, arguments);
};


8、call和apply的区别

对于apply和call两者在作用上是相同的,即是调用一个对象的一个方法,以另一个对象替换当前对象。将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入, 而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1, [var1,var2,var3]) 。


9、原生JS的window.onload与Jquery的$(document).ready(function(){})有什么不同?如何用原生JS实现Jq的ready方法?

window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。

所以JQ的ready执行比onload要快

原生JS实现JQ的ready方法一:

/* 方法一
 * 传递函数给whenReady()
 * 当文档解析完毕且为操作准备就绪时,函数作为document的方法调用
 */
var whenReady = (function() {               //这个函数返回whenReady()函数
    var funcs = [];             //当获得事件时,要运行的函数
    var ready = false;          //当触发事件处理程序时,切换为true
  
    //当文档就绪时,调用事件处理程序
    function handler(e) {
        if(ready) return;       //确保事件处理程序只完整运行一次
  
        //如果发生onreadystatechange事件,但其状态不是complete的话,那么文档尚未准备好
        if(e.type === 'onreadystatechange' && document.readyState !== 'complete') {
            return;
        }
  
        //运行所有注册函数
        //注意每次都要计算funcs.length
        //以防这些函数的调用可能会导致注册更多的函数
        for(var i=0; i<funcs.length; i++) {
            funcs[i].call(document);
        }
        //事件处理函数完整执行,切换ready状态, 并移除所有函数
        ready = true;
        funcs = null;
    }
    //为接收到的任何事件注册处理程序
    if(document.addEventListener) {
        document.addEventListener('DOMContentLoaded', handler, false);
        document.addEventListener('readystatechange', handler, false);            //IE9+
        window.addEventListener('load', handler, false);
    }else if(document.attachEvent) {
        document.attachEvent('onreadystatechange', handler);
        window.attachEvent('onload', handler);
    }
    //返回whenReady()函数
    return function whenReady(fn) {
        if(ready) { fn.call(document); }
        else { funcs.push(fn); }
    }
})();
方法二:

function ready(fn){
    if(document.addEventListener) {        //标准浏览器
        document.addEventListener('DOMContentLoaded', function() {
            //注销事件, 避免反复触发
            document.removeEventListener('DOMContentLoaded',arguments.callee, false);
            fn();            //执行函数
        }, false);
    }else if(document.attachEvent) {        //IE
        document.attachEvent('onreadystatechange', function() {
            if(document.readyState == 'complete') {
                document.detachEvent('onreadystatechange', arguments.callee);
                fn();        //函数执行
            }
        });
    }
};

10、实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制

方法一:

 Object.prototype.clone = function(){
         var o = this.constructor === Array ? [] : {};
         for(var e in this){
                 o[e] = typeof this[e] === "object" ? <span style="color:#cc0000;">this[e].clone()</span> : this[e];
         }
         return o;
}

方法二:使用argument.callee

 Object.prototype.clone = function(){
         var o = this.constructor === Array ? [] : {};
         for(var e in this){
                 o[e] = typeof this[e] === "object" ? arguments.callee(this[e]) : this[e];
         }
         return o;
}

方法三:

  function clone(Obj) {   
         var buf;   
         if (Obj instanceof Array) {   
             buf = [];                    //创建一个空的数组 
             var i = Obj.length;   
             while (i--) {   
                 buf[i] = clone(Obj[i]);   
             }   
             return buf;    
         }else if (Obj instanceof Object){   
             buf = {};                   //创建一个空对象 
             for (var k in Obj) {           //为这个对象添加新的属性 
                 buf[k] = clone(Obj[k]);   
            }   
            return buf;   
         }else{                         //普通变量直接赋值
             return Obj;   
         }   
     }

//2016.4.22未完待续












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值