JavaScript 面向对象(一)

吐槽君 分类:javascript

数据类型

JavaScript 中有 8 种数据类型,分别是:

简单基本类型

  • string 字符串类型
  • number 数字类型
  • boolean 布尔值类型
  • undefined 未定义类型
  • null 空类型
  • bigint 范围更大的整型值
  • symbol 独一无二的值

引用数据类型

  • Object 对象类型

其中 7 种简单基本类型的变量直接存储值,而应用数据类型存储地址,对象的值存储于堆中。

可以使用 tyeof 来判断变量的数据类型,其中 typeof null 输出为 Object 是因为在 JavaScript 中二进制前三位为 0 则会被判断为 Object 类型,而 null 的二进制全是 0 ,所以这是一个 JavaScript 的 bug 。

简单基本类型是值类型,不具有属性,但是我们依然可以使用 'abc'.length ,这是因为进行了封箱和拆箱的处理,在执行这句代码时会自动将 'abc' 进行封箱操作,自动生成一个 new String('abc') 对象,并调用打印其 length 属性,执行完毕则进行拆箱,回到字面量 'abc' 。而 nullundefined 没有对应的内置对象,所以无法进行封箱操作,也无法调用任何方法或属性。

对象的定义

对象可以通过两种方式定义: 声明形式和构造形式

// 声明形式
var obj1 = {
  name: 'knight1',
  age: 18
};

// 构造形式
var obj2 = new Object();
obj2.name = 'knight2';
obj2.age = 19;
 

对象是引用类型,变量存储对象的引用,而对象的属性如果也是对象,则存储的也是对象的引用

属性描述符

image1.png

上面这个例子向我们展示了通过 Object.getOwnPropertyDescriptor() 来获取属性的属性描述符,并通过 Object.defineProperty() 来设置属性描述符

属性描述符分为两类,

  • 数据描述符:
{
  configurable: true,
  enumerable: true,
  value: "knight2",
  writable: true
}
 
  • 访问描述符:
{
  configurable: true,
  enumerable: true,
  get(){console.log('get')}, 
  set(){console.log('set')}
 
  • configurable

设置属性是否是可配置,若为 false 无法通过 Object.defineProperty() 修改属性描述符,默认为 true

注意: 若我们将 configurable 设置为 false ,而 writabletrue 时,我们还可以调用一次 Object.defineProperty() 用于将 wirtable 修改为 false

  • enumberable

是否可被枚举,若为 false 则属性不会出现在对象的属性枚举种,如 for of 中,默认为 true

  • value

属性的值

  • writable

决定是否可以修改属性的值,若为 false 则属性只可被读取而无法被写入

  • get / set

重写属性的 getset 操作,若只定义其中一个,则另一个什么都不执行,如只定义 get ,则无法修改属性值

原型

image2.png

如图所示,其中 personPerson.protype 是对象,而 Person 为函数,我们通过 Person 构造函数实例化 person 对象,然后会将 Person()prototype 对象作为 person 的原型,在浏览器中国,我们可以通过 person.__proto__ 属性来访问这个原型对象,而 Personprototype.constructor 指向 Person() 函数。

原型链

刚才已经说了, personPerson.protype 是对象,所以 Person.protype 也有 __proto__ 属性,然后如果我们依次向上寻找原型的话,大部分时候都会找到 Object.prototype 对象,而这个对象的原型指向 null

当我们访问 person 中的属性时,若该属性在 person 中没有,则会向原型中寻找,然后依次向上寻找,如果找到原型的尽头依然找不到的话,就会返回 undefined

而如果我们找到了则会返回该属性,并停止寻找,这也会造成属性的屏蔽,就是原型链下端的属性会屏蔽上端的属性。

如果属性不在对象中,而在对象的原型中则会出现下面三种情况

  • 如果原型中存在该属性,且违背标记为只读,则会在对象中添加一个同名属性,他就是屏蔽属性
  • 如果原型中存在该属性,但被标记为只读,则无法被修改,也不会在对象中添加一个同名属性
  • 如果原型中存在该属性,但是是一个 setter ,则会调用该 setter

回复

我来回复
  • 暂无回复内容