JS对象常用操作

1. 对象属性操作

1.1 定义(新增/修改)属性

Object.defineProperty(obj, property, detail)

一次只能定义一个属性

传递三个参数

  • 参数 1: 需要进行定义属性的对象
  • 参数 2: 进行定义的属性名
  • 参数 3: 属性描述符,定义属性相关的配置信息对象
  • 参数 3 的配置信息对象的可用属性
  • value: 定义属性的值
  • configurable: 设置该属性是否可以被删除,默认是 false,即不可以被删除
  • writable: 设置该属性是否可以被修改,默认是 false,即不可以被修改
  • enumerable: 设置该属性是否可以被枚举,默认是 false,即不可以被枚举

注意,使用这种方式定义的属性,默认值都是 false。但是,使用字面量声明的对象,默认值都是 true,即可删,可改,可枚举

var obj = {a: 1};
Object.defineProperty(obj, 'b', {
    value: 3, 
    configurable: false
})
delete obj.b
console.log(obj);  // { a: 1, b: 3 }  无法删除
var obj = {a: 1};
Object.defineProperty(obj, 'b', {
    value: 3, 
    writable: false
})
obj.b = 4
console.log(obj);  // { a: 1, b: 3 }  无法修改
var obj = {a: 1};
Object.defineProperty(obj, 'b', {
    value: 3, 
    enumerable: false
})
for(var property in obj) {
    console.log(property);  // a  无法枚举
}

Object.defineProperties(obj, detail)

可以一次性定义多个属性

传递两个参数

  • 参数 1: 需要进行定义属性的对象
  • 参数 2: 需要进行定义的属性及其对应的属性描述配置对象
var obj = {};
Object.defineProperties(obj, {
    a: {
        value: 1,
        configurable: true,
        writable: true,
        enumerable: true
    },
    b: {
        value: 4,
        configurable: false,
        writable: false,
        enumerable: false
    }
})

1.2 属性存取器 get 和 set

在定义对象属性的属性描述符中,get 和 set 可以代替 value 和 writable 进行控制属性值的获取和写入。

var obj = {};
Object.defineProperties(obj, {
    a: {
        set: function (v) {
            console.log('设置 a 属性值')
            this._a = v;
        },
        get: function () {
            console.log('获取 a 属性值')
            return this._a;
        },
        // 访问器不能和 value 或者 writable 混在一起用,否则就会报错
        // 因为访问器就代替了这两个功能
        enumerable: true,
        configurable: true
    }
})
console.log(obj.a);  // 先输出 '获取 a 属性值',再输出 undefined
obj.a = 3;           // 输出 '设置 a 属性值'
console.log(obj.a);  // 先输出 '获取 a 属性值',再输出 3

属性描述符只能在 Object.defineProperty 或 Object.defineProperties 中使用。

不要在 set 和 get 中再次对当前变量进行赋值,否则会陷入死循环。可以在变量名前添加下划线,以示区分,作为属性值传递的中介。另外,按照习惯,前面添加下划线的属性或方法,一般都认为是对象内部使用的方法,外部不能使用。

link

1.3 枚举属性

使用 for…in… 语句循环遍历对象中的可枚举属性,依次输出
for(property in obj) { 
    // statement
}

property 通常是一个变量,也可以是一个可以被赋值的表达式,用于接收枚举出的属性名。obj 是一般是用于被枚举的对象。statement 是一个语句或语句块,它构成了枚举过程循环的主体。其中 property 如果是一个变量, 则可以在循环体中进行使用。

不可枚举属性,为继承于原型中的属性和直接定义为不可枚举的属性

基本使用 1:

var obj = {a: 1, b: 2};

for(x in obj) {
    console.log(x);  // 依次输出 a, b, 类型为 字符串
}

for(x in obj) {
    console.log(obj.x);  
    // 依次输出 undefined, undefined,无法通过 . 操作符来获取对应的属性值
    // 因为使用了点操作符则认为 x 是 obj 的属性名,并不是使用 a 和 b 属性名
}

