JavaScript:实例属性和原型属性的各种操作

104 阅读2分钟

一、判断属性是否可枚举

原型方法:obj.propertyIsEnumerable

let person = {
  name1: 'name1'
}
Object.defineProperty(person, 'name2', {
  value: 'name2',
  writable: true,
  enumerable: false,
  configurable: true
})
console.log(person.propertyIsEnumerable('name1')) // true
console.log(person.propertyIsEnumerable('name2')) // false

二、实例属性的操作

1、判断

hasOwnProperty返回true的条件:属性只要在实例上就行

:以下特殊属性也返回true

  • 不可枚举属性
  • 符号属性
function Person() {
  this.name1 = 'name1'
}
const person = new Person()
Object.defineProperty(person, 'name2', {
  value: 'name2',
  writable: true,
  enumerable: false,
  configurable: true
})

const desc1 = Symbol('desc1')
person[desc1] = 'symbol1'

Person.prototype.name3 = 'name3';
Object.defineProperty(Person.prototype, 'name4', {
  value: 'name4',
  writable: true,
  enumerable: false,
  configurable: true
})
Person.prototype.func = function() {
  console.log('func')
}
const desc2 = Symbol('desc2')
Person.prototype[desc2] = 'symbol2'

console.log(person.hasOwnProperty('name1')) // 实例+可枚举:true
console.log(person.hasOwnProperty('name2')) // 实例+不可枚举:true
console.log(person.hasOwnProperty(desc1)) // 实例+符号:true
console.log(person.hasOwnProperty('name3')) // 原型+可枚举:false
console.log(person.hasOwnProperty('name4')) // 原型+不可枚举:false
console.log(person.hasOwnProperty(desc2)) // 原型+符号:false

2、Object.keys

返回实例上所有可枚举属性名称的字符串数组。

条件

  • 实例
  • 可枚举
  • 不是符号
function Person() {
  this.name1 = 'name1'
}
const person = new Person()
Object.defineProperty(person, 'name2', {
  value: 'name2',
  writable: true,
  enumerable: false,
  configurable: true
})

const desc1 = Symbol('desc1')
person[desc1] = 'symbol1'

Person.prototype.name3 = 'name3';
Object.defineProperty(Person.prototype, 'name4', {
  value: 'name4',
  writable: true,
  enumerable: false,
  configurable: true
})
Person.prototype.func = function() {
  console.log('func')
}
const desc2 = Symbol('desc2')
Person.prototype[desc2] = 'symbol2'

console.log(Object.keys(person)) // 仅 实例+可枚举: ['name1']

3、Object.getOwnPropertyNames()

返回满足以下条件的属性。

条件

  • 实例
  • 不是符号

不论是否枚举都返回。

三、原型属性的操作

1、判断

function hasPrototypeProperty(obj, name) {
  return !obj.hasOwnProperty(name) && (name in obj);
}

function Person() {
  this.name1 = 'name1'
}

Person.prototype.name2 = 'name2';
Person.prototype.func = function() {
  console.log('func')
}

const person = new Person()

console.log(hasPrototypeProperty(person, 'name1')) // false
console.log(hasPrototypeProperty(person, 'name2')) // true

2、获取

function getPrototypeProperty(obj, name) {
  if (!obj.hasOwnProperty(name) && (name in obj)) {
    return obj[name]
  }

  return undefined
}

function Person() {
  this.name1 = 'name1'
}
Person.prototype.name2 = 'name2';
Person.prototype.func = function() {
  console.log('func')
}

const person = new Person()

console.log(getPrototypeProperty(person, 'name1')) // undefined
console.log(getPrototypeProperty(person, 'name2')) // name2

四、in操作符

1、单独使用

只要通过对象可以访问,in 操作符就返回 true,包括不可枚举属性和符号属性。

function Person() {
  this.name1 = 'name1'
}
const person = new Person()
Object.defineProperty(person, 'name2', {
  value: 'name2',
  writable: true,
  enumerable: false,
  configurable: true
})

const desc1 = Symbol('desc1')
person[desc1] = 'symbol1'

Person.prototype.name3 = 'name3';
Object.defineProperty(Person.prototype, 'name4', {
  value: 'name4',
  writable: true,
  enumerable: false,
  configurable: true
})
Person.prototype.func = function() {
  console.log('func')
}
const desc2 = Symbol('desc2')
Person.prototype[desc2] = 'symbol2'

console.log('name1' in person) // 实例+可枚举:true
console.log('name2' in person) // 实例+不可枚举:true
console.log(desc1 in person) // 实例+符号:true
console.log('name3' in person) // 原型+可枚举:true
console.log('name4' in person) // 原型+不可枚举:true
console.log(desc2 in person) // 原型+符号:true

2、for-in 枚举

返回可枚举的实例和原型属性,符号属性除外。

条件

  • 可枚举
  • 原型+实例
  • 不是符号
function Person() {
  this.name1 = 'name1'
}
const person = new Person()
Object.defineProperty(person, 'name2', {
  value: 'name2',
  writable: true,
  enumerable: false,
  configurable: true
})

const desc1 = Symbol('desc1')
person[desc1] = 'symbol1'

Person.prototype.name3 = 'name3';
Object.defineProperty(Person.prototype, 'name4', {
  value: 'name4',
  writable: true,
  enumerable: false,
  configurable: true
})
Person.prototype.func = function() {
  console.log('func')
}
const desc2 = Symbol('desc2')
Person.prototype[desc2] = 'symbol2'

for (let key in person) {
  console.log(key) // name1、name3、func
}