0%

javascript-object-without-prototype

Background

今天在练习正则表达式的时候,发现了一个有趣的输出,之前未见过(也许曾经见过,但没有留意),索性研究一下。

代码如下:

1
2
3
4
const str = `name: zdd, age: 18, gender: male`;
const regex = /name: (?<name>\w+), age: (?<age>\d+), gender: (?<gender>\w+)/;
const match = str.match(regex);
console.log(match.groups);

简单解释一下这个正则表达式:

  1. /.../ - 这是js的正则表达式语法,用//包裹。
  2. name: - 匹配字符串name:
  3. (?<name>...) - 这是一个命名捕获,表示匹配后的值放到name这变量中,可以用match.groups.name来输出捕获的值。
  4. \w+ - 表示匹配任意字母、数字或下划线(等价于 [a-zA-Z0-9_]), + - 表示一个或者多个。

输出结果如下:

1
[Object: null prototype] { name: 'zdd', age: '18', gender: 'male' }

这个输出结果里面的[Object: null prototype]是什么意思呢?问了一下通义千问,发现这是一个没有原型的对象。

那么,啥是没有原型的对象呢?可以简单的理解为,这个对象没有继承任何Object的属性和方法,是一个干净的对象。它就是它自己!
此类对象没有toStringvalueOf等方法,也没有__proto__属性,因此无法通过原型链访问到Object的属性和方法。我们可以通过Object.create(null)来创建一个没有原型的对象。

以下代码会产生一个TypeError,因为person对象没有原型,所以无法访问toString, hasOwnProperty等方法。

1
2
3
4
5
6
7
const person = Object.create(null);
person.name = 'Philip';
person.age = 18;

console.log(person.toString()); // TypeError: person.toString is not a function
console.log(person.hasOwnProperty('name')); // TypeError: person.hasOwnProperty is not a function
console.log('name' in person); // true

总结

没有原型的对象有哪些好处呢?我们常说,存在即有理,既然这种对象,那么必然有它存在的道理:

优点

  1. 避免原型污染:在JavaScript中,我们经常会遇到原型污染的问题,通过创建没有原型的对象,可以避免这种问题。
  2. 速度快:没有原型的对象,不需要查找原型链,因此访问属性和方法的速度更快。
  3. 纯粹的数据容器:没有原型的对象,可以作为一个纯粹的数据容器。

缺点

  1. 无法使用Object.prototype上的方法,如toStringvalueOf等。
  2. 检查属性是否存在只能使用in操作符,不能使用hasOwnProperty方法。