for(x in obj) {
    console.log(obj[x]);  
    // 依次输出 1, 2,可以通过 [] 的方式来读取对应的属性
}

基本使用 2:

var o = { a: 1, b: 2 };

// 以 o 为原型创建 obj,其中 o 的属性均可枚举
var obj = Object.create(o);

// 设置 obj 自身可枚举的属性
obj.c = 3;
for(var prop in obj) {
    console.log(prop);
}
// c, a, b  先将自身的可枚举属性进行遍历,再对原型中的可枚举属性进行遍历

2. 对象常用方法

2.1 复制与合并

Object.assign():用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

Object.assign(target, …sources)

传递参数数量不定,可以传递 2 个 到 多个,参数之间使用 , 隔开

  • 改变了目标对象,并返回目标对象
  • 参数 1:target,目标对象
  • 剩余参数:需要进行复制的多个源对象
2.1.1 复制

将想要的属性合并进空一个新的空对象中,相当于复制

var target = {};
var objSource = { a: 1 };
var copy = Object.assign(target, objSource);
console.log(copy);              // { a: 1 }
console.log(target);            // { a: 1 }
console.log(target === copy);   // true
2.1.2 合并

如果目标对象与被合并对象具有相同的属性名,则属性将被新增的同名属性覆盖。再后来的同名属性将类似地覆盖早先的属性。其中函数属性也可以被合并和覆盖。

var obj1 = { a: 1 }
var obj2 = { a: 2, c: 3, fn: 'fun' };
var obj3 = { fn: function () { console.log('fn') } };

Object.assign(obj1, obj2, obj3);

console.log(obj1);    // { a: 2, c: 3, fn: fn() }
obj1.fn();            // fn

函数也可以当做目标对象,被合并如其他属性

function foo() { 
    console.log('foo');
}
var obj = {
    a: 1,
    b: function () {
        console.log('b');
    }
}
Object.assign(foo, obj);
foo();       // foo
foo.b();     // b
2.1.3 无法复制(合并)或复制(合并)异常

继承属性和不可枚举属性是不能被复制(合并)的

var obj = Object.create(
    // foo 属性在原型对象中,是个继承属性
    { foo: 1 },
    { 
        bar: {
            value: 2          // bar 是个不可枚举属性。
        },
        baz: {
            value: 3,
            enumerable: true  // baz 是个自身可枚举属性。
        }
    }
);
var copy = Object.assign({}, obj);
console.log(copy);            // { baz: 3 }

基本数据类型在被复制(合并)会先被包装为对象类型数据,之后再进行相应的操作。其中,只有字符串才能包装成为具有自身可枚举属性的对象,其他类型在复制(合并)时会被忽略

var v1 = "abc";
var v2 = true;
var v3 = 10;
var v4 = Symbol("foo");
var obj = Object.assign({}, v1, null, v2, undefined, v3, v4); 
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

异常会打断接下来的复制(合并)任务

<script>
    var target = Object.defineProperty({}, "foo", {
        value: 1,
        writable: false
    }); 
    // target 的 foo 属性是个只读属性。

    Object.assign(target, { bar: 2 }, { fun: 3, foo: 4, baz: 5 }, { a: 6 });
    // TypeError: "foo" is read-only
    // 注意这个异常是在拷贝第二个对象的 foo 属性时发生的
</script>

<script>
    // 将输出语句放在第二个 script 标签中,会跳过方法错误,能够正常输出对应的值
    console.log(target.bar);  // 2,说明第一个源对象拷贝成功了
    console.log(target.fun);  // 3,说明第二个源对象的第一个属性也拷贝成功了
    console.log(target.foo);  // 1,error,只读属性不能被覆盖,返回的值仍是复制前的值。所以第二个源对象的第二个属性拷贝失败了
    console.log(target.baz);  // undefined,异常之后 assign 方法就退出了,第三个属性是不会被拷贝到的
    console.log(target.a);    // undefined,第三个源对象更是不会被拷贝到的
