你还认为JS中万物皆对象?

发布时间:2019-08-19 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了你还认为JS中万物皆对象?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

经常在国内的各大网站博客上看到一句话,叫做JS中万物皆对象,那是否真是如此?

那么,我们先来捋一捋JS中的数据类型,JS中的数据类型有下面几种

所以本质上真的都是Object? -- NO

1.数据类型

在JS中我们把前面六种类型称为为基本数据类型,最后一种则是复杂数据类型,也就是对象类型。其实从这里看貌似已经区分了对象以及其他。

2.对象类型与其他类型的区别

对象可以动态的添加属性和方法,而基本类型不行。
如下:

// 基本类型 Number
VAR num1 = 1000;
num1.length = 10;
console.LOG(num1.length); //undefinded 

// 对象类型 Array
var arr1 = [];
arr1.length = 10;
console.log(arr1.length); //10

3.值类型与引用类型

再进一步看,JS中的数据类型有值类型(基本类型)和引用类型(对象类型)之分(其实其他很多语言中也有这么个区别),所谓值类型和引用类型,无非只是实例对象中保存了值或者保存了对象的引用。

  1. 值类型:初始化一个值类型实例的时候,实际上是给这个值分配了一个内存空间来保存,当进行赋值操作的时候,新的实例会开辟一块新的内存空间,然后将原来的值copy 到了这个新的内存空间中;

  2. 引用类型:初始化一个引用类型实例的时候,仅仅是把这个实例的值所在内存空间的引用赋给这个实例,当copy 给了新的实例对象使,实际上是copy 了对这块内存空间的引用,两个实例对象本质上共用一块内存空间。

举个?:

// 值类型 Number
var num1 = 1;
var num2 = num1;
num2 = num2 + 1
console.log(num1);  // 1

// 引用类型 Array
var arr1 = [];
var arr2 = arr1;
arr2.push('oujm')
console.log(arr1);  // ["oujm"]

你还认为JS中万物皆对象?

目前的结论

其实从上面看,很明显的能得出JS中并非万物皆对象,可为什么还是有这么多的人认为并相信这个观点是正确的呢?(包括当初懵懂无知的我?)

为什么呢?

1. typeof null

console.log(tyPEof null); // object

很多人(可能不多,我瞎猜)都说,连null 都是对象类型,其他的能不是对象吗?讲道理我之前也很疑惑。直到在看书的时候看到null不过是一个空对象引用,这么说来,它的类型是object 也就没有那么奇怪了。

还有些人说这个是JS中的一个bug ,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判 断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回"object" 。是真也好,假也罢。但说这是个bug 其实没必要,我不知道底层是怎么实现,可仅仅是因为null 在底层全是0就返回object ,这种bug 未免显的太低级了点把... 我更愿意相信,JS的设计者就是想把null 表示为空对象引用

2. 基本数据类型的实例对象有 __PRoto__

如下所示:

var str = "oujm";
console.log(str.__proto__);

/* String {
anchor:ƒ anchor()
at: ƒ at()
Big: ƒ big()
blink: ƒ blink()
bold: ƒ bold()
charAt: ƒ charAt()
charCodeAt: ƒ charCodeAt()
codePointAt: ƒ codePointAt()
concat: ƒ concat()
constructor: ƒ String()
... 
} */

// Boolean Number 等基本类型打印出来的结论类似

从我们之前的学习中能知道str 是个基本类型,基本类型怎么会有属性呢。可是这里不但看到了这个基本类型的实例对象有属性__proto__,而且很明显它的构造函数就是String() ,这个时候有些人就会觉得既然有属性,有构造函数,那说明str 本质上就是个对象。这在表面上看起来好像是没什么问题。

那让我们再来看一个更直白的?:

var str1 = "oujm";
var str2 = str1.substring(2);

从上面能看出来str1 是有方法的。

OK,宗上所得:基本类型也是对象类型,即万物皆对象

我觉得大部分人能得出这个结论都基于此。但是他们忽略了,在JS的世界中有一种对象类型叫包装对象

包装对象(StringNumber,Boolean)

咦?,StringNumberBoolean ,这三个不是基本类型吗。其实不然,ECMAScript提供了这三个特殊的引用类型,这三个引用类型和其他的引用类型相似,但同时也具有于各自的基本类型相应的特殊行为,实际上,每当读取一个基本类型的时候,后台就会创建一个对应的基本包装类型的对象。

再来看上面那个?,str1 很明显是一个基本类型实例,问题就出在 str1.substring(2) 字符串怎么会有方法。其实,为了让我们更好的操作基本类型的实例对象,后台进行了一系列的操作:

  1. 创建String的实例

  2. 在实例上调用指定的方法

  3. 销毁这个实例

// var str2 = str1.substring(2) 动作拆解:

var tempStr = new String("oujm");
var str2 = tempStr.substring(2);
tempStr = null;

从这里能够看到,一般的引用类型和包装类型唯一的区别就在于对象的生命周期。包装类型的对象生命周期很短,只有代码执行的一瞬间,然后就被销毁了,所以这也就是为什么我们不能在运行的时候为基本类型的值添加属性和方法。

var str1 = "oujm";
var str1.bf = "ethan";
console.log(str1.bf); // undefined

这也解答了我曾经的一个疑问

var str1 = "oujm";
var str2 = new String("ethan");

console.log(str1.__proto__ === str2.__proto__); // true
console.log(str1 instanceof String); // false 
console.log(str2 instanceof String); // true 

同样的道理,在调用__proto__ 属性的瞬间,也是使用new String() 先来实例化一个对象,所以那一瞬间他们的构造函数以及原型对象是相同的,但也仅仅是那一瞬间。

综上

别再?到有些文章说的,JS的世界很大,并不只有对象

脚本宝典总结

以上是脚本宝典为你收集整理的你还认为JS中万物皆对象?全部内容,希望文章能够帮你解决你还认为JS中万物皆对象?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。