Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深入js之对象的属性类型 #12

Open
FE-Sadhu opened this issue Apr 24, 2019 · 0 comments
Open

深入js之对象的属性类型 #12

FE-Sadhu opened this issue Apr 24, 2019 · 0 comments
Labels
深入js笔记 about javascript

Comments

@FE-Sadhu
Copy link
Owner

在我们平常的使用中,给对象添加一个属性时,直接使用object.param的方式就可以了,或者直接在对象中挂载:

var person = {
    name: 'TOM'
}

在ECMAScript5中,对每个属性都添加了几个属性类型,来描述属性的特点。它们分别是:

  • configurable: 表示该属性是否能被delete删除。当其值为false时,其他的特性也不能被改变。默认值为true

  • enumerable: 是否能枚举。也就是是否能被for-in遍历。默认值为true

  • writable: 是否能修改值。默认为true

  • value: 该属性的具体值是多少。默认为undefined

  • get: 当我们访问属性的值时,get将被调用。该方法可以自定义返回的具体值时多少。get默认值为undefined

  • set: 当我们设置属性的值时,set方法将被调用。该方法可以自定义设置值的具体方式。set默认值为undefined

注意:不能同时设置value、writable 与 get、set的值。

我们可以通过Object.defineProperty方法来修改这些属性类型。

下面我们用一些简单的例子来演示一下这些属性类型的具体表现。

configurable

var person = {
  name: 'Sadhu'
}

delete person.name; // 使用delete删除该属性 返回true表示删除成功

Object.defineProperty(person, 'name', { // Object.defineProperty()重新添加name属性
  configurable: false,
  value: 'TOM'
})

console.log(person.name); // TOM 

delete person.name; // 已经不能删除了

console.log(person.name); // TOM

// 试图改变value
person.name = 'sadhu'; // 定义了configurable: false时,其他的特性也不能改变,定义过了value: 'TOM' ,再改变值也不能改变了。
console.log(person.name); // TOM 

enumerable

var person = {
  name: 'sadhu',
  age: 21
}

var params = []

// 使用for-in枚举person属性
for (var key in person) {
  params.push(key);
}

console.log(params); // [ 'name', 'age' ]

// 重新设置name属性的类型,让其不可被枚举.
Object.defineProperty(person, 'name', {
  enumerable: false
})

var _params = [];

for(var key in person) {
  _params.push(key);
}

console.log(_params); // [ 'age' ]

writable

var person = {
  name: 'sadhu'
}

person.name = 'kk';

console.log(person.name); // 'kk' 证明此时name属性是可写的

// 重新定义name属性的类型,让其不可写
Object.defineProperty(person, 'name', {
  writable: false
})

person.name = 'TOM'; // 此时修改无效。

console.log(person.name); // kk

value

var person = {
  name: 'sadhu'
}

Object.defineProperty(person, 'name', {
  value: 'kk'
})

console.log(person.name) // 'kk' 改变了属性原本的值sadhu。

var _person = {};

Object.defineProperty(_person, 'name', {
  value: 'sadhu'
})

console.log(_person.name); // 'sadhu'

get/set

var person = {}

// 通过get与set自定义访问与设置name属性的方式
Object.defineProperty(person, 'name', {
  get: function() {
    // 读取name属性的内容时,只会一直读到值'sadhu'
    return 'sadhu'
  },
  set: function(value) {
    var res = value + '后缀'
    console.log(res);
    return res;
  }
})

console.log(person.name); // sadhu 第一次访问,调用get

person.name = 'kk'; // kk后缀 尝试修改调用set

console.log(person.name); // sadhu 第二次访问还是调用get

console.log(person);

请尽量同时设置get、set。如果仅仅只设置了get,那么我们将无法设置该属性值。如果仅仅只设置了set,我们也无法读取该属性的值。

bject.defineProperties

Object.defineProperty只能设置一个属性的属性特性。当我们想要同时设置多个属性的特性时,需要使用Object.defineProperties.

var person = {}

Object.defineProperties(person, {
    name: {
        value: 'Jake',
        configurable: true
    },
    age: {
        get: function() {
            return this.value || 22
        },
        set: function(value) {
            this.value = value
        }
    }
})

person.name   // Jake
person.age    // 22

读取属性的特性值

var person = {};

Object.defineProperties(person, {
  name: {
    value: 'sadhu',
    writable: false,
    configurable: false
  },
  age: {
    get: function() {
      return this.value || 21
    },
    set: function(value) {
      this.value = value;
    }
  }
})

var desc = Object.getOwnPropertyDescriptor(person, 'name');

console.log(desc);

/*输出
desc {
    value: 'sadhu',
    writable: false,
    enumerable: false,
    configurable: false
}
*/

本文完。

希望看到各位技术人对这篇文章有不同的有“证据”,符合逻辑的分析、看法~

文章会第一时间更新在GitHub,觉得写得还不错的,可以点个star支持下作者🍪


参考:
详解面向对象、构造函数、原型与原型链

@FE-Sadhu FE-Sadhu added the 深入js笔记 about javascript label Apr 24, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
深入js笔记 about javascript
Projects
None yet
Development

No branches or pull requests

1 participant