JS高级学习笔记(1)- 基本数据类型

 

 

 

原始数据

基本数据类型是一种即非对象也无方法的数据。JS中有6中基本类型:stringnumberbooleanundefinedsymbol

多数情况下,基本类型直接代表了最底层的语言实现。

基本类型的值都是不可变的。注意,基本类型本身和被赋值为基本类型的变量区别,变量可以被赋予一个新值,二原值不能像数组、对象以及函数那样被改变。

示例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' ]

示例2

// 定义基本类型
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

将基本数据作为方法的入参,并没有将这个原始数据作为入参,而是将这个原始数据复制了一份,创建一个本地副本作为每个方法的入参。

并且,这个复制的副本只存在于该函数的作用域中,我们能够通过指定在函数中的标识符访问到它(addTwo中的num,addTwo_v2中的foo)。

综上所述,函数中的任何操作都不会影响到最初的foo,我们操作的只不过是它的副本。

JavaScript 中的基本类型包装对象

除了 nullundefined之外,所有基本类型都有其对应的包装对象:

  • String 为字符串基本类型。

  • Number 为数值基本类型。

  • Boolean 为布尔基本类型。

  • Symbol 为字面量基本类型。

这个包裹对象的valueOf()方法返回基本类型值。

Object.prototype.valueOf()

valueOf() 方法返回指定对象的原始值。

MDN对valueOf()的描述

JavaScript调用valueOf方法将对象转换为原始值。你很少需要自己调用valueOf方法;当遇到要预期的原始值的对象时,JavaScript会自动调用它。

默认情况下,valueOf方法由Object后面的每个对象继承。 每个内置的核心对象都会覆盖此方法以返回适当的值。如果对象没有原始值,则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]

Number强制转换对象

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.不是!报错:
     * */

 现在我们用自定义方法覆盖toString()方法:

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步

String()强制转换对象

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方法

2.判断该方法的返回值是否为基础数据类型(Number,String,Boolean,Undefined,Null)

3.若返回值为基础数据类型,则转换规则按照相应数据类型的转换规则对其进行转换

4.若返回值不为基础数据类型,则在该返回值的基础上继续调用valueOf方法

5.判断valueOf的返回值是否为基础数据类型

6.判断是否为基础数据类型,若是基础数据类型则进行操作3

7.若仍旧不为基础数据类型则报错

 

String与Number的区别则在于

  • Number是先调用valueOf再调用toString

  • 而String是先调用toString再调用valueOf

Boolean强制转换对象

转换为false的有undefined、null、''、0、NaN

面试题

    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([] + []) // 空字符串

猜你喜欢

转载自www.cnblogs.com/houfee/p/10393843.html