赞
踩
1、JS对象是基本数据数据类型之一,是一种复合值,可以看成若干属性的集合。
2、对象除了可以保持自有的属性,还可以从一个称为原型的对象继承属性。其中,原型链继承是JavaScript的核心特征。
3、对象是动态的,可以增加或删除属性。
4、除了字符串、数值、true、false、null和undefined,其它值都是对象。
5、对象最常见的用法是对其属性进行创建、设置、查找、删除、检测和枚举等操作。
6、每个对象还拥有三个相关的对象特性。分别为:
对象字面量是一个表达式,每次运算都会创建一个新的对象,其中的属性值也会重新计算。如:
- let empty = {};
- let point = { x: 0, y: 0 };
- let book = {
- "first title": "JavaScript",
- "second-title": "HTML5 CSS3",
- for: "readers",
- author: {
- firstname: "xiao",
- lastname: "ming",
- },
- };
在这个例子里,先创建了一个空对象,没有任何属性,然后创建了point对象,赋予了它两种属性,分别是x和y,book对象,赋予了first title,second-title,for,author四个属性,属性名可以是字符串也可以是对象。若属性名有空格或特殊字符,必须用字符串表示。属性名可以是保留字,但尽量避免。
当然,通过字面量创建还可以先给对象留空{},通过对象名.属性名或对象名["属性名"]来进行对象的赋值,如:
- let book = {}
- book.author = {
- firstname: "xiao",
- lastname: "ming",
- },
- book.for = "readers"
- book.salestate = "good"
- book["first title"] = "JavaScript",
- book["second-title"] = "HTML5 CSS3"
通过new调用构造函数来创建并初始化一个新对象,通过对象名.属性名或对象名["属性名"]来进行对象赋值。
JavaScript语言核心中的原始类型都包含内置构造函数,如Object()、Array()、Date()等,如:
- let book = new Object()
- book['author'] = {
- firstname: "xiao",
- lastname: "ming",
- },
- book.for = "readers"
- book.salestate = "good"
- book['first title'] = "JavaScript",
- book['second-title'] = "HTML5 CSS3"
- console.log(book);
对象也可以用Object.create(proto, [ propertiesObject ])方法创建,其中,proto指这个对象的原型对象,propertiesObject 可选参数,用以对对象的属性进行描述。该方法可以在创建对象时指定原型或若干属性的对象。如:
- let obj1 = Object.create({ x: 1, y: 2 });
- // obj1继承了属性x和y。
- let obj2 = Object.create(null);
- //obj2不继承任何属性和方法。
- let obj3 = Object.create(Object.prototype);
- //obj3是一个普通的空对象。
1、每一个JavaScript对象(null除外)都和原型对象相关联。每一个对象都从原型继承属性。
2、所有通过对象字面量创建的对象都具有同一个原型对象,可通过Object.prototype获得原型对象的引用。
3、通过new和构造函数创建的对象的原型就是构造函数的prototype属性引用的对象。如:
- let book = new Object()
- book['author'] = {
- firstname: "xiao",
- lastname: "ming",
- }
- console.log(Object.prototype); // [Object: null prototype] {}
- console.log(Object.getPrototypeOf(book)); // [Object: null prototype] {}
- console.log(book.__proto__); // [Object: null prototype] {}
4、极少数的对象没有原型,如:Object.prototype,它不继承任何属性。
5、所有内置构造函数都具有一个继承自Object.prototype的原型。
示例:
- let obj = { value: 100 };
- Object.prototype.sex= "boy";
- console.log(obj.sex); // boy
- let arr = [1, 2, 3, 4];
- console.log(arr.sex); // 继承了Object新添加的sex属性,输出boy
若存在一个对象person,里面有fullname,sex,age属性。要访问这些属性,可以通过person.sex等进行访问。也可以通过person['sex'],如:
- let person = Object.create({
- fullname:"小明",
- age: 12,
- sex: "男"
- })
- console.log(person.fullname); // 小明
- console.log(person['age']); // 12
- console.log(person['sex']); // 男
举个例子:
- let result = {
- data1: {
- name: "Language",
- value: "Chinese",
- },
- data2: {
- name: "Country",
- value: "China",
- },
- data3: {
- name: "Gender",
- value: "Male",
- },
- };
- for (let i = 1; i < 4; i++) {
- let data = result["data" + i];
- console.log(`${data.name}-->${data.value}`);
- }
输出结果:
Language-->Chinese
Country-->China
Gender-->Male
原型链继承是将父类的实例作为子类的原型,继承后父类方法可以复用,但是父类的引用属性会被所有子类实例共享,并且子类构建实例时不能向父类传递参数。如:
- function Parent() {
- this.parentName = '父级函数';
- }
- Parent.prototype.getParentName = function () {
- return this.parentName;
- };
- function Child() {
- this.childName = '子级函数';
- }
- // 继承 Parent
- Child.prototype = new Parent();
- Child.prototype.getChildName = function () {
- return this.childName;
- };
- let a = new Child();
- console.log(a.getParentName());
运行结果:
父级函数
查询一个不存在的属性并不会报错,如果在对象o自身的属性或继承的属性中均未找到属性x,属性访问表达式o.x返回undefined。
但是,如果对象不存在,那么试图查询这个不存在的对象的属性就会报错。
null和undefined值都没有属性,因此查询这些值的属性会报错。
举个例子:
改变前:
- let one = { two: { three: 3 } };
- console.log(one.two.three);
- if (one) {
- if (one.two) {
- if (one.two.three) console.log(one.two.three);
- }
- }
- console.log(one && one.two && one.two.three);
- console.log(one?.two?.three); // Null传导运算符
输出:
3
3
3
3
改变后:
- let one = {};
- console.log(one.two.three);
- if (one) {
- if (one.two) {
- if (one.two.three) console.log(one.two.three);
- }
- }
- console.log(one && one.two && one.two.three);
- console.log(one?.two?.three); // Null传导运算符
输出结果:
TypeError: Cannot read property 'three' of undefined
在以下场景下给对象o设置属性p会失败:
delete运算符可以删除对象的属性。
举个例子:
- let book = new Object()
- book['author'] = {
- firstname: "xiao",
- lastname: "ming",
- }
- book.name="致明天",
- book.salenum=123456,
- book.price=12
- console.log("删除前:",book);
- delete book.author;
- delete book.toString()
- console.log("删除后:",book);
运行结果:
删除前: {
author: { firstname: 'xiao', lastname: 'ming' },
name: '致明天',
salenum: 123456,
price: 12
}
删除后: { name: '致明天', salenum: 123456, price: 12 }
判断某个属性是否存在于某个对象中,可以通过in运算符、hasOwnPreperty()和propertyIsEnumerable()方法,甚至也可以仅通过属性查询。如:
- let o = { x: 1 };
- console.log("x" in o); // true
- console.log("y" in o); // false
- console.log("toString" in o); // true
-
- console.log(o.hasOwnProperty("x")); // true
- console.log(o.hasOwnProperty("y")); // false
- console.log(o.hasOwnProperty("toString")); // false
-
- console.log(o.propertyIsEnumerable("x")); // true
- console.log(o.propertyIsEnumerable("y")); // false
- console.log(o.propertyIsEnumerable("toString")); // false
- console.log(Object.prototype.propertyIsEnumerable("toString")); // false
1、for/in循环可以在循环体中遍历对象中所有可枚举的属性(包括自有属性和继承的属性),把属性名称赋值给循环变量。
注意:对象继承的内置方法不可枚举的,但在代码中给对象添加的属性都是可枚举的。
- let obj = Object.create({ a: 10, b: 20 });
- obj.c = 30;
- for (let i in obj) {
- console.log(i, obj[i]);
- }
输出结果:
c 30
a 10
b 20
2、利用for/in循环,可以对两个对象进行各种形式的合并。
3、Object.keys(),它返回一个数组,这个数组由对象中可枚举的自有属性的名称组成。如:
- let obj = Object.create({ a: 10, b: 20 });
- obj.c = 30;
- obj.d = 40;
- console.log(Object.keys(obj));
输出结果:
[ 'c', 'd' ]
4、Object.getOwnPropertyNames(),它和Ojbect.keys()类似,只是它返回对象的所有自有属性的名称,而不仅仅是可枚举的属性。如:
- let obj = Object.create({ a: 10, b: 20 });
- obj.c = 30;
- obj.d = 40;
- console.log(Object.getOwnPropertyNames(obj));
输出结果:
[ 'c', 'd' ]
实例:
- let circle = {
- r: 10,
- get round() {
- return 2 * this.r * Math.PI
- },
- set round(v) {
- this.r = v / 2 / Math.PI
- },
- get area() {
- return Math.PI * this.r ** 2
- }
- }
- console.log(circle.round, circle.area)
- circle.round = 60
- console.log(circle.r, circle.area)
-
- let circle1 = Object.create(circle);
- // 和数据属性一样,存取器属性是可以继承的。
- circle1.r = 20;
- console.log(circle1.round);
- circle1.round = 500;
- console.log(circle1.r, circle1.area);
输出结果:
62.83185307179586 314.1592653589793
9.549296585513721 286.47889756541167
125.66370614359172
79.57747154594767 19894.367886486918
1、除了包含名字和值之外,属性还包含一些标识它们可写、可枚举和可配置的特性。
2、数据属性的4个特性
值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)。
3、存取器属性不具有值(value)特性和可写性。
4、通过一个名为“属性描述符”(property descriptor)的对象实现属性特性的查询和设置操作。
如:
- let circle = {
- r: 10,
- get round() {
- return 2 * this.r * Math.PI
- },
- set round(v) {
- this.r = v / 2 / Math.PI
- },
- get area() {
- return Math.PI * this.r ** 2
- }
- }
-
- let circle1 = Object.create(circle);
-
- console.log(Object.getOwnPropertyDescriptor(circle, "r"));
- console.log(Object.getOwnPropertyDescriptor(circle1, "r"));
输出:
{ value: 10, writable: true, enumerable: true, configurable: true }
undefined
5、要想设置属性的特性,或者想让新建属性具有某种特性,则需要调用Object.definePeoperty(),传入要修改的对象、要创建或修改的属性的名称以及属性描述符对象。传入Object.defineProperty()的属性描述符对象不必包含所有4个特性。如:
- let o = {};
- Object.defineProperty(o, "x", {
- value: 10,
- writable: true,
- enumerable: false,
- configurable: false,
- });
-
- console.log(o.x, Object.keys(o)); // 10 []
6、如果要同时修改或创建多个属性,使用Object.defineProperties()。第一个参数是要修改的对象,第二个参数是一个映射表,它包含要新建或修改的属性的名称,以及它们的属性描述符。如:
- let p = Object.defineProperties(
- {},
- {
- x: { value: 1, writable: true, enumerable: true, configurable: true },
- y: { value: 1, writable: true, enumerable: true, configurable: true },
- r: {
- get: function () {
- return Math.hypot(this.x, this.y);
- },
- enumerable: true,
- configurable: true,
- },
- }
- );
原型属性是在实例对象创建之初就设置好的。
要想检测一个对象是否是另一个对象的原型(或处于原型链中),使用isPrototypeOf()方法。(和instanceof运算符非常类似)
如:
- let o = { x: 1 };
- let p = Object.create(o);
- p.y = 2;
- console.log(Object.getPrototypeOf(p)); // { x: 1 }
- console.log(o.isPrototypeOf(p)); // true
对象的可扩展性用以表示是否可以给对象添加新属性。
1、对象序列化是指将对象的状态转换为字符串,也可将字符串还原为对象。
2、ES5提供了内置函数JSON.stringify()和JSON.parse()用来序列化和反序列化JavaScript对象。
3、注意事项
Object构造函数提供了如下方法:
方法 | 描述 |
---|---|
Object.assign() | 通过复制一个或多个对象来创建一个新的对象。 |
Object.create() | 使用指定的原型对象和属性创建一个新对象。 |
Object.defineProperty() | 给对象添加一个属性并指定该属性的配置。 |
Object.defineProperties() | 给对象添加多个属性并分别指定它们的配置。 |
Object.entries() | 返回给定对象自身可枚举属性的 [key, value] 数组。 |
Object.freeze() | 冻结对象,其他代码不能删除或更改任何属性。 |
Object.getOwnPropertyDescriptor() | 返回对象指定的属性配置。 |
Object.getOwnPropertyNames() | 返回一个数组,它包含了指定对象所有的可枚举或不可枚举的属性名 |
Object.getOwnPropertySymbols() | 返回一个数组,它包含了指定对象自身所有的符号属性。 |
Object.getPrototypeOf() | 返回指定对象的原型对象。 |
Object.is() | 比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)。 |
Object.isExtensible() | 判断对象是否可扩展。 |
Object.isFrozen() | 判断对象是否已经冻结。 |
Object.isSealed() | 判断对象是否已经密封。 |
Object.keys() | 返回一个包含所有给定对象自身可枚举属性名称的数组。 |
Object.preventExtensions() | 防止对象的任何扩展。 |
Object.seal() | 防止其他代码删除对象的属性。 |
Object.setPrototypeOf() | 设置对象的原型(即内部 [[Prototype]] 属性)。 |
Object.values() | 返回给定对象自身可枚举值的数组。 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。