Js隐类型转换

今天关于一个valueOf和toString方法在我们的对象里面有这个属性。这两个方法我们先不讲要说一个对象里的属性
我是这样做的:
var s = new Number(9)
undefined
s
Number {9}proto: Number
这是内置对象Number之后可以得到里面的属性[[PrimitiveValue]]: 9
这个属性就是我们已经知道的和valueOf方法相关的一个值,根据这个值我们来判断是调用这些方法注意只有对象类型的里面才有这个属性基本数据类型里var s = 9并没有这个属性。
这回进入主题:首先我们要知道这个方法是在object的里面才有然后查了一下MDN
wrapper 对象:
Primitive wrapper objects in JavaScript

Except for null and undefined, all primitive values have object equivalents that wrap around the primitive values:

String for the string primitive.
Number for the number primitive.
Boolean for the Boolean primitive.
Symbol for the Symbol primitive.
他们的valueOf方法会返回他们的 primitive value
The wrapper’s valueOf() method returns the primitive value.
就是说一个var s = ‘123’
相当于建立了一个String对象这时候使用里面的valueOf自动调用的会发现里面的[[PrimitiveValue]]: ‘123’作为自己的这个属性值
所以隐式类型转换时候这些作为原始值的类型来判断转化
来自Mdn:
JavaScript调用valueOf方法将对象转换为原始值。很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

默认情况下,valueOf方法由Object后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则valueOf将返回对象本身。
因为原始值这个属性在String Number Boolean Symbol中有这个属性。在进行隐式转换类型。所以就是说在转换的时候遵循的原则。
function MyNumberType() {
return 12;
}

MyNumberType.valueOf = function() {
return 90;
};

console.log(MyNumberType + 3);
// expected output: 93
这个就是我们的输出因为会输出结果转换类型因为这个valueOf就会JS自动调用,而且一些类型通过改写这个方法实现自己的功能当然调用的时候都是js调用的。
那么这个呢就会输出93,因为是对象类型所以转化的时候就会有优先执行value Of 如果不满足再执行toString
function MyNumberType() {
return 12;
}

MyNumberType.valueOf = function() {
return 90;
};

MyNumberType.toString = function() {
return 100;
};

console.log(MyNumberType + 3);
//93
其实突然很想扯一句初始值的问题在MDN上刚看到特意来说说:
来自知乎:https://zhuanlan.zhihu.com/p/29064256?utm_medium=social&utm_member=NDQ5OGFhYmNhMDdhODNhODFhMmZhMzM5YzU1MmRhZWY%3D&utm_source=qq
原始值类型在在我们的有 6 primitive data types: string, number, boolean, null, undefined, symbol
来自segmentsfault:https://segmentfault.com/a/1190000007536949
所以在我们进行运算的时候就会来转换成这些类型进行计算这就是隐式转换。
这就是为什么我们在console的时候会输出字符串,加法计算的时候会进行转化成对应形式。所有计算都是最终会转化成这些原始类型的

补充:Javascript有两种基本数据类型,Primitive和Object。Object是properties的聚合,其property可以是Object也可以是Primitive。Primitive只有value, 没有properties。
除了null和undefined,其余Primitive都有对应的Object封装,如Object String对应string。在MDN上原始类型是不可以转变的一段代码

var s = 'w'
undefined
s.toLocaleUpperCase()
"W"
console.log(s)
//w
就是说我们的变量s 并没有改变这也就是为什么初始值是传递值调用的,就是在栈里重新建立了一个变量返回的是一个新的变量,这里补充一下javascript的参数传递都是按照值来传递只不过对象的引用拷贝的是同一份对象地址值,所以看起来像是引用传参,实际上利用引用在创建一个对象就发现并没有返回新的对象,这就是传值的原因,如果是引用就会返回新的对象。

还是回来说基本数据类型在我们的基本数据类型中有一个wrapper概念就是说为什么一个普通的


var s1 = "helloworld";
var s2 = s1.substr(4);
一个基本类型可以调用这个方法基本数据类型不是不可以添加属性的吗?
ECMAScript还提供了三个特殊的引用类型Boolean,String,Number.我们称这三个特殊的引用类型为基本包装类型,也叫包装对象.

也就是说当读取string,boolean和number这三个基本数据类型的时候,后台就会创建一个对应的基本包装类型对象,从而让我们能够调用一些方法来操作这些数据.

所以当第二行代码访问s1的时候,后台会自动完成下列操作:

  1. 创建String类型的一个实例;// var s1 = new String(“helloworld”);
  2. 在实例上调用指定方法;// var s2 = s1.substr(4);
  3. 销毁这个实例;// s1 = null;
    所以说这就是wrapper的作用。
    这个包装类型对像会在瞬间消灭掉。
    所以说这也是为什么我们的基本类型可以调用一些方法的原因,也是今天隐式转化的在一开始我们说进行一些运算的时候就会发现把某些类型转化成基本类型进行计算
    ToPrimitive
    来自知乎:
    在比较运算与加法运算中,都会涉及到将运算符两侧的操作对象转化为原始对象的步骤;而 JavaScript 中这种转化实际上都是由 ToPrimitive 函数执行的。实际上,当某个对象出现在了需要原始类型才能进行操作的上下文时,JavaScript 会自动调用 ToPrimitive 函数将对象转化为原始类型;譬如上文介绍的 alert 函数、数学运算符、作为对象的键都是典型场景。
    所以就是说我们需要转化成原始类型进行计算。
    就是在比较符号的两个值会进行ToPrimitive这个函数的转化,转化规则如下:
    如果两端的操作都是原始值则不转化,
    如果一个存在是对象类型优先执行valueOf然后不通过再执行toString方法
    如果是一个日期对象优先执行toString在执行valueOf函数所以就有
    var s = new Date()
    undefined
    s
    Wed Apr 25 2018 15:03:39 GMT+0800 (CST)
    s.valueOf()
    1524639819112测试确实如此
    所以说这就是为什么上边那个函数调用tostring和valueOf只是执行valueOF因为优先执行 valueOF对象优先valueOf. 不通过(不是基本类型)再执行tostring。只有date类型在自动转化先执行tostring再是valueof就像我们打印出来的一样。
    其实我的初衷不过是因为自动调用这两个方法来改变函数的返回值进行符号的运算。是因为一道面试题引发的种种联系。
    add(1)(9)(8)就是这个面试题啊
    现在可以说这个面试题了首先可以看见这个是可以无限添加参数的进行运算所以一定会有一个函数被一直调用。
    我们可以设计一个两层函数
    function addOut(…arg){
    var list = arg.slice();
    var adder = function(..args){
    list = […list, …args];

}
adder.valueOf = function() {
return
}
return adder
}

猜你喜欢

转载自blog.csdn.net/qq_32798243/article/details/80146881