首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >02 - 并不是所有东西都是对象

02 - 并不是所有东西都是对象

作者头像
公众号---人生代码
发布2020-12-29 15:54:50
4170
发布2020-12-29 15:54:50
举报
文章被收录于专栏:人生代码人生代码

挖槽,这年轻人无耻

本文翻译自如下链接:

https://dev.to/d4nyll/not-everything-in-javascript-is-an-object

关于 JS 是面向对象编程语言还是函数式编程语言,还是存在很多困惑。确实,JS 可以两种都兼容,但这会导致一个问题,是什么呢?会导致人们会有这样的疑问:在 JS 中,所有的东西都是对象?

今天我们就来解决这个问题

让我们从头开始吧

在 JS 中,有六种原始数据类型:

  • 布尔值 true or false
  • null
  • undefined
  • number 双精度 64 位浮点型数。JS 中没有整数
  • string
  • symbol (ES6 中新增的功能)

除了这六个基本类型,ECMAScript 标准还定义了一个 Object 类型,它用来存储键值对类型。

const obj = {
    key: 'value'
}

简而言之,不是原始类型的任何事物都是 Object,并且包括函数和数组。

所有的功能都是对象?

// 原始类型
true instanceof Object // false
null instanceof Object // false
undefined instanceof Object // false
0 instanceof Object // false
'bar' instanceof Object // false

// 非原始类型
const foo = function() {}
foo instanceof Object // true

原始类型

基本类型是没有其他附加方法的,所以你永远看不到 undefined.toString()。也正因为如此,原始类型是不可变动的,因为他们没有附加可以使得他们变异的方法。

你可以将原始类型重新分配给变量,但是它将是一个新的值,旧的值不能也不可以更改。

const answer = 42
answer.foo = "bar"
console.log(answer.foo) // undefined

基本类型是不可变动的。

此外,与对象不同,原始类型作为值本身存储为对象,后者作为参考存储,这在执行相等性检查时会产生影响。

"dog" === "dog" // true
14 === 14 // true
{} === {} // false
[] === [] // false
(function(){}) === (function(){}) // false

基本类型是按值存储,对象是按引用存储

函数

函数是一种特殊的对象,具有一些特殊的属性,例如 constructor 和 call

const foo = function(bar) {}
foo.name // foo
foo.length // 1

就像普通对象一样,您可以向对象添加新属性:

foo.bar = "baz"
console.log(foo.bar) // baz

这使得函数成为一等公民,因为它可以像传递给其他函数的参数一样传递给其他对象,这就像其他对象一样。

方法

方法是对象的属性,它也恰好是函数。

const foo = {}
foo.bar = function(){console.log("baz")}
foo.bar() // 'baz'

构造函数

如果你有几个共享同一实现的对象,则可以将该逻辑放在构造函数中,然后使用该构造函数创建这些对象。

构造函数与其他函数没有什么不同,在 new 关键字之后使用函数时,该函数将用作构造函数。

任何函数都可以当做构造函数。

const Foo = function() {}
const bar = new Foo()
console.log(bar); // {}
bar instanceof Foo; // true
bar instanceof Object; // true

构造函数将返回一个对象,你可以在函数体内使用 this 来为对象分配新的属性。因此,如果我们要使许多对象的属性 bar 初始化为 value 'baz',则可以创建一个新的构造函数 Foo 来封装该逻辑。

const Foo = function() {
    this.bar = "baz"
}
const qux = new Foo()
console.log(qux); // {bar: 'baz'}
qux instanceof Foo // true
qux instanceof Object // true

你可以使用构造函数创建一个新的对象。

运行诸如 new Foo() 的构造函数,不带 (new)就像普通函数一样执行,函数内部将与执行上下文 this 相对应。因此,如果我们直接 Foo() ,实际上是在 window 对象上调用该函数:

Foo() // undefined
window.bar // 'baz'

相反,如你所见,将普通函数作为构造函数运行:

const pet = new String('dog')

包装对象

类似 String, Number,Boolean,Function,当 new 关键字结合为这些原始类型创建包装对象。

String 是一个全局函数,当传入参数时会创建原始字符串,它将尝试该参数转换为字符串:

String(1337); // '1337'
String(true); // 'true'
string(null); // 'null'
String(undefined); // 'undefined'
String() // ''
String('dog') === 'dog'; // true
typeof  String('pet'); // 'string'

但是你也可以将该String函数作用构造函数:

const pet = new String('dog')
typeof pet // 'object'
pet === 'dog' // false

这将创建一个新的对象,该对象便是 string 'dog',具有以下属性:

{
    0: 'd',
    1: 'o',
    2: 'g',
    length: 3
}

对象包装通常也称为包装器对象。

自动装箱

有趣的是,原始字符串和对象的构造函数都是函数,更有趣的是.constructor,当我们已经介绍了原始 类型不能有方法时,你可以调用原始字符串。

const pet = new String('dog')
pet.constructor === String // true
String('dog').constuctor === String // true

发生力一个称为自动装箱的过程,当你尝试某些原始类型上调用属性或者方法时,js 首先会将其转换为 临时包装对象,然后在不影响原始属性的情况下访问其上的属性、方法。

const foo = "bar"
foo.length // 3
foo === "bar" // true

在上面的示例中,要访问property length,JavaScript将自动装箱foo到包装对象中,访问包装对象的length属性,然后将其丢弃。这样做不会影响foofoo仍然是原始字符串)。

这也解释了为什么在尝试将属性分配给原始类型时JavaScript不抱怨的原因,因为赋值是在该临时包装对象上完成的,而不是原始类型本身。

const foo = 42;
foo.bar = "baz"; // Assignment done on temporary wrapper object
foo.bar; // undefined

如果您使用没有包装对象的原始类型(例如undefined或)尝试此操作,则报错null

const foo = null
foo.bar = "baz" // Uncaught TypeError: Cannot set property 'bar' of null

概要

  1. 并非JavaScript中的所有内容都是对象
  2. JavaScript有6种原始类型
  3. 所有不是原始类型的东西都是对象
  4. 函数只是对象的一种特殊类型
  5. 函数可用于创建新对象
  6. 字符串,布尔值和数字可以表示为原始类型,也可以表示为对象
  7. 由于JavaScript具有自动装箱功能,因此某些基本类型(字符串,数字,布尔值)看起来像对象。

万水千山总是情,点个再看行不行

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CryptoCode 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 让我们从头开始吧
    • 所有的功能都是对象?
      • 原始类型
        • 函数
          • 方法
            • 构造函数
              • 包装对象
                • 自动装箱
                  • 概要
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档