JavaScript数据类型及语言基础
1.如何判断一个变量是否是数组、函数
typeof 操作符
typeof操作符是ECMAScript提供涌来做数据类型检测的操作符,使用typeof操作符会返回 undefined, boolean, string, number, object, function 这几种类型,对于数组,正则表达式,日期类型甚至是null返回的都是object, 用它来检测有点不靠谱。
instanceof 操作符
因为typeof不给力只能测测数值,字符串,instanceof就闪亮登场了,它可以检测一个变量是否是特定“对象”的实例,它是通过原型链来实现的,也就是说你可以通过修改原型链的方式来改变它的结果。所以对于不在同一个域的两个变量身处不同的原型链,就无法通过它来判断。
检测的黑魔法
我们可以使用一个对象所特有的东西来检测。利用Object.prototype.toString.call(obj) === ‘[object Array]’;这个可以来检测是否是数组,原因是对数组对象调用Object原型上的toString方法可以得到这个唯一的结果,调用Object原型上的方法是因为obj的toString可能被改写了
ECMAScript5
ECMAScript 5 新增了Array.isArray()方法。这个方法的目的是最终确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。
那么函数呢
函数可以直接用typeof吗?很遗憾。在Safari 5 及之前版本和Chrome 7 及之前版本中使用typeof 检测正则表达式时,由于规范的原因,这个操作符也返回”function”。ECMA-262 规定任何在内部实现[[Call]]方法的对象都应该在应用typeof 操作符时返回”function”。由于上述浏览器中的正则表达式也实现了这个方法,因此对正则表达式应用typeof 会返回”function”。在IE 和Firefox 中,对正则表达式应用typeof 会返回”object”。
所以我们要开发新的办法了,按照黑魔法我们使用它独有的东西就可以判断出来,但是坑爹的是他没有独有的东西啊。DOM节点也叫function!我们只能将那些都排除了,有nodeName属性的是DOM节点,constructor是String,RegExp, Array的是字符串,正则表达式,数组!将他们都排除
2.深拷贝
在JavaScript中数组,对象都是引用类型,所以不同变量用=赋值得到的是同一个变量的引用。所以在数组和对象的拷贝时候需要用到深拷贝。将对象,数组中的值一个个赋值。
3.数组去重
思路是便利整个数组,如果新数组没有当前值,那么将当前值push到新数组中,否则就跳过。这应该是最简单的方法了吧,如果要降低时间复杂度可以用上hash。
4.trim实现
jQuery最初的版本实现方法是匹配头部的空格字符使用正则表达式/^\s+/,匹配尾部的空格字符/\s+$/,然后用replace将字符中的空格替代掉。
5.正则表达式
正则表达式是很难的,只能说正则表达式需要不断的练习,不断的理解!
6.DOM类操作
增加类名,移除类名,很简单,就是测试节点的className属性中是否存在这个类名,然后进行增加和移除的操作。使用正则表达式/(^||\s+)className(\s||$)/, 这里className是个变量所以不能用正则表达式字面量的方法来赋值,要使用构造函数,使用构造函数要对\进行转义。
7.DOM元素选择操作
首先利用正则表达式先检测出选择器类型,然后对应的进行操作。元素选择器,id选择器比较简单可以直接进行系统调用。这里要注意的是类选择器和属性选择器,要使用document.getElementsBytagName(‘*’)将所有节点选出来,查找元素是否有对应的类(利用之前的DOM类操作),或者是属性(利用getAttribute方法)
8.DOM事件
JS与HTML的交互是通过事件的侦听实现的。有几个核心概念需要理解。事件冒泡,事件开始时是由最具体的元素接收,然后逐级向上传输到不那么具体的节点。事件捕获,正好相反,是从不那么具体的节点更早接收到事件。DOM2级事件规定的事件流包括三个阶段事件捕获阶段,处于目标阶段,冒泡阶段。
DOM0级事件处理程序: onclick等等,这种方式指定不能接收多个处理事件。DOM2级处理事件addEventListener,可以接收多个事件并且确定是在冒泡阶段或是捕获阶段处理事件。默认是false,冒泡阶段!可以使用removeEventListener来移除响应。在IE中使用的是类似的方法attachEvent和detachEvent。
事件代理的概念,使用apply函数可以进行代理的操作。事件代理利用了冒泡,指定一个处理程序管理某一类型的所有事件!
9.判断IE浏览器
可以使用navigator.userAgent属性,这是一个字符串,如果包含了MSIE: 10.0; 这样的字符串就说明是IE浏览器,并且版本号为10.0.这里就可以使用正则表达式/MSIE ([^;]+)/来测试并且捕捉出版本号。 IE11中不能用这个办法,因为IE11这个属性中不包含MSIE这个字符串了,需要用其他办法来测试。可以使用IE特有的属性和方法进行测试。
10.cookie
是在客户端用于存储会话信息的。cookie由名字,值,域,路径,失效时间,安全标志组成。在Javascript中使用cookie用的是document.cookie这个接口。设置document.cookie并不会删除其他的cookie。删除cookie是将失效时间设置为一个过去的值。name,value需要通过encodeURIComponent来编码,失效时间要使用toGMTString来标准化时间变量。
11.Ajax
使用XMLHttpRequest来实现Ajax。XHR的用法,首先是要open,它接受三个参数,发送请求的类型(GET,POST,PUT,DELETE),请求的URL以及是否异步发送请求的bool值。随后调用send方法,将作为请求主体发送的数据发送出去。然后等待接收响应。在异步发送的情况下,通过检测Xhr对象的readyState属性。这个属性有5个值0:未初始化,尚未调用open。1:调用了open但是没有调用send。2:调用了send但是还没收到响应。3:收到响应了,但是没有收到全部响应。4:收到了全部响应。 随后检测xhr对象的status属性来检测响应状态码。可以利用xhr.abort()取消异步请求。