【☆】javascript数据类型拾遗

时间:2023-12-09 18:53:49

一、Array对象

1.两个数组能用< > == ===做比较吗?

答:数组可以用> <进行矩阵比较,比如a=[1,2,3] b=[1,2,4],那么a<b,如果a的数值长度增加,比如a=[1,2,3,1],那么结果还是a<b。而如果数组的长短和数据项大小都相同,那么ab怎么比较都是false。

所以我们可以知道数组的比较规则:从索引0开始,只要二者比较出结果,即停止比较,返回比较结果。

2.两个空数组相等吗?[]==[]?

答:不相等,等同于两个空对象比较,有法比较吗?所以false。

3.变态使用数组的方法:x=array.sort;【任意方法名】x();会产生什么效果?

答:只能是报错。

4.变态数组[,,]的长度?现有成员数目?join('1')会显示什么?

答:数组将,号的解析undefined,长度也是undefined,但是成员却是两个undefined,join('1')会显示 1 。

5.给数组元素变态的加上一对[],比如[[[[1]]]],它和数值1是什么关系?

答:不论加多少[],都是换汤不换药,1还是1,所以1==[[[[1]]]]

6.如何对字符数组进行降序排序?

答:sort方法中的function参数的返回值指定排序方式,如果返回的两个参数差值是大于零的升序拍,等于0并排。小于零降序排。所以我们只需稍微修改sort的两个参数的表现形式,变成function(a,b){return a.charCodeAt(0)-b.charCodeAt(0);}就可以了。

二、Number类型

1.var x=1,x.toString()和1.toString()有什么区别?

答:前者输出1,后者错误,因为数值没有toString()方法。

2.如果非想用一个数值调用toString方法怎么办?

答:用1..toString();

3.问题2多点几个点行不?

答:就只能俩点,多了不行!

4.parseInt('011')会得到什么?

答:在ECMAScript3浏览器下(IE8以下老版本)会输出9,因为parseInt遇见0或0x会把字符串当成八、十六进制解析,而ECMAScript5却不支持8进制,直接输出11,但是还没有放弃16进制。

三、RegExp对象

1.正则对象有哪三种有用的方法?

答:reg.test(string):检测目标字符串是否含有正则表达式的内容,如果有则返回true,否则false。

reg.exec(string):检测目标字符串是否含有正则表达式匹配的内容,如果有则返回匹配到的字符串,没有返回"".

reg.complie(regExp):将reg的正则表达式改变为regExp。返回值是替换后的正则表达式。

2.正则表达式的test(null) 和 test(),二者匹配的项是什么?

答:test:返回值为布尔,如果匹配成功返回true。exec:返回匹配成功的字符串。complie:返回值为正则表达式,用途是更换当前正则对象的匹配内容。

正则表达式的test 方法会把 null看成字符串"null",而空则被看成"undefined". 相似的方法是:exec 。但是complie方法比较特殊,对于null和其他方法处理一致,但是当为undefined时,就变成了 /(?:)/,很奇特。

四、Function对象

1.你不知道的function对象的默认属性。

答:有一个name属性是函数对象特有的,值就是函数名,如果是匿名函数,这个值就是"",而如果该函数对象时通过new Function()出来的,默认值是"anonymous"--匿名的

2.当我eval一个函数名的时候会发生什么?

答:会将该函数的函数体整出来,但是该函数不会执行。typeof这个eval会告诉你这是一个 function;如果eval的是一个匿名函数名,即eval(),那么会返回undefined。

3.如果我给函数的name属性赋值,结果会是怎样?

答:name属性是只读的,不能赋值!

4.function定义函数和new Function生成函数对象有什么区别?

答:其实二者在实现功能方面没什么区别,区别在于闭包上。function声明函数如果在一个函数体内,则会形成闭包,而new Function则不会形成闭包。

5.如果我的函数名和变量名重复了,怎么办?

答:这得分情况。

如果我的变量声明了但是没有赋值,那么以函数名为准。不管谁先声明。

如果我的变量声明了也赋了具体的值,那么以变量为准,不管谁先声明。

五、Object类型

1.ECMAScript5新增特性Object.getPrototypeOf([object]) 会返回什么?

答:其实就是得到该参数的__proto__这个指针所指向的内容。

可以知道如下等式:[object].__proto__=[object].constructor.prototype=Object.getPrototypeOf([object])

                               [object].constructor=[object].constructor.prototype.constructor

2.一个function的constructor.prototype和一个变量的constructor.prototype是什么?

答:前者是一个空函数

后者根据不同的数据类型会有不同。

自定义对象:[object object]

RegExp对象://

Number对象:0

Array和String:空

null和undefined:报错

3.如何对对象进行深度克隆?(不是有cloneNode方法么为什么还要?cloneNode是克隆节点的呀笨蛋!)

答:思路是这样的,a.先找到待克隆对象的constructor指向,这样就找到了创建该对象的父类。

