likes
comments
collection
share

你觉得var num = 123; num.abc = 'abc'; console.log(num.abc);打印的结果是什么呢

作者站长头像
站长
· 阅读数 64

对象知多少

前言

针对上述问题,想必有不少小伙伴会发出疑问:这难道不会报错嘛?接下来,小编将从基础知识开始深入讲解其V8执行过程。

先了解对象

什么是对象

JavaScript的原始类型包括数字、字符串、布尔值、null和underfined,除了他们之外的所有值都是对象。数字、字符串和布尔值“貌似”对象,因为它们拥有方法,但它们是不可变的。

一、访问对象的属性和方法

在 JavaScript 中,访问对象的属性和方法有两种主要的语法:点语法和方括号语法。

1. 点语法

点语法是最常用的方式,通过对象名后面的点 . 加上属性名或方法名来访问。例如:

const person = {
  name: 'Alice',
  age: 25,
  greet: function() {
    console.log('Hello!');
  }
};

// 访问属性
console.log(person.name); // 输出:Alice
console.log(person.age);  // 输出:25

// 调用方法
person.greet(); // 输出:Hello!

2. 方括号语法

方括号语法通过对象名后面的方括号 [] 包含属性名的字符串来访问。例如:

const person = {
  name: 'Alice',
  age: 25
};

// 访问属性
console.log(person['name']); // 输出:Alice
console.log(person['age']);  // 输出:25

方括号语法在属性名包含特殊字符或是变量时特别有用:

const key = 'name';
console.log(person[key]); // 输出:Alice

注意:访问对象上不存在的属性,得到的结果是underfined, 不会报错

二、增加对象属性和方法

要增加对象的属性和方法,可以直接使用点语法或方括号语法赋值。例如:

const car = {};

// 增加属性
car.make = 'Toyota';
car.model = 'Camry';
car.year = 2023;

// 增加方法
car.start = function() {
  console.log('Car is starting...');
};

console.log(car); // 输出:{ make: 'Toyota', model: 'Camry', year: 2023, start: [Function: start] }
car.start(); // 输出:Car is starting...

三、删除对象的属性和方法

要删除对象的属性和方法,可以使用 delete 操作符。例如:

const car = {
  make: 'Toyota',
  model: 'Camry',
  year: 2023,
  start: function() {
    console.log('Car is starting...');
  }
};

// 删除属性
delete car.year;
console.log(car); // 输出:{ make: 'Toyota', model: 'Camry', start: [Function: start] }

// 删除方法
delete car.start;
console.log(car); // 输出:{ make: 'Toyota', model: 'Camry' }

使用 delete 操作符可以完全移除对象中的属性或方法,但要注意这并不会释放内存。如果对象包含大量属性和方法,使用 delete 可能会影响性能。在实际应用中,应谨慎使用 delete 操作符。

创建对象

当我们在JavaScript中创建对象时,通常有几种方式可以选择。

一. 创建对象字面量

对象字面量是最简单和最直接的方法来创建对象。它允许我们在大括号中定义对象的属性和方法。

// 创建对象字面量
const person = {
  name: 'John',
  age: 30,
  greet() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
};

// 调用对象方法
person.greet(); // 输出:Hello, my name is John and I'm 30 years old.

二. 调用系统自带的构造函数

JavaScript提供了一些内置的构造函数,如 ObjectArrayDate 等,通过使用 new 关键字可以调用这些构造函数来创建对象。

// 调用系统自带的构造函数
const book = new Object();
book.title = 'JavaScript Cookbook';
book.author = 'John Doe';
book.pages = 300;

console.log(book); // 输出:{ title: 'JavaScript Cookbook', author: 'John Doe', pages: 300 }

三. 调用自定义的构造函数

除了系统自带的构造函数外,我们还可以自定义构造函数来创建对象。构造函数是一个普通的函数,通过使用 new 关键字来调用它,我们可以创建一个新的对象实例。

// 调用自定义的构造函数
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.drive = function() {
    console.log(`The ${this.make} ${this.model} is driving.`);
  };
}

// 创建Car对象实例
const myCar = new Car('Toyota', 'Camry', 2020);

console.log(myCar); // 输出:Car { make: 'Toyota', model: 'Camry', year: 2020, drive: [Function] }
myCar.drive(); // 输出:The Toyota Camry is driving.

在上面的示例中,我们定义了一个名为 Car 的构造函数,它有三个参数:makemodelyear。在构造函数内部,我们使用 this 关键字来指代新创建的对象实例,并分配属性和方法。通过调用 new Car(...) 来创建 myCar 对象实例,并使用 myCar.drive() 方法来调用对象的方法。

构造函数 new的解释过程:

  1. new 会在构造函数中创建一个this
  2. 执行构造函数中的逻辑代码,相对于给this添加属性和方法
  3. 返回this对象

答疑

var num = 123;
num.abc = 'abc'; 
console.log(num.abc);

通过上述讲解你是不是已经对对象有了一个基本的认识!但是数字类型不是对象,为什么添加属性不会发生报错呢?

在 JavaScript 中,数字是基本数据类型,但在访问其属性时,V8引擎会临时将其转换为包装对象。

因此,当你尝试给数字添加属性时,JavaScript 会临时创建一个临时对象,给这个对象添加属性,但这个属性只在这个临时对象上有效,对原始的数字没有影响。所以虽然不会报错,但实际上添加的属性并不会对原始数字产生影响。(所以才说“貌似”对象,但不会改变)

你也可以这样去理解过程:

//包装类

//V8引擎把num创建成了一个对象,并给其添加了属性
new Number(123).abc = 'abc'

//但是V8复查时发现并不是想把它作为对象来使用,所以又删除了它的属性
delete new Number(123).abc 

//所以打印对象不存在的属性时就会出现underfined的结果
console.log(new Number(123).abc);

对比分析

我们再来思考一下下面这个代码打印的结果是什么?

var num = new Number(123);
num.abc = 'abc';
console.log(num.abc); 

这段代码会打印出 'abc'。因为 num 是一个包装了数字的对象,你可以给对象添加属性。

在前一个例子中,num 是一个基本数据类型的数字,而在第二个例子中,num 是一个包装了数字的对象。虽然两者在语法上很相似,但在底层实现上有所不同。

在第一个例子中,当你尝试给基本数据类型的数字添加属性时,JavaScript 引擎会临时将其转换为包装对象,给临时对象添加属性。这种转换是临时的,不会对原始数据类型产生影响。

而在第二个例子中,你显式地创建了一个包装了数字的对象,这个对象本身就是一个完整的 JavaScript 对象,你可以向它添加属性,这些属性会被对象保留,与原始数据类型本身无关。

你也可以这样去理解过程:

//也就是说V8复查时是把它作为对象来使用,所以没有删除了它的属性

//这个也可以
console.log(num * 2);    //结果246  
//因为是包装了数字的对象,所以在参与运算时, V8认为它是数字

上难度,给出面试题

这是一个大厂面试题,欢迎小伙伴在评论区留言解答

var str = 'abc'
str += 1
var test = typeof (str)
if (test.length == 6) {
  test.sign = 'typeof 的返回结果是String'
}
console.log(test.sign);
//这个结果是什么

最后

在学习过程中,我们常常知其然而不知其所以然,尤其对于弱语言,有太多需要我们去深入其内核本质的地方,保持追溯本源的态度才能百战不殆!

小编同样将继续学习,继续分享,喜欢的小伙伴不要忘了一键三连哦!

转载自:https://juejin.cn/post/7365694439569113128
评论
请登录