原始数据
基本数据类型是一种即非对象也无方法的数据。JS中有6中基本类型:string
、number
、boolean
、undefined
、symbol
。
多数情况下,基本类型直接代表了最底层的语言实现。
基本类型的值都是不可变
示例1
// 使用字符串的方法不会改变一个字符串 let bar = 'abcd'; console.log(bar); // abcd // 赋值行为可以给一个基本类型一个新值,而不是改变原来的值 let bar1 = bar.toUpperCase() console.log(bar1); // ABCD console.log(bar); // abcd // 使用一个数组的方法可以改变数组 let foo = [] console.log(foo); // [] foo.push('plugh') console.log(foo); // [ 'plugh' ]
// 定义基本类型 let foo = 5; // 定义一个方法 function addTwo(num) { // 本地num参数 num += 2; } function addTwo_v2(foo) { // 本地foo参数 foo += 2 } // 调用第一个函数,并传入基本类型作为参数 addTwo(foo) console.log(foo); // 5 // 调用第二个方法 addTwo_v2(foo) console.log(foo); // 5
将基本数据作为方法的入参,并没有将这个原始数据作为入参,而是将这个原始数据复制了一份,创建一个本地副本作为每个方法的入参。
综上所述,函数中的任何操作都不会影响到最初的foo,我们操作的只不过是它的副本。
JavaScript 中的基本类型包装对象
除了 null
和 undefined
之外,所有基本类型都有其对应的包装对象:
这个包裹对象的valueOf()
方法返回基本类型值。
Object.prototype.valueOf()
valueOf()
方法返回指定对象的原始值。
MDN对valueOf()的描述
JavaScript调用valueOf
方法将对象转换为原始值。你很少需要自己调用valueOf
方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。
默认情况下,valueOf
JavaScript的许多内置对象都重写了该函数,以实现更适合自身的功能需要。因此,不同类型对象的valueOf()方法的返回值和返回值类型均可能不同。
// Array:返回数组对象本身 var array = ["ABC", true, 12, -5]; console.log(array.valueOf() === array); // true // Date:当前时间距1970年1月1日午夜的毫秒数 var date = new Date(2013, 7, 18, 23, 11, 59, 230); console.log(date.valueOf()); // 1376838719230 // Number:返回数字值 var num = 15.26540; console.log(num.valueOf()); // 15.2654 // 布尔:返回布尔值true或false var bool = true; console.log(bool.valueOf() === bool); // true // new一个Boolean对象 var newBool = new Boolean(true); // valueOf()返回的是true,两者的值相等 console.log(newBool.valueOf() == newBool); // true // 但是不全等,两者类型不相等,前者是boolean类型,后者是object类型 console.log(newBool.valueOf() === newBool); // false // Function:返回函数本身 function foo(){} console.log( foo.valueOf() === foo ); // true var foo2 = new Function("x", "y", "return x + y;"); console.log( foo2.valueOf() ); /* ƒ anonymous(x,y ) { return x + y; } */ // Object:返回对象本身 var obj = {name: "张三", age: 18}; console.log( obj.valueOf() === obj ); // true // String:返回字符串值 var str = "http://www.xyz.com"; console.log( str.valueOf() === str ); // true // new一个字符串对象 var str2 = new String("http://www.xyz.com"); // 两者的值相等,但不全等,因为类型不同,前者为string类型,后者为object类型 console.log( str2.valueOf() === str2 ); // false
toString()
Boolean.prototype.toString()
toString()
方法返回指定的布尔对象的字符串形式。
let flag = new Boolean(true); console.log(flag.toString()) // true let flag1 = new Boolean(1); console.log(flag1.toString()) // true
Array.prototype.toString()
toString()
let array = ['abc', true, 12, undefined, 'ok'] console.log(array.toString()); // abc,true,12,,ok
Function.prototype.toString()
toString()
function fun(num) { num += 5 } console.log(fun.toString()); /** * function fun(num) { num += 5 } */
Object.prototype.toString()
toString()
let obj = { name: 'houfee'} console.log(obj.toString()); // [object Object]
let a={name:123}; console.log(Number(a)); // NaN /* * JS对象强制类型转换 * 主要调用 object.valueOf() 和 object.toString() 方法 * 1.先调用 object 的 valueOf() 方法 * 2.判断返回值 是否为 基础数据类型? * 3.是!则转换规则按照相应数据类型的规则对其进行转换 * 4.不是!在返回值的基础上继续调用 toString() 方法 * 5.判断调用 toString() 方法返回值是否为 基础数据类型 * 6.是!则转换规则按照相应数据类型的规则对其进行转换 * 7.不是!报错: * */
a.toString = function () {return {name: 'newName'}} // 让toString方法返回值为 复杂数据类型 a.toString() // 调用覆盖的方法 Number(a) // 报错
现在验证让toString方法返回值为 基础数据类型
a.toString = function () {return '321'} // 让toString方法返回值为 复杂数据类型 a.toString() // 调用覆盖的方法 Number(a) // 321
所以Number强制转换对象的过程即为如上7步
let b = {name: 'houfee'} console.log(String(b)); // [object Object] let c = [] console.log(String(c)); // 空字符串 let d = {} console.log(String(d)); // [object Object]
1.先调用对象的toString方法
3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换
4.若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法
5.判断valueOf的返回值是否为基础数据类型
6.判断是否为基础数据类型,若是基础数据类型则进行操作3
7.若仍旧不为基础数据类型则报错
String与Number的区别则在于
-
Number是先调用valueOf再调用toString
-
而String是先调用toString再调用valueOf
Boolean强制转换对象
转换为false
的有
面试题
console.log({}); // {} console.log(Number({})); // NaN、 console.log(String({})); // [object Object] console.log(Boolean({})); // true console.log([]); // [] console.log(Number([])); // 0 console.log(String([])); // 空字符串 console.log(Boolean([])); // true console.log({} + {}) // [object Object][object Object] console.log({} + []) // [object Object] console.log([] + {}) // [object Object] console.log([] + []) // 空字符串