b.有了父类对于普通对象来说New就可以了。可是如果待克隆对象是Date Array String Number的话,我们得不到它的默认值,所以针对这三类我们还要在构造时把待克隆对象的valueOf()传进去。 而另一种对象json就更为复杂,即时new constructor也不能满足深度克隆,需要使用ECMAScript5定义的下列方法:s = JSON.stringify(obj), //系列化对象 newobj = JSON.parse(s); //反系列化(还原)

c.做好了这些一个支持IE8以上及其他新版本浏览器的对象深度克隆就可以了。

        function cloneObject(obj) {
if (!obj.valueOf()) {
var cstr = new obj.constructor();
}
else if(window.JSON) {
var s = JSON.stringify(obj);
var cstr = JSON.parse(s);
for (var item in obj) {
cstr[item] = obj[item];
}
}
else {
cstr = new obj.constructor(obj.valueOf());
}
return cstr;
}

 4.如何实现ECMAScript5的Object的create方法?

答:Object.create有两个参数,第一个是某类的原型。第二个是属性,可选。方法返回一个对象。因此我们可以通过下面的代码实现这一方法:

Object.prototype.create=function(objProto,jsonpro){
function XClass(){}
XClass=objProto.constructor;
var obj=new XClass();
if(jsonpro) {
for(var item in jsonpro){
obj[item]=jsonpro[item];
}
}
return obj;
}

5.obj.prototype.sayname=function(){}和obj.prototype={sayname:function(){}}有什么区别吗?

答:前者的原型constructor指向obj,而后者原型的constructor则指向了Object。

6.ECMAScript5下一个对象如何防篡改?有哪些级别?

答:使用Object.preventExtensions(obj)这种方法。对象被防篡改后就不会再被随意增加属性,但可以修改删除属性。

使用Object.seal(obj)方法,对象被防篡改之后就不可以删除属性,但是可以更改。

使用Object.freeze(obj)方法,对象不可以删除不可以修改。

7.遇到如下这种变态的操作,会得出什么结果呢?

function foo(){
// => 执行顺序3:foo.abc => alert(1)
foo.abc = function () {
alert(1);
};
// => 执行顺序4:obj.abc => alert(2)
this.abc = function () {
alert(2);
};
// => 执行顺序5:window.abc => alert(3)
abc = function () {
alert(3);
};
// => 执行顺序6:局部变量 var abc = alert(4)
var abc = function () {
alert(4);
};
}
// => 执行顺序1:obj.abc => alert(5)
foo.prototype.abc = function () {
alert(5);
};
// => 执行顺序2:foo.abc => alert(6)被foo对象实例化过程中产生的abc覆盖
foo.abc = function () {
alert(6);
};
var obj = new foo();
obj.abc();
foo.abc();

这个问题涉及到的知识点:

使用方法优先在对象自身上找,如果没有就在原型链上找,如果自身和原型链有冲突,使用自身的方法。

最后编译的函数会覆盖前面定义的函数

obj 是 foo 构造函数的实例对象,在调用 abc 方法时会优先查找实例方法,如果找不到 abc 实例方法,就会去原型链上继续搜索是否存在名为 abc 的方法,直到原型链的顶端。本例中存在实例方法,所以返回值为 2.

foo.abc() 为什么不是 6 呢?因为在实例化 foo 构造函数时,其函数中的 foo.abc 声明覆盖了后面的声明,所以返回值是 1

8.给call方法传入null或undefined会有什么结果?

答:会把this对象变为window。

 六、String对象

1.字符串中出现转义字符'\'怎么办?

答:看转义后的内容是什么,如果只是\n啥的长度会比眼见的缩减1.

2.类似这种var str = '\u104A0';这个str的长度是多少?

答:是2,不要忽视转义字符啊,一般情况下,有'\'出现,字符串的长度就比眼看到的要小。题目输出的结果是这样的:၊0,这个方块就是\u104a

3.有什么最简单的将 纯数字型 字符串转为数字的方法么?

答:javascript中如果想要把字符串转变为数字,最好的方法还是用parseInt吧。不过最简单的方法就是 比如var s="12" ; +s就是12这个数字。如果s中含有非数字字符,那么得到的就是NaN。

X.其他

1.乱使用关键字的后果:a={class:'一班',name:'jack'}; a.class是什么?

答:根据浏览器的不同,效果也不同,在FF下(其他浏览器好像和FF一致),会输出一班,而在IE8会报错。

2.对undefined赋值会有什么效果?对undefined typeof将获得什么?

答:对undefined赋值听起来很疯狂,可是在IE8下偏偏就成功了。undefined的typeof是undefined.

3.如果另a为window,那么a.a==a返回什么?

答,这不就是一个循环么,window的window属性不还是为window么。所以返回true。

5.如果遇到如下情况,得到的结果是什么?

if (!("a" in window)) {
var a = 1;
}
alert(a);

答:输出undefined,因为javascript引擎在初始化的时候,会把变量声明(而不是赋值)在其所在的作用域提前置顶。

6.如果给一个已赋值变量赋值为一个无返回值的函数执行体,那这个值变为什么?

答:变为undefined,这是自动返回的。