关于javascript:Object-重识一

内容有点儿多,将分为两篇内容与大家分享。有的中央的确难以了解,能够多入手实现一下,看看成果。

始终据说有这么一句话,在JavaScript中,所有皆为对象。

经自己谨慎钻研之后发现,此言确实不虚。(这不废话么,虚不虚的还用你说。)

明天斗胆跟大家一起讨论一下JavaScript重的Object。理解Object背地的 — 生存

浏览间隙,还得多留神劳动哟~

1. 对象的创立

开始第一个小问题,看一下如何创立一个对象。创建对象有四(shi)种形式。以下几种形式都可创立一个对象,只不过创立之后的体现稍有不同。具体表现为原型和this的指向问题。有趣味的读者可点击查看相干文章。在这里咱们就不具体介绍了。(偷个懒)

彻底弄懂JavaScript原型问题

深刻了解JavaScript的 this 指针

留神点:

四种形式创建对象,除了原型this指针体现不同,构造函数指向也有不同。(此时阐明的是不手动指定构造函数的状况下)

  • 字面量形式创立的对象。构造函数为 function Object() {}
  • 构造函数创立。构造函数为函数自身
  • Object.create创立的对象,构造函数为入参origin的构造函数
  • class 形式创立,会将自身也作为构造函数。

1.1 字面量形式创立

const obj = {} // 构造函数为 [Function: Object]

1.2 构造函数创立

function Obj() {}

const obj = new Obj() // 构造函数为 [Function: origin]

1.3 Object.create 创立

const origin = {a: 1, b: 2}

const target = Object.create(origin) // 构造函数为 origin 的构造函数

1.4 class形式创立

class Origin {}

const target = new Origin() // 构造函数 [Function: Origin]

2. 属性和办法

注:

  • 官方版

    • 属性是这个对象的属性,办法是这个对象所领有的性能
  • 艰深版

    • 属性是一个值,不可执行。
    • 办法为一个函数,可执行。

2.1 属性和办法获取

1.获取确定的key属性,应用 . 运算符 或 中括号
const obj = {
  a: 1,
  b: 2,
  c: 3,
  d: function () {}
}

obj.a === obj['a']// 1
obj.b === obj['b'] // 2
obj.c === obj['c'] // 3
obj.d === obj['d'] // function (){}
2.获取须要计算的kay值,只能应用中括号形式
const obj = {
  a1: 1,
  a2: 2,
  a3: 3,
  a4: function (){}
}

for(let i = 1;i < 5;i ++) {
  obj['a' + i]
}
// 1,2,3,function (){}

留神:

如果对象中不含有某个key,获取到的为 undefined

例如:

const obj = {}

obj.c() // TypeError: obj.c is not a function

因为obj中不含有c这个办法,所以获取到的是undefined。此值不是函数,执行报错

可批改为以下写法

const obj = {}

typeof obj.c === 'function' && obj.c()

这里有的读者可能会说这样也能够 obj.c && obj.c()。这种写法在上面这种状况下仍然会报错

const obj = {
  c: 1
}

obj.c()

所以,还是要分明的判断咱们要获取的key是一个函数,能力执行。

2.2 如何判断对象中含有某个值

在此段内容开始之前,先说一个小问题,如何判断对象中是否含有某个key值?

1. 应用 2.1中的属性获取
  • 只需判断是否为 undefined 即可。
  • 此办法有一个缺点,如果此值的确为 undefined,则会呈现判断失误的状况
const obj = {
  c: undefined
}

console.log(obj.c === 'undefined') // 判断为true,然而obj中的确含有c这个key
2. in
  • 蕴含某个key
// 蕴含某个key
function A () {
  this.b = 1
}
const a = new A()
console.log('b' in a) // true
  • 不蕴含某个 key
// 不蕴含某个key
function A () {
}
const a = new A()
console.log('b' in a) // false
  • 查问的key,值为 undefined 的状况
// 不蕴含某个key
function A () {
  this.b = undefined
}
const a = new A()
console.log('b' in a) // true
  • 查问的key存在于原型链上
function A () {
}

Object.prototype.b = 1
const a = new A()

console.log('b' in a) // true

留神点:

毛病:in办法无奈判断以后key是存在于对象自身还是在原型链上。此状况,咱们须要用到上面这种办法。

3. hasOwnProperty 查问属性是否存在于本身
  • 存在于原型链上
function A () {}

Object.prototype.b = 1
const a = new A()

console.log(a.hasOwnProperty('b')) // false
  • 存在于本身
function A () {
  this.b = 1
}

const a = new A()

console.log(a.hasOwnProperty('b')) // true
  • 属性值为undefined
function A () {
  this.b = undefined
}

const a = new A()

console.log(a.hasOwnProperty('b')) // true

总结:

  • 属性获取不能判断属性值为undefined的状况
  • in 办法不能判断属性是在对象自身还是在原型链上
  • hasOwnProperty能够判断属性是否存在于本身,同时也可判断属性值为undefined的状况