</script>

2.2 使用指定的对象及其属性去创建一个新的对象

Object.create():使用指定对象作为原型去创建一个新的对象,并可以为新对象直接添加属性

Object.create(proto, [propertiesObject])

  • 参数 1:被指定为新创建的对象的原型对象
  • 参数 2:可选,传递值为一个对象。可直接在返回值新对象中添加新属性及配置相应属性描述符(具体写法和要求与 Object.defineProperties() 的第二个参数一样)
  • 抛出异常:如果 propertiesObject 参数不是 null 也不是对象,则抛出一个 TypeError 异常。

基本使用 1:

var obj = {
    a: 1, b: 2
}
var baz = Object.create(obj);
console.log(baz);    // {} 空对象
console.log(baz.a);  // 1,可以访问到原对象中的属性,则说明,原对象就是新对象的原型

基本使用 2:

var tar = { a: 1 };
var obj = Object.create(tar, {
    // p 会成为新创建对象的数据属性,省略了的属性特性默认为 false,所以属性 p 是不可写,不可枚举,不可配置的
    p: { value: 42 },
    // q 也会成
    q: { value: 12, enumerable: true, writable: true, configurable: true },
    // foo会成为新创建对象的数据属性
    foo: { value: "hello", writable: true, configurable: true },
    // bar会成为新创建对象的访问器属性
    bar: {
        configurable: false,
        get: function () { return 10 },
        set: function (value) { console.log("Setting `obj.bar` to", value) }
    }
});
console.dir(obj);      // 访问器属性不能通过 log 查看到,需使用 dir,但是能正常使用

// 获取自身属性
console.log(obj.foo);  // hello
console.log(obj.bar);  // 10

// 获取继承属性
console.log(obj.a);    // 1

obj.p = 24;
console.log(obj.p);    // 42,不可修改

for (var prop in obj) {
    console.log(prop);
    // q,由于剩余其他属性均未设置 enumerable 属性,默认为 false,不可枚举
}

console.log(delete obj.p);  // false, 删除失败

扩展使用:实现构造函数原型对象之间的继承

function Shape() {
    this.x = 0;
    this.y = 0;
}

// 父类的原型方法
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info('Shape moved.');
};

// 子类
function Rectangle() {
    Shape.call(this); // 调用构造函数
}

// 子类继承父类
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?', rect instanceof Rectangle);  // true
console.log('Is rect an instance of Shape?', rect instanceof Shape);          // true
rect.move(1, 1);      // Outputs, 'Shape moved.'

2.3 遍历自身可枚举属性

Object.keys():会返回一个由一个给定对象的自身可枚举属性组成的数组。数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)

  • 参数:传递一个对象
  • 返回值:一个表示给定对象的所有可枚举属性的字符串数组

基本使用:

var o = { a: 1, b: 2 };

// 以 o 为原型创建 obj,其中 o 的属性均可枚举
// 再添加一些不可枚举属性
var obj = Object.create(o, {
    c: { value: 3 }
});

// 设置 obj 自身可枚举的属性
obj.d = 4;

var arr = Object.keys(obj);
console.log(arr);
// ['d']  只会将自身的可枚举属性进行遍历,将遍历到的属性名放置在数组中

