Detailed explanation of JavaScript basic objects (organized and shared)

WBOY
Release: 2021-12-20 15:06:54
forward
1942 people have browsed it

This article brings you relevant knowledge about objects in JavaScript. Objects in JavaScript are also variables, but objects contain many values. I hope it will be helpful to you after reading this article.

Detailed explanation of JavaScript basic objects (organized and shared)

1. The basis of objects

1.1 Type

JavaScript has six main language types:

string, number, boolean, undefined, null, object

Basic types: string, number, boolean, undefined, null; the basic types themselves are not objects.

null

Butnullis sometimes regarded as an object, and typeof null will return object. In fact, null is a basic type. The reason is that different objects are represented as binary at the bottom level. In JavaScript, if the first three digits of the binary number are0, it will be judged as the object type, and null means all 0s, so typeof will return object.

Special object subtypes

Array

Array is also a type of object with some additional behaviors. The organization of arrays is more complex than ordinary objects.

Function

Functions are essentially the same as ordinary functions, except that they can be called, so you can operate functions in the same way as objects.

1.2 Built-in Object

String
Number
Date
Boolean
Object
Function
Array

1.3 Content

.a is called attribute access, and ['a'] is called operator access.

//对象中的属性名始终是字符串 myobj={} myobj[myobj]='bar'//赋值 myobj['[object object]'] //'bar'
Copy after login

1.4 Calculable attribute names

es6 Add computable attribute names, you can use [] in text form to wrap an expression as the attribute name

var perfix = 'foo' var myobj={ [perfix + 'bar'] :'hello' } myobj['foobar']//hello
Copy after login

1.5 Attribute descriptor

Starting from es5, all attributes have attribute descriptors. For example, you can directly determine whether the attribute is readable and writable.

/* * 重要函数: * Object.getOwnPropertyDescriptor(..) //获取属性描述符 * Object.defineProperty(..) //设置属性描述符 */ writeble(可读性) configurable(可配置性) enumerable (可枚举性)
Copy after login

1.6 Traversal

for in

for in can be used to traverse the enumerable attribute list of the object (including the [[Prototype]] chain), and you need to manually obtain the attribute value . Can traverse arrays and ordinary objects

for of

es6 is new and can be used to traverse the attribute values of arrays. The for of loop will first request an iterator object from the accessed object, and then Iterate through all return values by calling the next() method of the iterator object.
Arrays have built-in @@iterators,

how does for of work?

var arr = [1, 2, 3] var it = arr[Symbol.iterator]()//迭代器对象 console.log(it.next());//{value: 1, done: false} console.log(it.next());//{value: 2, done: false} console.log(it.next());//{value: 3, done: false} console.log(it.next());//{value: undefined, done: true} /* * 用es6 的Symbol.iterator 来获取对象的迭代器内部属性。 * @@iterator本身并不是一个迭代器对象,而是一个返回迭代器对象的函数。 */
Copy after login

How does an object have a built-in @@iterator to traverse the values of attributes?

Because the object does not have a built-in @@iterator, the for...of traversal cannot be automatically completed. However, you can define @@iterator for any object you want to traverse, for example:

var obj={ a:1,b:2 } Object.defineProperty(obj, Symbol.iterator, { enumerable: false, writable: false, configurable: true, value: function () { var self = this var idx = 0 var ks = Object.keys(self) return { next: function () { return { value: self[ks[idx++]], done: (idx > ks.length) } } } } }) //手动遍历 var it = obj[Symbol.iterator]()//迭代器对象 console.log(it.next());//{value: 1, done: false} console.log(it.next());//{value: 2, done: false} console.log(it.next());//{value: undefined, done: true} //for of 遍历 for (const v of obj) { console.log(v); } //2 //3
Copy after login

Other array traversal functions

/* forEach:会遍历所有并忽略返回值 some:会一直运行到回调函数返回 true(或者"真"值) every:会一直运行到回调函数返回 false(或者"假"值) map: filter:返回满足条件的值 reduce: some和every 和for的break语句类似,会提前终止遍历 */
Copy after login

2. Mixed class objects

Interview questions

1. Deep copy and shallow copy of objects

Related knowledge

Basic types and reference types

