竹笋

首页 » 问答 » 问答 » Web前端面试题类型转换的原理是什么开
TUhjnbcbe - 2023/1/4 9:43:00
Web前端面试题及答案

问题:类型转换的原理是什么?

解析:类型转换指的是将种类型转换为另种类型,例如:

varb=2;

vara=String(b);

console.log(typeofa);//string

当然,类型转换分为显式和隐式,但是不管是隐式转换还是显式转换,都会遵循定的原理,由于JavaScript是动态类型的语,可以随时赋予任意值,但是各种运算符或条件判断中是需要特定类型的,因此JavaScript引擎会在运算时为变量设定类型.

这看起来很美好,JavaScript引擎帮我们搞定了类型的问题,但是引擎毕竟不是ASI(超级智能),它的很多动作会跟我们预期相去甚远,我们可以从到试题开始.

{}+[]//0

答案是0

是什么原因造成了上述结果呢?那么我们得从ECMA-中提到的转换规则和抽象操作说起。

这是JavaScript种类型转换可以从原始类型转为引类型,同样可以将引类型转为原始类型,转为原始类型的抽象操作为ToPrimitive,后续更加细分的操作为:ToNumberToStringToBoolean。

为了更深的探究JavaScript引擎是如何处理代码中类型转换问题的,就需要看ECMA-详细的规范,从探究其内部原理,我们从这段内部原理示意代码开始.

//ECMA-,section9.1,page30.Usenull/undefinedfornohint,

//(1)fornumberhint,and(2)forstringhint.

functionToPrimitive(x,hint){

//Fastcasecheck.

if(IS_STRING(x))returnx;

//Normalbehavior.

if(!IS_SPEC_OBJECT(x))returnx;

if(IS_SYMBOL_WRAPPER(x))throwMakeTypeError(kSymbolToPrimitive);

if(hint==NO_HINT)hint=(IS_DATE(x))?STRING_HINT:NUMBER_HINT;

return(hint==NUMBER_HINT)?DefaultNumber(x):DefaultString(x);

}

//ECMA-,section8.6.2.6,page28.

functionDefaultNumber(x){

if(!IS_SYMBOL_WRAPPER(x)){

varvalueOf=x.valueOf;

if(IS_SPEC_FUNCTION(valueOf)){

varv=%_CallFunction(x,valueOf);

if(IsPrimitive(v))returnv;

}

vartoString=x.toString;

if(IS_SPEC_FUNCTION(toString)){

vars=%_CallFunction(x,toString);

if(IsPrimitive(s))returns;

}

}

throwMakeTypeError(kCannotConvertToPrimitive);

}

//ECMA-,section8.6.2.6,page28.

functionDefaultString(x){

if(!IS_SYMBOL_WRAPPER(x)){

vartoString=x.toString;

if(IS_SPEC_FUNCTION(toString)){

vars=%_CallFunction(x,toString);

if(IsPrimitive(s))returns;

}

varvalueOf=x.valueOf;

if(IS_SPEC_FUNCTION(valueOf)){

varv=%_CallFunction(x,valueOf);

if(IsPrimitive(v))returnv;

}

}

throwMakeTypeError(kCannotConvertToPrimitive);

}

上代码的逻辑是这样的:

1.如果变量为字符串,直接返回.

2.如果!IS_SPEC_OBJECT(x),直接返回.

3.如果IS_SYMBOL_WRAPPER(x),则抛出异常.

4.否则会根据传的hint来调DefaultNumber和DefaultString,如如果为Date对象,会调DefaultString.

5.DefaultNumber:先x.valueOf,如果为primitive,则返回valueOf后的值,否则继续调x.toString,如果为primitive,则返回toString后的值,否则抛出异常

6.DefaultString:和DefaultNumber正好相反,先调toString,如果不是primitive再调valueOf.

那讲了实现原理,这个ToPrimitive有什么呢?实际很多操作会调ToPrimitive,如加、相等或较操。在进加操作时会将左右操作数转换为primitive,然后进相加。

下来个实例,({})+1(将{}放在括号中是为了内核将其认为个代码块)会输出啥?可能常写代码并不会这样写,不过上出过类似的试题。

加操作只有左右运算符同时为String或Number时会执对应的%_StringAdd或%NumberAdd,下看下({})+1内部会经过哪些步骤:

{}和1先会调ToPrimitive{}会到DefaultNumber,先会调valueOf,返回的是,不是primitive类型,从继续到toString,返回[objectObject],是String类型最后加操作,结果为[objectObject]1再如有问你[]+1输出啥时,你可能知道应该怎么去计算了,先对[]调ToPrimitive,返回空字符串,最后结果为1。

1
查看完整版本: Web前端面试题类型转换的原理是什么开