2.4 其它对象操作属性

  • Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。如果某个属性的值是一个对象时,该对象是可以改变的,即次冻结方法只能进行浅冻结。
  • Object.isFrozen() 方法判断一个对象是否被冻结(frozen)。
  • Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。
  • Object.isSealed() 方法判断一个对象是否是密封的(sealed)。
  • Object.seal() 方法可以让一个对象密封,并返回被密封后的对象。密封对象是指那些不能添加新的属性,不能删除已有属性,以及不能修改已有属性的可枚举性、可配置性、可写性,但可能可以修改已有属性的值的对象。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: JavaScript对象编程是指使用JavaScript语言创建和操作对象的过程。在JavaScript中,对象是一种复合数据类型,可以包含属性和方法。对象可以通过字面量、构造函数、原型等方式创建。通过对象编程,可以实现面向对象编程的思想,使代码更加模块化、可维护和可扩展。在JavaScript中,对象是非常重要的概念,掌握对象编程是成为一名优秀的JavaScript开发者的必备技能之一。 ### 回答2: JavaScript是一种流行的编程语言,其中面向对象编程(OOP)是其中的重要组成部分。对象JavaScript编程中最重要的概念之一,它是一种数据类型,通过对象可以轻松地组织和管理数据。JS对象包含了一组属性和方法,可以用来描述某个对象的性质和行为。 在JavaScript中,对象是动态创建的。创建对象的方法有很多,其中最简单的就是使用字面量,例如: var person = { name: 'Tom', age: 20, gender: 'male', sayHi: function() { console.log('Hi, my name is ' + this.name + ',I am ' + this.age + ' years old.') } }; 上面的代码定义了一个名为person的对象,该对象具有属性name、age、gender和方法sayHi。使用字面量创建对象的好处是,可以轻松地在代码中定义对象,而无需使用专门的构造函数。 当然,也可以使用构造函数来创建对象,例如: function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; this.sayHi = function() { console.log('Hi, my name is ' + this.name + ',I am ' + this.age + ' years old.') } }; var person = new Person('Tom', 20, 'male'); 上面的代码定义了一个名为Person的构造函数,在创建对象时使用了new关键字来调用该构造函数,返回一个新的person对象。这个对象包含了属性name、age、gender和方法sayHi。 在JavaScript中,对象是可以嵌套的。可以在对象中嵌套其他对象,也可以在对象中嵌套函数,这些函数就是对象的方法。通过对象的嵌套,可以更好地管理数据,使程序更加规范和易于维护。 总之,JavaScript对象编程是一种强大且灵活的编程方式,通过对象可以轻松地组织和管理数据,从而实现更好的开发效率和代码质量。由于JavaScript的广泛应用,对于对象编程的掌握将有助于开发者更好地掌握这门语言。 ### 回答3: 在JavaScript中,对象是一种基础数据类型,也是语法的重要组成部分。对象是由若干属性构成的,每个属性都是键值对的形式,其中键是字符串类型,值可以是任意的JavaScript数据类型,包括对象。通过定义对象的属性和方法,我们可以在JavaScript中创建功能强大的程序。 JavaScript对象编程有以下几个重要概念: 1. 对象字面量:使用“{}”来定义对象,字符:“:”分割键与值,“,”分割不同键值对。如:var obj = {name: "小明", age: 18}; 2. 访问对象属性:使用“.”操作符访问对象属性。如:obj.name 3. 新增属性:使用“.”或“[]”,如:obj.height = 180; 或 obj['sex'] = 'male'; 4. 删除属性:使用“delete”关键字,如:delete obj.age; 5. 遍历对象属性:使用“for...in...”语句遍历对象属性,如: for(var key in obj) { console.log(key + ": " + obj[key]); } 6. 面向对象编程:JavaScript中也可以实现面向对象编程。定义一个构造函数,然后使用“new”关键字创建对象实例,如: function Person(name, age) { this.name = name; this.age = age; this.sayHello = function () { console.log("Hello, my name is " + this.name + ", I'm " + this.age + " years old."); } } var p = new Person('小明', 18); p.sayHello(); // 输出:Hello, my name is 小明, I'm 18 years old. JavaScript对象编程是非常灵活的,我们可以根据需要动态地定义、操作对象,同时结合面向对象编程,使得JavaScript的代码结构更加清晰有序。掌握好JavaScript对象编程的技巧,可以让我们开发出更高效、更具有扩展性的项目。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值