万物皆对象?彻底弄懂JavaScript对象的底层逻辑

0 阅读3分钟

在JavaScript的世界里,有一句广为流传的箴言:“万物皆对象”。初学JS时,我们常常对此深信不疑——毕竟连数组、函数甚至是函数本身的属性,似乎都能挂载上各种自定义的键值对。然而,当你写下 toString () 报错时,这个看似绝对的真理便开始摇摇欲坠。JavaScript中的“对象”到底是什么?它仅仅是一堆键值对的集合吗?

在聊万物皆对象前我们先要了解js的2种类型

1.原始类型:number、string、boolean、null、undefined、symbol、bigint

2.引用类型:object、function、array、date

一、创建对象的方式

1.字面量

const obj = {      // 对象字面量
    name:'猪猪侠' 
}
let hello = 'world'
obj[hello] = 123        // 往对象里面增加变量属性用[变量名]

delete obj[hello]       // 删除对象属性

2.构造函数 (new Object())

const obj = new Object()    // 构造函数创建对象
obj.name = '猪猪侠'

console.log(obj);

3.new 一个构造函数

function Person() {
    
}

// Person()     
const obj = new Person()  

函数有二义性:可以普通调用,也可以 new 调用

二、new 的工作原理

function Car(color) {
    // var this = {}      
    this.name = 'bmw'
    this.height = 1400
    this.long = 4900
    this.wide = 1700
    this.color = color
    // this.__proto__ = Car.prototype
    // return this
}

const aCar = new Car('pink')   // 实列对象
const bCar = new Car('blue')


bCar.name = '劳斯莱斯'

console.log(aCar);
console.log(bCar);

工作原理:

1.new 会往函数内凭空创建一个对象(this = {} )

2.执行函数中的代码

3.让这个对象的原型 等于 函数的原型 ( this.__ proto __ = Xxx.prototype )

4.retun 这个对象(this = {} )

原型:

1.所有的 函数都天生有一个属性:prototype

2.对象 天生拥有一个属性:_ proto _

var str = 'abc'           // const strObj = new String('abc')
str.length = 4            // strObj.length = 4   delete strObj.length
console.log(str.length);  

上面这个代码输出结果为3,我们要如何将输出结果改为4呢?这就需要我们在原型上面进行更改了即以下方式

String.prototype.len = 4
var str = 'abc'
console.log(str.len)

三、包装类

讲这个之前我们要先了解2个规则:

1.原始类型是不能添加属性和方法的

2.V8 在对象中查找属性,如果找不到,一定会去它原型上找

const str = 'hello'    // 字符串字面量   const str = new String('hello')

str.name = '猪猪侠'     // str.name = '猪猪侠'  不会报错,但是没有效果
                       // delete str.name  删除属性
                       // str.[[PrimitiveValue]]
console.log(str);
console.log(str.name); // undefined

工作过程:

1.当用户创建一个字面量, V8 会默认执行成 new Xxx()

2.因为原始类型不能增加属性和方法,所以 V8 在 new 出这个实列对象后,立即会做一个拆箱操作

3.例:str.length length 是 String 函数原型上的属性,并不是给字符串增加的属性

四、总结

总而言之,JavaScript中的对象绝非简单的“键值对集合”,而是融合了动态属性描述、原型链继承与元编程代理的精巧机制;当我们拨开“万物皆对象”的表象迷思,深入V8隐藏类的内存布局与属性描述符的精细管控,并理顺__proto__构建的寻址链路时,便真正掌握了这门语言的核心运转逻辑,从而能在日常开发中写出契合引擎优化、避开深层陷阱的高质量代码。