2.3 删除对象的属性

删除对象的属性能够应用delete办法,只不过此办法的性能并不算太优越

const obj = {
  b: 1,
  c: 2
}

delete obj.b
console.log(obj) // {c: 2}

劳动会儿,这篇文章可长哈,循序渐进的来。

2.4 属性分类

JavaScript中将属性分为两种:数据属性和拜访器属性

数据属性包含:ConfigurableEnumerableWritableValue 四个属性描述符

拜访器属性包含:ConfigurableEnumerableSetGet 四个属性描述符

通过比照咱们能够发现,属性形容有六类:

Configurable、Enumerable、Writeable、Value、Set、Get

留神:

批改描述符,只能够通过Object.defineProperty(obj, key, config)批改一个 || Object.defineProperties(obj,config)批改多个 办法来批改。

例如:

const obj = {
  a: 1,
  b: 2,
  c: 3
}
// 批改一个
Object.defineProperty(obj, 'a', {
  enumerable: true,
  writable: true,
  configurable: true
})

// 批改多个

Object.defineProperties(person, {
  a: {
    enumerable: true,
    writable: true,
    configurable: true
  },
  b: {
    enumerable: true,
    writable: true,
    configurable: true
  }
}
1. 描述符介绍

Configurable:是否可通过delete删除属性、是否可从新定义属性、是否可批改描述符、是否可进行属性调换。

  • true 上述操作都可进行
const obj = {
  a: 1,
  b: 2,
  c: 3
}
Object.defineProperty(obj, 'a', {
  configurable: true
})

delete obj.a
Object.defineProperty(obj, 'a', {
  value: 11
})
Object.defineProperty(obj, 'a', {
  enumerable: true
})
Object.defineProperty(obj, 'a', {
  set() {}
})
  • false 严格模式下报错,一般模式下过滤操作
const obj = {
  a: 1,
  b: 2,
  c: 3
}
Object.defineProperty(obj, 'a', {
  configurable: false
})

delete obj.a
Object.defineProperty(obj, 'a', {
  value: 11
})
Object.defineProperty(obj, 'a', {
  enumerable: true
})
Object.defineProperty(obj, 'a', {
  set() {}
})

Enumerable:是否可枚举

const obj = {
  a: 1,
  b: 2,
  c: 3
}

// 为 true 的状况,可遍历
Object.defineProperty(obj, 'a', {
  enumerable: true
})

for(let item in obj) {
  console.log(item) // a, b, c  可遍历到 a
}

// 为false的状况,不可遍历
Object.defineProperty(obj, 'a', {
  enumerable: false
})

for(let item in obj) {
  console.log(item) // b, c  遍历不到 a
}

Writable:是否可批改属性的值,加上它,将变为数据属性

const obj = {
  a: 1,
  b: 2,
  c: 3
}

// 为 true 可批改属性值
Object.defineProperty(obj, 'a', {
  writable: true
})
obj.a = 2
console.log(obj.a) // 2

// 为false 不可批改属性值 严格模式下会报错
Object.defineProperty(obj, 'a', {
  writable: false
})
obj.a = 2
console.log(obj.a) // 1

Value:属性的数据值,加上它,将变为数据属性

const obj = {
  a: 1,
  b: 2,
  c: 3
}
Object.defineProperty(obj, 'a', {
  value: 11
})
console.log(obj.a) // 11

Set:写入属性时调用,加上它,将变为拜访器属性

const obj = {
  a: 1,
  b: 2,
  c: 3
}
Object.defineProperty(obj, 'a', {
  set() {
    console.log('a的值扭转了')
  }
})

obj.a = 2 // a的值扭转了

Get:读取属性时调用,加上它,将变为拜访器属性

const obj = {
  a: 1,
  b: 2,
  c: 3
}
Object.defineProperty(obj, 'a', {
  get() {
    console.log('获取a的值')
  }
})

obj.a // 获取a的值
2. 属性调换:

数据属性 –> 拜访器属性

Writable、Value 中的任意一个替换为 Set、Get 中的任意一个。

拜访器属性 –> 数据属性

Set、Get 中的任意一个替换为 Writable、Value 中的任意一个。

示例可接着往下看

3. 获取某个属性的形容(查看此属性是数据属性还是拜访器属性)

想要查看某个属性的形容,能够应用Object.getOwnPropertyDescriptor(obj, key) 来查看

const obj = {
  a: 1
}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
// { value: 1, writable: true, enumerable: true, configurable: true }

Object.defineProperty(obj, 'a', {
  get() {
    console.log('获取a的值')
  }
})
console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
/*
{
  get: [Function: get],
  set: undefined,
  enumerable: true,
  configurable: true
}
*/

此例咱们能够验证 属性调换 的正确性,当咱们将get设置为 a 的描述符时,a 会变为拜访器属性

接下文:Object 重识(二)

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理