What is an object
Object is the basic data type of JavaScript. It is an unordered collection of attributes, and each attribute is a key-value pair. There are two types of attributes: one is data attributes and the other is method attributes. (Another way of saying is: an object is a collection of key-value pairs, and an object is composed of attributes and methods)
Object attribute names are strings, so objects can be seen as a mapping from strings to values. The structure of string-to-value mapping usually has some other names, such as hash tables, dictionaries, and associative arrays.
JavaScript objects are dynamic. We can add and delete properties on the object. Except for string, number, true, false, null, undefined values in JS, all other values are objects.
How the object was created
Object direct quantity
The easiest way to create an object is to use object direct quantity. For example, the following code:
// 创建一个空对象
const o1 = {};
// 创建一个带有属性和方法的对象
const o2 = {
name: "thirteen",
class: "class",
age: 18,
say: function () {
console.log("console.log: say hello");
}
};
console.log(o2.class, "关键字当做属性名");
o2.say();
new operator (constructor)
The new operator creates and initializes a new object, and the new operator is followed by a function call. The function following new is called a constructor.
Use the constructor to create an object
let o = new Object(); // 创建一个空对象,和{}(对象直接量)一样
let a = new Array(); // 创建一个空数组对象,和[]一样
function papa(){};
let child = new papa(); // 通过实例化构造函数papa来创建一个对象。
Object.create
The Object.create method is a new method for creating objects in ES5. This method has two parameters. The first parameter must be the prototype of the newly created object, and the second parameter is the description of the object's properties. Object.create method returns a new object
grammar
Object.create(proto,[propertiesObject])
// 创建没有原型的新对象
const o1 = Object.create(null);
// 从该方法的介绍中我们可以看到,第一个参数是新创建对象的原型,
// o1创建的时候传入null,则表示o1是没有原型的新对象,没有原型,也就没有继承任何的方法和属性。
// 创建一个具有原型的对象
const o2 = Object.create(Object.prototype); // 相当于{}和new Object()创建对象一样
// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
const o3 = Object.create({}, { p: { value: 42 } })
const o4 = Object.create(Object.prototype, {
// foo会成为所创建对象的数据属性
foo: {
writable:true,
configurable:true,
value: "hello"
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function() { return 10 },
set: function(value) {
console.log("Setting `o.bar` to", value);
}
}
});
// 创建一个继承现有对象的新对象
const person = {
name:"thirteen",
age:18,
say:function(){
console.log(`name:${this.name},age:${this.age} `);
}
}
const o3 = Object.create(person);
o3.name === "thirteen" // true
o3.age === 18 // true
o3.say(); // name:thirteen,age:18
Use Object.create to implement class inheritance
// 父类
function parent(){
this.x = 0;
this.y = 0;
}
// 父类的方法
parent.prototype.move = function(x,y){
this.x += x;
this.y += y;
console.log('move 执行了');
}
// 子类
function child(){
parent.call(this);
}
// 子类继承父类
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
// 实例化
var o1 = new child();
console.log(o1 instanceof child);
console.log(o1 instanceof parent);
o1.move(2,2);
Object properties
A JavaScript object has many attributes. The attribute of an object can be interpreted as a variable attached to the object. Object properties are basically the same as ordinary JavaScript variables, except that the properties belong to an object.
Property query and setting (modification)
There are two ways to query and set properties. The first is to use the (•) dot operator. The second is to use the ([]) square bracket operator. In ES3, the "." operator cannot be followed by reserved words in JS, for example: for, class, function, etc., but this problem does not exist after ES5, so the following code is in modern browsers There will be no problems. obj.for = "for"
. If you use square brackets [], the middle of the square brackets must be an expression whose result is a string before ES6. In modern browsers, the symbol type can also be in the middle of the square bracket expression.
Dot operator
// 定义一个对象o1
const o1 = {
name:"thirteen",
age:18
}
// 读取对象o1的属性
o1.name // thirteen
o1.age // 18
// 修改对象o1的属性,如果属性名原来就有,就是修改,如果原来对象上没有该属性,就是新增
o1.sex = "男";
o1.say = function(){
console.log('i say');
}
console.log(o1.name);
//
const name = "thirteen";
const age = 18;
const o2 = {
name,
age
}
o2.name // thirteen
o2.age // 18
Square bracket operator
When accessing (adding, modifying) the properties of an object through [], the property name is represented by a string. Strings are the basic data type of JS, we can modify and create them while the program is running. Because of the square brackets this way of accessing objects, sometimes objects are also called associative arrays, but the index of the array is a number, and the index of the object is a string.
const addr = "";
const obj = {
p0:"p0",
p1:"p1",
p2:"p2",
p3:"p3"
};
for(i=0;i<4;i++){
addr += obj["p"+i] + '\n';
}
// 当对象的属性名字无法确认(动态)的时候,只能通过方括号访问
function addStock(portfolio,name,shares){
portfolio[name] = shares;
}
//同时创建四个变量,用逗号分割
const myObj = new Object(),
str = "myString",
rand = Math.random(),
obj = new Object();
myObj.type = "点运算符";
myObj['data create'] = '有空格的字符串';
myObj[str] = "字符串值";
myObj[rand] = "随机数";
myObj[obj] = "Object 对象";
myObj[""] = "空字符串";
// PS:方括号中所有的键都将转换为字符串类型。
Comparison of the two ways
dot operator
- Easy to use and flexible
- There are certain restrictions. When the properties of the object are strings starting with numbers, empty strings, or hyphens, they cannot be accessed using the dot operator
- The identifier immediately following the dot operator is static and must be hard-coded in the program
square bracket operator
- Use comprehensively, all the inaccessible attributes that can be accessed by the dot operator, and the square brackets can be accessed
- When the properties of the object cannot be known in advance, you can only use the square bracket operator
Deletion of attributes
The delete operator can delete the attributes of an object; however, it can only delete the attributes of the object itself, not the attributes inherited by the object. In addition, if the configurable value of the object's property is false, it cannot be deleted. After the delete expression is executed successfully, it will return a true
const o1 = {
name:"thirteen"
}
Object.defineProperty(o1, 'age', {
value: 42,
configurable: false
});
// 可以删除
delete o1.name
console.log(o1.name) // 返回undefined
// 不可以删除,因为属性的可配置值configurable是false
delete o1.age
console.log(o1.age) // 返回42
// 不可以删除
delete o1.toString
Enumeration of attributes
Attribute traversal order
- First traverse the number keys, according to the method of whoever is smaller
- Then traverse the string keys and arrange them according to their position in the object
- Finally, it traverses the Symbols and arranges them in ascending order according to the time they were added.
// 对象属性遍历的次序
Reflect.ownKeys({
[Symbol()]:0,
b:0,
10:0,
2:0,
a:0
})
// 返回结果
['2','10','a','b',Symbol()]
for...in loop
This method sequentially accesses an object and all enumerable properties in its prototype chain
const o = {
x: 1,
y: 2,
z: 3,
};
// 对象 o1 继承 对象o
const o1 = Object.create(o, {
foo: {
writable: true,
configurable: true,
enumerable:true, // 可以被枚举
value: "hello",
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function () {
return 10;
},
set: function (value) {
console.log("Setting `o.bar` to", value);
},
},
});
console.log("打印对象o1的属性名和属性值");
for (prop in o1) {
console.log(`${prop}:${o1[prop]}`);
}
// foo:hello x:1 y:2 z:3
// 给对象o1新增a属性,属性可枚举配置为true 能够遍历得到
Object.defineProperty(o1, "a", {
value: "4",
enumerable: true,
});
// 给对象o1新增b属性,属性可枚举配置为false 不能能够遍历得到
Object.defineProperty(o1, "b", {
value: "5",
enumerable: false,
});
console.log("打印对象o1可枚举的属性名和属性值");
for (prop in o1) {
console.log(`${prop}:${o1[prop]}`);
}
//foo:hello x:1 y:2 z:3 a:4
Object.keys(obj)
This method returns an array of names of all enumerable properties contained in the object obj itself (not including the prototype)
const o = {
x: 1,
y: 2,
z: 3,
};
// 对象o1继承o,
const o1 = Object.create(o);
o1.name = "thirteen";
o1.age = 18;
const resultArray = Object.keys(o1);
console.log(resultArray,'打印对象可枚举属性的名称数组');
// [name,age]
// 给对象o1新增a属性,属性可枚举配置为true 能够遍历得到
Object.defineProperty(o1, "a", {
value: "4",
enumerable: true,
});
// 给对象o1新增b属性,属性可枚举配置为false 不能能够遍历得到
Object.defineProperty(o1, "b", {
value: "5",
enumerable: false,
});
const resultArray1 = Object.keys(o1);
console.log(resultArray1,'打印对象可枚举属性的名称数组');
// [name,age,a]
Object.getOwnPropertyNames(obj)
This method returns an array of the names of all properties (whether enumerable or not) contained in the object obj itself (excluding the prototype).
const o = {
x: 1,
y: 2,
z: 3,
};
const o1 = Object.create(o, {
sex: {
enumerable: false,
value: "男",
},
height: {
enumerable: true,
value: 165,
},
});
o1.name = "thirteen";
o1.age = 18;
const resultArray = Object.getOwnPropertyNames(o1);
console.log(resultArray, "打印对象可枚举属性的名称数组");
// [sex,height,name,age]
// 给对象o1新增a属性,属性可枚举配置为true 能够遍历得到
Object.defineProperty(o1, "a", {
value: "4",
enumerable: true,
});
// 给对象o1新增b属性,属性可枚举配置为false 不能能够遍历得到
Object.defineProperty(o1, "b", {
value: "5",
enumerable: false,
});
const resultArray1 = Object.getOwnPropertyNames(o1);
console.log(resultArray1, "打印对象可枚举属性的名称数组");
// [sex,height,name,age,a,b]
Object.getOwnPropertySymbols(obj)
Returns an array containing the keys of all Symbol properties of the object obj itself
const mySymbol = Symbol("mySymbol");
const mySymbol1 = Symbol("mySymbol1");
const mySymbol2 = Symbol("mySymbol2");
const mySymbol3 = Symbol("mySymbol3");
const o = {
[mySymbol]: 1,
y: 2,
z: 3,
};
const o1 = Object.create(o, {
sex: {
enumerable: false,
value: "男",
},
height: {
enumerable: true,
value: 165,
},
});
o1.name = "thirteen";
o1.age = 18;
o1[mySymbol1] = "mySymbol1";
const resultArray = Object.getOwnPropertySymbols(o1);
console.log(resultArray, "打印对象Symbol属性的键名数组");
// [symbol(mySymbol1)]
// 给对象o1新增a属性,属性可枚举配置为true 能够遍历得到
Object.defineProperty(o1, mySymbol2, {
value: "4",
enumerable: true,
});
// 给对象o1新增b属性,属性可枚举配置为false 不能能够遍历得到
Object.defineProperty(o1, mySymbol3, {
value: "5",
enumerable: false,
});
const resultArray1 = Object.getOwnPropertySymbols(o1);
console.log(resultArray1, "打印对象Symbol属性的键名数组");
// [symbol(mySymbol1),symbol(mySymbol2),symbol(mySymbol3)]
Reflect.ownKeys(obj)
Returns an array containing all the keys of the object itself, regardless of whether the key is a Symbol or a string, or whether it is enumerable or not.
const mySymbol = Symbol("mySymbol");
const mySymbol1 = Symbol("mySymbol1");
const mySymbol2 = Symbol("mySymbol2");
const mySymbol3 = Symbol("mySymbol3");
const o = {
[mySymbol]: 1,
y: 2,
z: 3,
};
const o1 = Object.create(o, {
sex: {
enumerable: false,
value: "男",
},
height: {
enumerable: true,
value: 165,
},
});
o1.name = "thirteen";
o1.age = 18;
o1[mySymbol1] = "mySymbol1";
const resultArray = Reflect.ownKeys(o1);
console.log(resultArray, "打印对象自身所有属性的键名数组");
// [sex,height,name,age,Symbol(mySymbol1)]
// 给对象o1新增a属性,属性可枚举配置为true 能够遍历得到
Object.defineProperty(o1, mySymbol2, {
value: "4",
enumerable: true,
});
// 给对象o1新增b属性,属性可枚举配置为false 不能能够遍历得到
Object.defineProperty(o1, "b", {
value: "5",
enumerable: false,
});
const resultArray1 = Reflect.ownKeys(o1);;
console.log(resultArray1, "打印对象Symbol属性的键名数组");
// [ "sex", "height", "name", "age", "b", Symbol(mySymbol1), Symbol(mySymbol2) ]
Properties of the property
In addition to containing names and values, attributes also contain some features that mark them as writable, enumerable, and configurable. These contents cannot be set in ES3, but after ES5. Attributes can be divided into "accessor attributes" (attributes defined by getters and setters) and "data attributes". Different attributes have different characteristics.
attributes
- get // read
- set // write
- enumerable // Whether it can be enumerated (traverse reading)
- configurable // If and only if the configurable key value of the attribute is true, the descriptor of the attribute can be changed, and the attribute can also be deleted from the corresponding object.
Data attributes
- value // attribute value
- writable // Whether the attribute is writable (can it be modified)
- enumerable // Whether it can be enumerated (traversely read)
- configurable
Get the attribute description of the attribute
The property description of a specific property of an object can be obtained by calling the Object.getOwnPropertyDescriptor method, for example:
const o = {
x: "我是X",
y: 2,
z: 3,
};
const o1 = Object.create(o);
o1.age = 18;
Object.defineProperty(o1, "name", {
value: "thirteen",
writable: true,
configurable: true,
enumerable: true,
});
const ageDesc = Object.getOwnPropertyDescriptor(o1, "age");
const nameDesc = Object.getOwnPropertyDescriptor(o1, "name");
const xDesc = Object.getOwnPropertyDescriptor(o1, "x");
//
console.log(ageDesc, "获取自有属性age默认的属性描述");
console.log(nameDesc, "获取自有属性name配置的属性描述");
console.log(xDesc, "获取继承属性X的属性描述");
// 如果想要获取继承的属性的属性描述,需要通过Object.getPrototypeOf方法先遍历原型链
const xdesc2 = Object.getOwnPropertyDescriptor(
Object.getPrototypeOf(o1),
"x"
);
console.log(xdesc2, "获取继承属性X的属性描述");
Property getter and setter
The attributes of an object are made up of names, values, and a set of characteristics. After ES5, the value of the property can be replaced by one or two methods, these two methods are getter and setter. The attributes defined by getters and setters are called "accessor attributes". Unlike "data attributes", data attributes have only one simple value.
When we use getters and setters to define properties, we can monitor the read and write actions of the properties. For example, in the VUE framework, the Object.defineProperty method is used to rewrite all the properties in the data object, so that when the value of data is When there is a change, you can update the template in vue;
Accessor properties can also intelligently check the written value of the property, and return a different value each time the property is read;
// 如何定义,第一种
const o1 = {
name: "thirteen",
$age: 18,
get age() {
return this.$age;
},
set age(v) {
this.$age = v;
},
};
console.log("第一种返回");
console.log(o1.age); // 18
o1.age = 20;
console.log(o1.age); // 20
// 第二种
const o2 = {
$age: 18,
};
let ageValue = 18;
Object.defineProperty(o2, "age", {
get: function () {
return ageValue;
},
set: function (value) {
ageValue = value;
},
});
console.log("第二种返回");
console.log(o2.age); // 18
o2.age = 20;
console.log(o2.age); // 20
// 第三种:当使用Object.create 方法创建对象的时候
const o3 = Object.create(Object.prototype, {
// foo会成为所创建对象的数据属性
foo: {
writable: true,
configurable: true,
value: "hello",
},
// bar会成为所创建对象的访问器属性
bar: {
configurable: false,
get: function () {
return 10;
},
set: function (value) {
console.log("Setting `o.bar` to", value);
},
},
});
console.log("第三种返回");
console.log(o3.bar); // 10
o3.bar = 20; // 打印 『Setting o.bar to 20』
// 读取对象属性时,每次返回不同的值
const serialnum = {
$n: 0,
get next() {
return this.$n++;
},
set next(n) {
if (n >= this.$n) this.$n = n;
else throw "序列号的值不能比当前值小";
},
};
console.log("序列号属性返回")
console.log(serialnum.next); // 0
console.log(serialnum.next); // 1
console.log(serialnum.next); // 2
console.log(serialnum.next); // 3
console.log(serialnum.next); // 4
console.log(serialnum.next); // 5
// 每次读取属性都返回一个随机数
const random = {
get octet() {
// 返回0~255之间的数字
return Math.floor(Math.random() * 256);
},
get uint16() {
// 返回0~65535之间的数字
return Math.floor(Math.random() * 65536);
},
get int16() {
// 返回-32768~(65535-32768)之间的数字
return Math.floor(Math.random() * 65536) - 32768;
},
};
console.log("随机数打印结果")
console.log(random.octet);
console.log(random.octet);
console.log(random.octet);
console.log(random.uint16);
console.log(random.uint16);
console.log(random.uint16);
console.log(random.int16);
console.log(random.int16);
console.log(random.int16);
Object method
When we pass object direct measurement, new Object() and Object.create() without passing in null, the created object will be associated with another object. The "another" object is the prototype we are familiar with. Every object is derived from Prototype inheritance properties;
So when we create a new object, the object has some methods that can be used, and these methods are inherited from the prototype.
toString
Returns a string representing the value of the object that called this method.
toLocaleString
Similar to toString, the difference is customized processing for different types of objects, such as Data and Number objects
valueOf
Similar to toString, it is often called when JavaScript needs to convert an object to some primitive value instead of a string.
other
new Object()
Create an object in the form of a constructor. The new Object() method accepts one parameter; here are some examples:
const o = new Object();
console.log(o,'不传入任何参数');
const o1 = new Object(null);
console.log(o1,'传入null');
const o2 = new Object(undefined);
console.log(o2,'传入undefined');
// 相当于 const o3 = new Boolean(true);
const o3 = new Object(true);
console.log(o3,'传入true');
// 相当于 const o4 = new String("3");
const o4 = new Object("3");
console.log(o4,'传入字符串');
const o5 = new Object(function(){});
console.log(o5,'传入函数');
const o6 = new Object(function(){
return [1,2,3]
});
console.log(o6,'传入函数');
// 相当于 const o4 = new Boolean(false);
const o7 = new Object(Boolean());
console.log(o7,'传入对象');
Print result:
super keyword
The this in the object points to the current object, a new super keyword has been added in ES6, and the super keyword points to the prototype object of the object;
const parent = {
name: 'papa'
};
const child = {
name: 'child',
say() {
return super.name;
}
};
// 通过setProtoTypeOf 设置对象child的原型是parent
Object.setPrototypeOf(child, parent);
child.say() // "papa"
PS: Note that when the super keyword represents a prototype object, it can only be used in the method of the object, and it will report an error when used in other places.
Details Reference: ES6-- extended object
For more extensions of JavaScript objects, refer to Ruan Yifeng's ES6 object extension section
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。