As mentioned above, the main language types of JavaScript There are six types: string, number, boolean, null, undefined, and object; the first five are basic types, and the last object is a reference type.

The storage methods of JavaScript variables: stack and heap

Stack: automatically allocates memory space and is automatically released by the system. It stores basic type values and reference types. The address of

Heap: dynamically allocated memory, the size is variable and will not be automatically released. Reference type values are stored in it

The biggest difference between basic types and reference types is the difference between passing by value and passing by address

Basic types use value passing; reference types use address (pointer) passing. Assign the address stored in stack memory to the received variable.

What are shallow copy and deep copy?

Shallow copy: A shallow copy of an object will copy the 'main' object, but will not copy the objects in the object. The 'inner object' is shared between the original object and its copy.

Deep copy: A deep copy of an object not only copies each attribute of the original object out one by one, but also deeply copies the objects contained in each attribute of the original object. The method is recursively copied to the new object, so modifications to one object will not affect the other object.

For example:

var anotherObject={ b:"b" } var anotherArray=[] var myObject={ a:'a', b:anotherObject, //引用,不是副本 c:anotherArray //另外一个引用 } anotherArray.push(anotherObject,myObject) /* 如何准确的复制 myObject? 浅复制 myObject,就是复制出 新对象中的 a 的值会复制出对象中a 的值,也就是 'a', 但是对象中的 b、c两个属性其实只是三个引用,新对象的b、c属性和旧对象的是一样的。 深复制 myObject,除了复制 myObject 以外还会复制 anotherObject 和 anotherArray。 但是这里深复制 myObject会出现一个问题,anotherArray 引用 anotherObject 和 myObject, 所以又需要复制 myObject,这样就会由于循环引用导致死循环。 后面会介绍如何处理这种情况。 */
Copy after login

How to implement shallow copy

object

object.assign(), spread operator (…)

var obj1 = {x: 1, y: 2} var obj2 = Object.assign({}, obj1); console.log(obj1) //{x: 1, y: 2} console.log(obj2) //{x: 1, y: 2} obj2.x = 2; //修改obj2.x console.log(obj1) //{x: 1, y: 2} console.log(obj2) //{x: 2, y: 2} var obj1 = { x: 1, y: { m: 1 } }; var obj2 = Object.assign({}, obj1); console.log(obj1) //{x: 1, y: {m: 1}} console.log(obj2) //{x: 1, y: {m: 1}} obj2.y.m = 2; //修改obj2.y.m console.log(obj1) //{x: 1, y: {m: 2}} console.log(obj2) //{x: 2, y: {m: 2}}
Copy after login

Array

slice(), concat, Array.from(), spread operator (...), concat, for loop

var arr1 = [1, 2, [3, 4]], arr2 = arr1.slice(); console.log(arr1); //[1, 2, [3, 4]] console.log(arr2); //[1, 2, [3, 4]] arr2[0] = 2 arr2[2][1] = 5; console.log(arr1); //[1, 2, [3, 5]] console.log(arr2); //[2, 2, [3, 5]]
Copy after login

How to implement deep copy

JSON.parse(JSON.stringify(obj))

During the serialization process of JSON.stringify(), undefined, arbitrary functions and symbol values will be ignored during the serialization process (appearing in non- when it is in the property value of an array object) or is converted to null (when it appears in an array).

var obj1 = { x: 1, y: { m: 1 }, a:undefined, b:function(a,b){ return a+b }, c:Symbol("foo") }; var obj2 = JSON.parse(JSON.stringify(obj1)); console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)} console.log(obj2) //{x: 1, y: {m: 1}} obj2.y.m = 2; //修改obj2.y.m console.log(obj1) //{x: 1, y: {m: 1}, a: undefined, b: ƒ, c: Symbol(foo)} console.log(obj2) //{x: 2, y: {m: 2}}
Copy after login

Simple implementation of deep copy function

