JS 对象

"为什么我给对象加的属性不见了?""new 构造函数为什么不用 return 也能拿到对象?""对象遍历为什么会拿到原型上的属性?"

重点:JS 万物皆对象

一、JS 对象是什么

简而言之,对象是用花括号 { } 包裹的键值对,

js 复制代码
const a = 1
const person = {
  name: '小明',
  age: 18
}

二、JS 对象的创建方式

1.通过字面量创建

例如:

js 复制代码
const person = {

}

这里的花括号相当于告诉了 V8 引擎,我现在写的东西是个对象,接下来的逻辑请按对象处理

2.通过 new 创建(调用官方提供的构造函数)

例如:

js 复制代码
const a = new Object()
// a = {}

官方为 JS 提供了引用类型以及原始类型的构造函数,调用即可创建该类型的实例对象

3.通过自己写的构造函数通过 new 关键字调用

例如:

js 复制代码
function Car(color) {
  this.name = 'su7'
  this.height = '1400'
  this.lang = '4800'
  this.weight = '1500'
  this.color = color
}
const car1 = new Car('purple')
const car2 = Car('purple')
console.log(car1, car2); // Car { name: 'su7', height: '1400', lang: '4800', weight: '1500', color: 'purple' } undefined

可以看到,car1 是通过 new 生成的,car2 则是直接通过直接调用我们写的 Car 函数生成的,为什么 car1 有值,car2 却是 undefined 呢?

先看 car2 ,因为我们在函数内并没有返回值,是 undefined 情有可原 再看 car1 ,同样没有返回值,可是有值,这唯一的区别就是 car1 是通过 new 生成的, 而在 new 一个函数(此处为Car ) ,将 Car 用成了一个构造函数的样子,返回了一个实例对象,new 完源码其实是添加了返回值的,再来粗浅表达一下 new 源码大概干了些什么(不涉及原型链的部分的写法)

js 复制代码
function Car(color) {
  this.name = 'su7'
  this.height = '1400'
  this.lang = '4800'
  this.weight = '1500'
  this.color = color
}
const car1 = new Car('purple')


// function Car(color) {
//   const a = {}
//   a.name = 'su7'
//   a.height = '1400'
//   a.lang = '4800'
//   a.weight = '1500'
//   a.color = color
//   return a
// }

像是官方提供的数据类型构造函数,其实是涉及原型链和原型的继承的,这个点后面文章再介绍,此文仅谈论对象的表层内容

4.Object.create()

这是官方提供的 Object 里的方法,侧重于原型的继承,后续文章详细介绍,此文提一嘴

三、对象的一些基本操作

1.对象身上的键值对是可以添加函数的,我们一般称之为方法

js 复制代码
const a = {
  skill: function() {
    console.log('会飞');
  }
}

a.skill() // 会飞

2.对象身上的增加和函数属性值

js 复制代码
const a = {
  skill: function() {
    console.log('会飞');
  }
}

a.skill() // 会飞

a.options = {
  color: 'red',
  size: '1000'
}

console.log(a.options); // { color: 'red', size: '1000' }

delete a.options

console.log(a.options); // undefined

此处介绍了 JS 中对象怎么删除和添加属性

四、包装类

这个名词也就是看着专业

在你定义一个字面量,不管是谁的字面量,官方都是通过 new 字段调用对应数据类型的构造函数生成的

这也是 JS 万物皆对象的依据

js 复制代码
var num = 123  // new Number(123)
num.a = 'aaa'
console.log(num.a); // undefined

// // 原始类型一定无法添加属性和方法,属性和方法是对象独有的
// var num = 123  // new Number(123)
// num.a = 'aaa'
// delete num.a
// console.log(num.a); // undefined

按理来说,在给身为String 类型的 num 添加 a 属性的时候就应该报错,但是 JS 是弱类型语言,一个变量只有在被使用的时候才知道是什么类型

在打印 num.a 的时候, V8 才想起来了, numString 类型,而不是一个对象,所以源码在编译运行的时候, 偷偷把 num 身上的属性值给删掉了,当值被判定 为原始类型时就会自动将包装对象上添加的属性移除

但是在给 num 加属性的时候,JS 是真让把 num 当对象使

这里再举一个例子,涉及一点原型,后端文章会具体讲

js 复制代码
var str = 'hello' 
typeof('hello')  // string
var str = new String('hello')
str.length = 2

console.log(str.length);  // 5

delete str.length

console.log(str.length);  // 5

其实 JS 中,String 类型的数据身上本就有 length 属性,我这里给他再挂一个 length ,可以看到,打印出来的 str.length 还是 5 ,就算把这个 length 删了,他还是有

这个是什么原因,最主要的,就是因为 length 不是挂在 str 的表层上,他是挂在 String 的原型上,这里 strlength 其实是继承过来的,关于原型的介绍,后续文章会提及

相关推荐
bearpping3 小时前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx
@大迁世界3 小时前
07.React 中的 createRoot 方法是什么?它具体如何运作?
前端·javascript·react.js·前端框架·ecmascript
January12073 小时前
VBen Admin Select 选择框选中后仍然显示校验错误提示的解决方案
前端·vben
. . . . .3 小时前
前端测试框架:Vitest
前端
xiaotao1314 小时前
什么是 Tailwind CSS
前端·css·css3
颜酱4 小时前
DFS 岛屿系列题全解析
javascript·后端·算法
战南诚5 小时前
VUE中,keep-alive组件与钩子函数的生命周期
前端·vue.js
发现一只大呆瓜5 小时前
React-彻底搞懂 Redux:从单向数据流到 useReducer 的终极抉择
前端·react.js·面试
霍理迪5 小时前
Vue的响应式和生命周期
前端·javascript·vue.js