看不懂的隐式转换(上)--- 基础铺垫

前言

看不懂系列 [滑稽.jpg] 最近在找工做,后面的博客内容也算本身的准备了,嘿嘿 其实本身日常看书的时候,也会发现不少东西讲的太官话,有点看不懂 有些资料呢,可能又将的太碎片化了, 因此我常常把书上知识点当作一个扩散点,去扩展一些原来不知道的 像这篇,其实讲隐式转换的文章仍是比较多,好的也比较多的 但可能我过小白了,有些一笔带过的内容好比说,原始值,引用值,toString,valueOf这些一笔带过 因此在讲以前先铺垫铺垫 讲些原理 PS: 小白一个 欢迎吐槽 嘿嘿嘿git

原始值和引用值

原始值

存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。github

Undefined、Null、Boolean、Number 和 String 因为这些原始类型占据的空间是固定的,因此可将他们存储在较小的内存区域 - 栈中。这样存储便于迅速查寻变量的值。bash

引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。函数

object,Array , 函数spa

存储在变量处的值是一个指针(point),指向存储对象的内存处。.net

var a = "i am string";
typeof a; // "string"
a instanceof String  //false

var b = new String("i am a string");
typeof b; // "object"
b instanceof String  //true
复制代码

WTF ???prototype

WHY ???翻译

一开始看这道题的时候满脸问号指针

其实吧 这是由于 "i am string" 他是一个原始值code

But

"i am string".length // 8  这些本属于String的方法却能被调用
复制代码

这是应为在必要时。js语言会把字符串字面量转换成String对象。也就是你并不须要显示的建立一个对象valueOf()

toString valueOf()

toString 使用方法

var x = {};
console.log(x.toString());           
//  [object Object]

//特别的用法
toString.call(new Date); // [object Date]
toString.call(new String); // [object String]
toString.call(Math); // [object Math]
toString.call(undefined); // [object Undefined]
toString.call(null); // [object Null]

var x = [1,2,3];
x.toString(); //返回'1,2,3'

var x = function(){console.log('lalala')}
x.toString();// 返回'function(){console.log('lalala')}'

var x = 33333;
x.toString();// 返回'33333'
复制代码

网上copy的一段示例,接下来详细了解一下toString()经常使用语法

obj.toString();

这种使用形式能够把除null undefined外,全部对象转为字符串

//boolean类型
true.toString()  //true
false.toString()  // false
//string类型
var str = "stringlalala"
str.toString()  //"stringlalala"
复制代码

可是下面出现了一个很是好玩的现象

// Object
var obj = {
    name: "MrZss",
    age: "23"
};
obj.toString(); //[object Object]

// Array
var arr = ["MrZss","23"];
arr.toString();  // "MrZss","23"

//Date
var date = new Date();//
date.toString() //   Wed Feb 27 2019 13:46:35 GMT+0800 (CST)

// Number 
var num = 23;
var num = 23;
console.log(num.toString(2)); //10111 二进制
console.log(num.toString(8)); //27 八进制
console.log(num.toString(16)); //17 十六进制
复制代码

问题来了 按理来讲 Array Date这些对象toString方法 都是从Object对象继承来的呀。为何表现彻底不同

友情提醒:Array,RegExp,Date,Number等内置对象中的toString重写了,用于自己的类型转化

MDN参考

Object.prototype.toString()

来来来 敲黑板画重点了

ES6规范描述

实在不行就一键翻译吧 [滑稽.jpg]

这一块我也去搜了搜大佬的资料,看这个理解的比较详细

Object.prototype.toString()

因此,可使用Object.prototype上的原生toString()方法判断数据类型

由于其余对象例如Array,Date的toString方法都没覆盖了 因此仍是须要使用

Object.prototype.toString.call(value) 来调取

Object.prototype.toString.call(null);//”[object Null]”
Object.prototype.toString.call(undefined);//”[object Undefined]”
Object.prototype.toString.call(“abc”);//”[object String]”
Object.prototype.toString.call(123);//”[object Number]”
Object.prototype.toString.call(true);//”[object Boolean]”
....
就不一一列举了
能够本身414
复制代码

Object.prototype.toString.call、instanceof、typeof又有啥不一样呢

typeof undefined //undefined
typeof null //object
typeof true //boolean
typeof 1.11 //number
typeof "lalala" //string
typeof function(){} //function
typeof new Object() //object
typeof new Array()  //object
typeof new RegExp() //object
复制代码

typeof 的局限性

在于 像Array,RegExp,null都会被判断为object,这就很尴尬了,没法去判断这些内置对象的具体类型

instanceof 的局限性

在于你必须知道实际类型和父类型再去判断对与,,对未知构造函数构造的对象来讲没法提早给定,constructor属性返回的值又不是预期的单纯的构造函数名。

Object.prototype.toString 的局限性

Object.prototype.toString 就很是牛批了,对全部的内建对象都能支持得很是好 惟一很差的地方 自定义的构建的对象,没法经过原型链去查父类型

Object.prototype.toString.call('');  //[object String]
Object.prototype.toString.call(undefined); // [object Undefined]
Object.prototype.toString.call(null); //[object Null]
Object.prototype.toString.call(1111);  // [object Number]
Object.prototype.toString.call(true);  //[object Boolean]
复制代码

valueOf

这个方法在Array等对象中也会被覆写

表现形式以下

先盗一个MDN的图嘿嘿

好了铺垫完了,待会进入正题

相关文章
相关标签/搜索