function deepClone(obj){ let result = Array.isArray(obj)?[]:{}; if(obj && typeof obj === "object"){ for(let key in obj){ if(obj.hasOwnProperty(key)){ if(obj[key] && typeof obj[key] === "object"){ result[key] = deepClone(obj[key]); }else{ result[key] = obj[key]; } } } } return result; } var obj1 = { x: { m: 1 }, y: undefined, z: function add(z1, z2) { return z1 + z2 }, a: Symbol("foo"), b: [1,2,3,4,5], c: null }; var obj2 = deepClone(obj1); obj2.x.m = 2; obj2.b[0] = 2; console.log(obj1); console.log(obj2); //obj1 { a: Symbol(foo) b: (5) [1, 2, 3, 4, 5] c: null x: {m: 1} y: undefined z: ƒ add(z1, z2) } //obj2 { a: Symbol(foo) b: (5) [2, 2, 3, 4, 5] c: null x: {m: 2} y: undefined z: ƒ add(z1, z2) }
Copy after login

The above deep copy method encounters a circular reference and will fall into a cyclic recursive process, causing the stack to explode. Therefore improvements are needed.

Improvement of deep copy function (preventing loop recursion)

To solve the problem of stack explosion due to loop recursion, you only need to determine whether the fields of an object refer to this object or any parent of this object Level is enough.

function deepClone(obj, parent = null){ // 改进(1) let result = Array.isArray(obj)?[]:{}; let _parent = parent; // 改进(2) while(_parent){ // 改进(3) if(_parent.originalParent === obj){ return _parent.currentParent; } _parent = _parent.parent; } if(obj && typeof obj === "object"){ for(let key in obj){ if(obj.hasOwnProperty(key)){ if(obj[key] && typeof obj[key] === "object"){ result[key] = deepClone(obj[key],{ // 改进(4) originalParent: obj, currentParent: result, parent: parent }); }else{ result[key] = obj[key]; } } } } return result; } // 调试用 var obj1 = { x: 1, y: 2 }; obj1.z = obj1; var obj2 = deepClone(obj1); console.log(obj1); console.log(obj2);
Copy after login

Final version of deep copy function (supports basic data types, prototype chains, RegExp, and Date types)

function deepClone(obj, parent = null){ let result; // 最后的返回结果 let _parent = parent; // 防止循环引用 while(_parent){ if(_parent.originalParent === obj){ return _parent.currentParent; } _parent = _parent.parent; } if(obj && typeof obj === "object"){ // 返回引用数据类型(null已被判断条件排除)) if(obj instanceof RegExp){ // RegExp类型 result = new RegExp(obj.source, obj.flags) }else if(obj instanceof Date){ // Date类型 result = new Date(obj.getTime()); }else{ if(obj instanceof Array){ // Array类型 result = [] }else{ // Object类型,继承原型链 let proto = Object.getPrototypeOf(obj); result = Object.create(proto); } for(let key in obj){ // Array类型 与 Object类型 的深拷贝 if(obj.hasOwnProperty(key)){ if(obj[key] && typeof obj[key] === "object"){ result[key] = deepClone(obj[key],{ originalParent: obj, currentParent: result, parent: parent }); }else{ result[key] = obj[key]; } } } } }else{ // 返回基本数据类型与Function类型,因为Function不需要深拷贝 return obj } return result; } // 调试用 function construct(){ this.a = 1, this.b = { x:2, y:3, z:[4,5,[6]] }, this.c = [7,8,[9,10]], this.d = new Date(), this.e = /abc/ig, this.f = function(a,b){ return a+b }, this.g = null, this.h = undefined, this.i = "hello", this.j = Symbol("foo") } construct.prototype.str = "I'm prototype" var obj1 = new construct() obj1.k = obj1 obj2 = deepClone(obj1) obj2.b.x = 999 obj2.c[0] = 666 console.log(obj1) console.log(obj2) console.log(obj1.str) console.log(obj2.str)
Copy after login

Note: Deep copy of Function type:

bind(): Use fn.bind() to make a deep copy of the function, but it cannot be used because of the problem with the this pointer;

eval(fn.toString()): Only arrow functions are supported. Ordinary function function fn(){} is not applicable;

new Function(arg1,arg2,...,function_body): The parameters and function body need to be extracted;

PS: Generally not A deep copy of Function is required.

[Related recommendations:javascript learning tutorial]

The above is the detailed content of Detailed explanation of JavaScript basic objects (organized and shared). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:csdn.net
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!