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

学习JavaScript的对象 #12

Open
7 tasks
lfb opened this issue Jul 20, 2019 · 0 comments
Open
7 tasks

学习JavaScript的对象 #12

lfb opened this issue Jul 20, 2019 · 0 comments
Assignees
Labels

Comments

@lfb
Copy link
Owner

lfb commented Jul 20, 2019

创建对象

方法一:Object对象创建

var obj1 = new Object();
// 字面量
var obj1 = {};

方法二:Object.create()

Object.create(null) 创建的对象是一个空对象,在该对象上没有继承 Object.prototype 原型链上的属性或者方法,例如:toString(), hasOwnProperty()等方法,使用 Object.create() 是将对象继承到 __proto__ 属性上

var obj2 = Object.create(null);

方法三:构造函数

function Person(name) {
    this.name = name;
}

var p = new Person('bobobo');

属性类型

分为两种:数据属性 和 访问器属性。

数据属性

数据属性包含4个特征:

  • [[Configurable]]:表示是否可以通过 delete 删除属性从而重新定义属性,能否修改属性的特征,或者能否把属性改为访问器属性。默认值为 true。
  • [[Enumerable]]: 表示是否可以通过 for-in 遍历返回属性。默认值为 true。
  • [[Writable]]: 表示是否可以修改属性的值。默认值为 true。
  • [[Value]]: 表示属性的值。默认值为 undefined。

想要修改数据属性默认特征,需要使用 Object.defineProperty()方法修改。

  • 第一个参数为对象。
  • 第二个参数为对象属性名字。
  • 第三个参数为一个描述符对象(descriptor):Configurable, Enumerable, Writable, Value
var person = {}

Object.defineProperty(person, 'name', {
    configurable: false,
    enumerable: false,
    writable: false,
    value: 'js'
})

console.log(person.name); // 初始化值为 'js'

person.name = "bobo";
console.log(person.name); // 修改不成功,热输出 'js'

delete person.name;
console.log(person.name); // 仍然存在 name 属性,输出 'js'

for (var val in person) {
    console.log(val); // 打印不出来
}

访问器属性

访问器属性包含4个特征:

  • [[Configurable]]: 表示是否可以通过 delete 删除属性,从而重新定义属性,能否修改属性的特征,或者能否把属性改为数据属性。默认值为true。
  • [[Enumerable]]: 表示是否能通过 for-in 遍历返回属性。默认值为true
  • [[Get]]: 在读取属性时候调用的函数。默认值为 undefined。
  • [[Set]]: 在写入属性时候调用的函数。默认值为 undefined。

访问器属性必须使用:Object.defineProperty() 方法来定义。

  • 第一个参数为对象
  • 第二个参数为对象属性名字
  • 第三个参数为描述对象(descriptor):Configurable, Enumerable, Get, Set
var animate = {
    _name: 'dog'
};

Object.defineProperty(animate, "name", {
    get: function () {
        return this._name + ' [Get]';
    },
    set: function (newValue) {
        this._name = newValue + ' [Set]'
    }
});

console.log(animate.name); // god [Get]
animate.name = "cat";
console.log(animate.name); // cat [Set] [Get]

定义多个属性

使用 Object.definedProperties()方法,这个方法接收两个对象参数:

  • 第一个对象是要添加和修改其属性的对象
  • 第二个对象的属性与第一个对象中要添加或修改的属性一一对应
var tree = {};

Object.defineProperties(tree, {
    _name: {
        writable: true,
        value: 'Pine Tree'
    },
    _year: {
        writable: true,
        value: 100
    },
    name: {
        get: function () {
            return this._name;
        },
        set: function (newVale) {
            this._name = newVale
        }
    },
    year: {
        get: function () {
            return this._year;
        },
        set: function (newValue) {
            this._year = newValue;
        }
    }
});
console.log(tree.name); // Pine Tree
console.log(tree.year); // 100

tree.name = "Yang Tree";
tree.year = 200;

console.log(tree.name); // Yang Tree
console.log(tree.year); // 200

读取属性的特征

属性类型有2个:数据属性 和 访问器属性,需要读取属性是哪个特征的话,需要使用到:Object.getOwnPropertyDescriptor() 方法,第一个参数为:属性所在的对象,第二个参数为:读取的属性名称,返回的结果是一个对象:

  • 如果是数据属性:则这个对象包含:configurable, enumerable, writable, value
  • 如果是服务器属性: 则这个对象包含:configurable, enumerable, get, set
var tree = {};

Object.defineProperties(tree, {
    _name: {
        writable: true,
        value: 'pine tree'
    },
    name: {
        get: function () {
            return this._name;
        },
        set: function (newVale) {
            this._name = newVale
        }
    }
});

var descriptor1 = Object.getOwnPropertyDescriptor(tree, 'name');
var descriptor2 = Object.getOwnPropertyDescriptor(tree, '_name');

// 检测属性是哪个属性特征,我们简单的检测返回的对象是否有 get 方法即可
// 如果存在 get 方法那么就是 访问器属性
// 如果不存在 get 方法那么就是 数据属性
console.log(typeof descriptor1.get); // function
console.log(typeof descriptor2.get); // undefined

总结

  • 创建对象有3种方法,1. 字面量,new Object对象,2. Object.create()方法,3. 构造函数创建对象
  • 对象属性类型有2种:数据属性 和 访问器属性。
  • 数据属性有4个特征:Configurable,Enumerable,Writable,Value
  • 访问器属性有4个特征:Configurable,Enumerable,Get,Set
  • 定义数据属性和访问器属性都使用 Object.defineProperty()方法
  • 读取属性的特征属性的方法为:Object.getOwnPropertyDescriptor()方法

课后练习

  • 创建对象有几种方法?
  • 对象有几种属性?分别是什么?
  • 请说下数据属性的4个特征?
  • 请说下访问器属性的4个特征?
  • Object.defineProperty() 方法的作用
  • Object.defineProperties() 方法的作用
  • Object.getOwnPropertyDescriptor() 方法的作用

参考资料

@lfb lfb self-assigned this Jul 20, 2019
@lfb lfb added the 原型 label Jul 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant