Article directory
1. this points to the question
This points to: The point of this cannot be determined in the function definition. Only when the function is executed can it be determined who this points to. In general, the point of this is the object that calls it.
Generally divided into the following three situations:
- In the global scope or normal function, this points to the global object window
- In the method call, who calls this and points to whom
- In the constructor this points to the instance of the constructor
1. In the global scope or ordinary function, this points to the global object window
The function call in the global scope is called by the window object, but when calling, it is generally omitted
window.
, that is, it isfn()
actuallywindow.fn
console.log(this); // Window {window: Window, …}
function fn() {
console.log(this); // Window {window: Window, …}
}
fn(); // 等同于window.fn()
// 等同于window.setTimeout()
setTimeout(function () {
console.log(this); // Window {window: Window, …}
}, 1000);
2. Who calls this in the method call and points to whom
obj = {
fn: function () {
console.log(this); // {fn: ƒ}
}
};
obj.fn(); // obj对象调用了fn方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>点击一下</button>
<script>
var btn = document.querySelector("button");
// btn调用了匿名函数
btn.addEventListener("click", function () {
console.log(this); // <button>点击一下</button>
});
</script>
</body>
</html>
3. In the constructor, this points to the instance of the constructor
When creating an object, a new space will be opened, and this will point to this object
function Person() {
console.log(this); // Person {}
}
var person = new Person(); // this指向的是person实例对象
2. Advanced objects
2.1 Definition and use of objects
1. Create objects using literals
// 创建对象
var obj = {
name: "Bill",
age: 18,
sex: "男",
sayHi: function () {
console.log("hi");
}
};
// 获取对象的属性
console.log(obj.age);
console.log(obj["age"]);
// 调用对象的方法
obj.sayHi();
2. Use the new keyword to create an object
// 创建空对象
var obj = new Object();
// 设置对象的属性和方法
obj.name = "Bill";
obj.age = 18;
obj.sex = "男";
obj.sayHi = function () {
console.log("hi");
};
// 获取对象的属性
console.log(obj.age);
console.log(obj["age"]);
// 调用对象的方法
obj.sayHi();
Note: It is not recommended to use the new keyword to create objects
2.2 Object Accessor
Getter
and the role Setter
of :
- Provides a more concise syntax
- Allow properties and methods to have the same syntax
- Can ensure better data quality
Note: The method name of
getter
and cannot be the same as the property namesetter
2.2.1 Getter
Getter
: Use get
the keyword to get the attribute value of the object.
var person = {
name: "Bill",
age: 18,
get uname() {
return this.name;
},
get uage() {
return this.age;
}
};
console.log(person.uname); // Bill
console.log(person.uage); // 18
2.2.2 Setter
Setter
: Use set
the keyword to set the attribute value of the object.
var person = {
name: "Bill",
age: 18,
set uname(value) {
this.name = value;
},
set uage(value) {
this.age = value;
}
};
person.uname = "Jackson";
person.uage = 20;
console.log(person.name, person.age); // Jackson 20
2.3 Object Constructor
Object constructor: It is a constructor, which can create objects of the same type by calling the constructor through new
keywords .
The role of the constructor: using 2.1
the method of creating objects in the section, only a single object can be created, but through the constructor, many objects of the same type can be created.
1. Use the constructor to create multiple objects of the same type
// 1.定义构造函数
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayHi = function () {
console.log("hi");
};
}
// 2.调用构造函数来创建对象
var teacher = new Person("Jackson", 40, "male");
var student = new Person("Bill", 18, "male");
// 3.获取对象的属性
console.log(teacher.name); // Jackson
console.log(student.name); // Bill
// 4.调用对象的方法
teacher.sayHi(); // hi
student.sayHi(); // hi
Analysis: Two object instances
teacher
andstudent
, and the two object instances have the same properties and methods
2. Add properties and methods to objects
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sayHi = function () {
console.log("hi");
};
}
var student = new Person("Bill", 18, "male");
// 为对象添加属性
student.nationality = "English";
// 为对象添加方法
student.sayHello = function () {
console.log("hello");
};
console.log(student);
2.4 Object Prototype
Constructor and prototype object: After declaring a constructor, the constructor will have a prototype
property, which refers to the prototype object of the constructor.
The role of the prototype object: the method of the constructor will waste memory, and the method of the constructor through the prototype allocation is shared by all objects, that is, the same block of memory can be reused to avoid wasting memory.
Several properties related to the prototype:
prototype
__proto__
constructor
2.4.1 prototype property
prototype
: Each constructor has a prototype property, pointing to another object. This prototype is an object (prototype object), and all properties and methods of this object will be owned by the constructor.
We can define the invariant methods directly on the prototype object, so that all object instances can share these methods.
Summary:
1. The prototype is an object
2. The role of the prototype object is to realize the sharing of methods
1. new
Each will open up a new memory space. When the method is defined inside the constructor, it will cause memory waste.
function Person(name, age) {
this.name = name;
this.age = age;
this.sayHi = function () {
console.log("hi");
};
}
var teacher = new Person("Jackson", 40);
var student = new Person("Bill", 18);
console.log(teacher.sayHi === student.sayHi); // false
Analysis: When creating two object instances of teacher and student, the two instances open up different memory spaces (including name, age attribute and sayHi method), so the addresses pointed to by these two instance methods are different. After comparison The result obtained is
false
2. Put the method inside the constructor on the prototype object of the constructor, only open up memory space for the method once, and the method can be reused, thus avoiding memory waste.
function Person(name, age) {
this.name = name;
this.age = age;
}
// 将构造函数的方法定义到原型对象上
Person.prototype.sayHi = function () {
console.log("hi");
};
var teacher = new Person("Jackson", 40);
var student = new Person("Bill", 18);
console.log(teacher.sayHi === student.sayHi); // true
Analysis: Since the sayHi method is defined on the prototype object, every time an object instance is new, the method of the instance points to the sayHi method of the prototype object (the same memory space), so the addresses pointed to by these two instance methods are the same , the result obtained after comparison is
true
2.4.2 The __proto__ attribute
__proto__
: Every object has an __proto__
attribute, which points to the prototype
prototype object of the constructor. The reason why the object can use prototype
the object's attributes and methods is because of __proto__
the existence of the object.
1. Point to the prototype object __proto__
of the constructorprototype
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log("hi");
};
var student = new Person("Bill", 18);
console.log(student.__proto__);
The running results are as follows: You can see __proto__
that there is sayHi
a method, and this method is defined on prototype
the object, that is to say, __proto__
it points to prototype
the prototype object
Note: here
[[Prototype]]
can be roughly understood as__proto__
2. __proto__
Pointed to prototype
, so the two are actually equivalent
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log("hi");
};
var student = new Person("Bill", 18);
console.log(student.__proto__ === Person.prototype); // true
2.4.3 constructor attribute
constructor
: __proto__
and prototype
inside both have an constructor
attribute constructor
called constructor because it points back to the constructor itself.
constructor
It is used to record which constructor the object refers to, and it can make the prototype object point to the original constructor again.
1. constructor
Point to the constructor of the prototype object reference
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log("hi");
};
var student = new Person("Bill", 18);
console.log(Person.prototype.constructor);
console.log(student.__proto__.constructor);
The result of the operation is as follows:
2. You can use constructor
the attribute to point the prototype object back to the original constructor
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
// 使用constructor属性,将原型对象指回Person构造函数
constructor: Person,
sayHi: function () {
console.log("Hi");
},
sayHello: function () {
console.log("Hello");
}
};
var student= new Person("Bill", 18);
student.sayHi();
student.sayHello();
Note: If we assign an object to the prototype object, the prototype object will lose the constructor attribute. At this time, we need to manually add the constructor attribute back and point back to the original constructor.
2.4.4 Prototype chain
Prototype chain: JavaScript objects have a chain pointing to a prototype object. When trying to access a property of an object, it searches not only on the object, but also on the object's prototype, and on the prototype of the object's prototype, and so on until it finds a property with a matching name or reaches the prototype the end of the chain.
- First understand the relationship between constructors, instances and prototype objects, and then understand the prototype chain
- The prototype chain is
__proto__
to look up the prototype object layer by layerprototype
until the top prototype object is foundObject.prototype
- In each layer of the prototype chain, there is a relationship between the constructor, the instance and the prototype object
Through the following example, analyze the relationship among constructors, instances and prototype objects, as well as the prototype chain:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function () {
console.log("hi");
};
var student = new Person("Bill", 18);
console.log(student.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null
Analysis:
1.student.__proto__
points toPerson.prototype
2.Person.prototype.__proto__
points toObject.prototype
3.Object.prototype
is the top-level prototype object, soObject.prototype.__proto__
points tonull
1. The relationship between constructors, instances and prototype objects
2. Prototype chain
2.5 Object object
2.5.1 Management objects
Methods of managing objects:
method | describe |
---|---|
create() |
Create new objects based on existing objects |
defineProperty() |
Add or change individual properties of an object |
defineProperties() |
Add or change multiple properties of an object property |
getOwnPropertyDescriptor() |
Get the descriptor for a single property of an object |
getOwnPropertyDescriptors() |
Get descriptors for all properties of an object |
getOwnPropertyNames() |
Return all properties as an array |
getPrototypeOf() |
Get the prototype of the object |
keys() |
Returns enumerable properties as an array |
create
method to create a new object based on an existing object
var person = {
name: "Bill",
age: 18,
sayHi: function () {
console.log("Hi");
}
};
// 以person对象为原型,创建一个新对象student
var student = Object.create(person);
student.age = 28;
console.log(student.name); // Bill
console.log(student.age); // 28
student.sayHi(); // Hi
Analysis:
student.name
andstudent.sayHi()
can be used because the person object is the prototype of the student object, the student object inherits the properties and methods of the person object, andstudent.age
28 is because the student object covers the age attribute of the person object
2. defineProperty
Methods for adding or changing object properties
Object.defineProperty(obj, prop, descriptor)
:
obj
: Object to define propertiesprop
: The name of the property to define or modifydescriptor
: property descriptor to define or modify
Attribute descriptors are divided into data descriptors and access descriptors:
- A data descriptor is an attribute with a value, which may or may not be writable
- An access descriptor is an attribute described by a getter function and a setter function
- Data descriptors and access descriptors cannot be mixed
data descriptor | describe |
---|---|
value |
attribute value |
writable |
Whether the attribute value can be changed |
enumerable |
Whether the attribute is enumerable |
configurable |
Whether the attribute can be deleted |
access descriptor | describe |
---|---|
get() |
When the property is accessed, this function is called |
set() |
This function is called when the property value is modified |
Data descriptor:
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
// 设置name属性为只读
Object.defineProperty(person, "name", {
writable: false });
person.name = "Jackson";
console.log(person.name); // Bill
// 设置age属性为不可枚举
Object.defineProperty(person, "age", {
enumerable: false });
for (var i in person) {
console.log(i); // name addr
}
// 设置addr属性为不可删除
Object.defineProperty(person, "addr", {
configurable: false });
delete person.addr;
console.log(person.addr); // Shanghai
Access descriptor:
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
// 添加getter和setter
Object.defineProperty(person, "uage", {
get() {
return this.age;
},
set(value) {
this.age = value;
}
});
// 访问getter
console.log(person.uage); // 18
// 访问setter
person.uage = 28;
console.log(person.uage); // 28
console.log(person.age); // 28
3. defineProperties
Method, used to add or change object properties, can operate multiple properties of an object at the same time
Object.defineProperties(obj, props)
:
- object to define properties
- The object whose enumerable properties or modified property descriptors are to be defined
Data descriptor:
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
// 同时定义person对象的多个属性
Object.defineProperties(person, {
name: {
writable: false
},
age: {
enumerable: false
},
addr: {
configurable: false
}
});
// name属性只读
person.name = "Jackson";
console.log(person.name); // Bill
// age属性不可枚举
for (var i in person) {
console.log(i); // name addr
}
// addr属性不可删除
delete person.addr;
console.log(person.addr); // Shanghai
Access descriptor:
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
// 同时定义person对象的多个属性
Object.defineProperties(person, {
uname: {
get() {
return this.name;
},
set(value) {
this.name = value;
}
},
uage: {
get() {
return this.age;
},
set(value) {
this.age = value;
}
}
});
// 访问uname属性
console.log(person.uname); // Bill
person.uname = "Jackson";
console.log(person.uname); // Jackson
// 访问uage属性
console.log(person.uage); // 18
person.uage = 28;
console.log(person.uage); // 28
4. getOwnPropertyDescriptor
and getOwnPropertyDescriptors
method , used to obtain the descriptor of the object property
Get the descriptor for a single property of an object:getOwnPropertyDescriptor(obj, prop)
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
var descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor); // {value: 'Bill', writable: true, enumerable: true, configurable: true}
Get descriptors for all properties of an object:getOwnPropertyDescriptors(obj)
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
var descriptor = Object.getOwnPropertyDescriptors(person);
console.log(descriptor.name); // {value: 'Bill', writable: true, enumerable: true, configurable: true}
console.log(descriptor.age); // {value: 18, writable: true, enumerable: true, configurable: true}
console.log(descriptor.addr); // {value: 'Shanghai', writable: true, enumerable: true, configurable: true}
5. getOwnPropertyNames
Method to return the attribute names of all attributes in an array
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
var properties = Object.getOwnPropertyNames(person);
console.log(properties); // ['name', 'age', 'addr']
6. getPrototypeOf
Method, used to access the prototype of the object
var person = {
name: "Bill",
age: 18,
sayHi: function () {
console.log("Hi");
}
};
var student = Object.create(person); // 以person对象为原型,创建一个新对象student
var prototype = Object.getPrototypeOf(student); // 获取student的原型
console.log(prototype); // {name: 'Bill', age: 18, sayHi: ƒ}
// student的原型就是person对象,而person的原型是Object的原型
console.log(prototype == person); // true
console.log(Object.getPrototypeOf(person) == Object.prototype); // true
7. keys
Method that returns enumerable properties as an array
var person = {
name: "Bill",
age: 18,
addr: "Shanghai"
};
Object.defineProperty(person, "age", {
enumerable: false }); // 设置age属性为不可枚举
console.log(Object.keys(person)); // ['name', 'addr']
2.5.2 Protected objects
Methods to protect objects:
method | describe |
---|---|
preventExtensions() |
Prevent adding properties to objects |
isExtensible() |
Returns true if the object is extensible |
seal() |
Prevent adding and removing attributes |
isSealed() |
Returns true if the object is sealed |
freeze() |
prevent any changes to the object |
isFrozen() |
Returns true if the object is frozen |
Summary: The above
preventExtensions
,seal
,freeze
and three methods limit the object progressively.
1.preventExtensions
: Objects cannot add attributes, but can modify and delete attributes
2.seal
: Objects cannot add and delete attributes, but can modify attributes
3.freeze
: Objects cannot add, delete, and modify attributes
1. preventExtensions
The method makes an object non-extensible and prevents adding properties to the object
var person = {
name: "Bill",
age: 18
};
Object.preventExtensions(person); // 防止对象添加属性
Object.defineProperty(person, "addr", {
value: "Shanghai" }); // Uncaught TypeError
2. isExtensible
Method that returns true if the object is extensible
var person = {
name: "Bill",
age: 18
};
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); // false
3. seal
Method, encloses an object, prevents adding new properties, and does not allow deletion of existing properties
var person = {
name: "Bill",
age: 18
};
Object.seal(person); // 防止对象添加和删除属性
person.addr = "Shanghai";
delete person.age;
console.log(person); // {name: 'Bill', age: 18}
4. isSealed
method that returns true if the object is sealed
var person = {
name: "Bill",
age: 18
};
Object.seal(person);
console.log(Object.isSealed(person)); // true
5. freeze
Method, freeze an object, that is, the object cannot add, delete and modify attributes
var person = {
name: "Bill",
age: 18
};
Object.freeze(person); // 防止对象添加、删除和修改属性
person.addr = "Shanghai";
delete person.age;
person.name = "Jackson";
console.log(person); // {name: 'Bill', age: 18}
6. isFrozen
Method that returns true if the object is frozen
var person = {
name: "Bill",
age: 18
};
Object.freeze(person);
console.log(Object.isFrozen(person)); // true
3. Advanced functions
3.1 Definition and use of functions
1. Declaration and call of ordinary functions
// 函数声明
function getSum(x, y) {
return x + y;
}
getSum(1, 2); // 函数调用
2. Function expression
1. Functions can be defined using expressions
2. Functions defined using expressions are anonymous functions
// 函数声明
var sum = function (x, y) {
return x + y;
};
sum(1, 2); // 函数调用
3. Function improvement
1. Hoisting: The default behavior of moving declarations to the top of the current scope
2. Functions defined using function expressions will not be hoisted
// 函数调用
getSum(1, 2);
// 函数声明
function getSum(x, y) {
return x + y;
}
Analysis: Because the function declaration is promoted to the top of the scope, the function call is actually after the function declaration, so no error will be reported.
4. Self-invoking functions
- Function expressions can act as "self-invocations"
- expression followed by
()
the function expression is automatically executed - cannot self-call a function declaration
// 函数自调用
(function () {
console.log("Hello World");
})();
var sum = (function (x, y) {
return x + y;
})(1, 2);
console.log(sum); // 3
5. Functions are objects
Functions are
function
objects, so functions have properties and methods
function getSum(x, y) {
return x + y;
}
console.log(typeof getSum); // function
3.2 Function object
Function object: Each js function is a Function object.
Methods of the Function object:
call()
: The function will be called and the this point inside the function will be changedapply()
: The function will be called and the this point inside the function will be changedbind()
: The function will not be called, and the this point inside the function can be changed
1. The three methods of call, apply and bind can change the this point inside the function.
2. The call and apply methods will call the function, but the bind method will not call the function.
3. The parameters passed by call and apply are different, and the method of passing parameters by call Yesarg1,arg2
, and apply must be in the form of an array[args]
3.2.1 call
grammar:function.call(thisArg, arg1, arg2, ...)
function
:Function namethisArg
: the object pointed to by this, optionalarg1, arg2, ...
: the parameter list of the function
1. Use the call method to call the function, you can change the this point inside the function
var person = {
name: "Bill"
};
function fn() {
console.log(this);
}
fn(); // Window {window: Window, ...}
fn.call(person); // {name: 'Bill'}
Analysis:
1. Call the function directly, this points to the window object
2. Use the call method to point this to the person object
2. The call method can pass in parameters and get the return value of the function
var person = {
name: "Bill"
};
function fn(a, b) {
console.log(this);
return a + b;
}
var sum = fn.call(person, 1, 2); // {name: 'Bill'}
console.log(sum); // 3
3. The main application of the call method is to implement inheritance
Example: The child constructor inherits the properties of the parent constructor
// 父构造函数
function Father(name, age) {
// this指向父构造函数的对象实例
this.name = name;
this.age = age;
}
// 子构造函数
function Son(name, age) {
// this指向子构造函数的对象实例
Father.call(this, name, age); // 修改父构造函数的this为子构造函数的this
}
var son = new Son("Bill", 18);
console.log(son); // Son {name: 'Bill', age: 18}
3.2.2 apply
grammar:function.apply(thisArg, argsArray)
function
:Function namethisArg
: the object pointed to by this, optionalargsArray
: function parameter list in array form
1. Use the apply method to call the function, you can change the this point inside the function
var person = {
name: "Bill"
};
function fn() {
console.log(this);
}
fn.apply(person); // {name: 'Bill'}
2. The apply method can pass in parameters (must be in the form of an array) and get the return value of the function
var person = {
name: "Bill"
};
function fn(a, b) {
console.log(this);
return a + b;
}
var sum = fn.apply(person, [1, 2]); // {name: 'Bill'}
console.log(sum); // 3
3. The main application of the apply method is to manipulate arrays
Example: Use apply to find the maximum value with the help of the Math object
var arr = [1, 3, 2];
// Math.max(1, 3, 2)
max = Math.max.apply(null, arr); // 通过apply将arr数组传递给了max方法
console.log(max); // 3
Analysis:
1.null means not to change
the content of this pointing to 2.arr array as a parameter list, which is passed to the max method
3.2.3 bind
grammar:function.bind(thisArg, arg1, arg2, ...)
function
:Function namethisArg
: the object pointed to by this, optionalarg1, arg2, ...
: the parameter list of the function
1. Using the bind method will change the this pointer inside the function, but will not call the function
Note: The return value of the bind method is a new function generated after the original function changes this
var person = {
name: "Bill"
};
function fn() {
console.log(this);
}
var f = fn.bind(person);
f(); // {name: 'Bill'}
2. The bind method can pass in parameters and get the return value of the function (new function)
var person = {
name: "Bill"
};
function fn(a, b) {
console.log(this);
return a + b;
}
var f = fn.bind(person, 1, 2); // f是返回的新函数
var sum = f(); // sum是f函数的返回值
console.log(sum); // 3
3. If some functions do not need to be called immediately, but want to change the this pointer inside the function, use the bind method
Example: There is a button on the page, when the button is clicked, the button is disabled, and the button is turned on after 3 seconds
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<button>点击一下</button>
<script>
var btn = document.querySelector("button");
btn.onclick = function () {
this.disabled = true; // 此处this指向的是btn
setTimeout(
function () {
this.disabled = false; // 该回调函数绑定外部的this之后,此处的this也指向btn,否则指向window
}.bind(this),
3000
);
};
</script>
</body>
</html>
3.3 Higher-order functions
Higher-order functions: Functions that operate on other functions are called higher-order functions, which receive functions as parameters or return functions as values.
1. Functions are passed as parameters
function fn(a, b, callback) {
console.log(a + b);
callback && callback(); // 调用回调函数
}
// 匿名函数作为参数传递
fn(1, 2, function () {
console.log("Hello World");
});
2. Function as return value
function fn(a, b) {
console.log(a + b);
// 将匿名函数作为返回值
return function () {
console.log("Hello World");
};
}
f = fn(1, 2);
f();
3.4 Closures
Closure: Refers to a function that has access to variables in the scope of another function.
- A scope can access local variables inside another function
- A closure is a function
- The function where the variable is defined is a closure function
1. Generation of closure
// fn为闭包
function fn() {
var num = 10;
function fun() {
console.log(num); // 10
}
fun();
}
fn();
Analysis:
1. Infun
the scope of the function, the local variable of another function fn is accessednum
, so a closure is generated
2.num
It is defined in the fn function, sofn
it is a closure
Make a breakpoint at the place where the closure is generated, and you can see that there is one more on the right Closure (fn)
, which means that fn is a closure.
2. The main function of closures: extending the scope of variables
// fn为闭包
function fn() {
var num = 10;
return function () {
console.log(num);
};
}
var f = fn();
f(); // 10
Analysis:
1. In the absence of a closure, the local variablenum
will befn
destroyed as the function call ends.
2. With the closure, after the functionfn
call ends,num
it is not destroyed, but waits for the functionf
call . Use After the variable isnum
destroyed, it extendsnum
the scope of the local variable
4. Abnormal
Exception: When the code is executed, various errors may occur, and an exception will be thrown when an error occurs. When an exception is thrown, the program will be interrupted and the subsequent code will not be executed. Sometimes we want the subsequent code to continue to execute. At this time, we need to use the exception handling statement.
Exception statement:
try
statement is able to detect errors in code blockscatch
statement allows you to handle errorsthrow
statement allows you to create custom errorsfinally
Indicates code that will be executed regardless of the results of try and catch
1. In the case of not using exception statements, when an error occurs in the code, the program will be interrupted, and the subsequent code will not be executed
var x = y + 1; // ReferenceError
console.log("Hello World");
The running results are as follows: It can be found that after the error occurs, the subsequent output statement is not executed
2. try...catch
Statement
Syntax: execute try
the code block first, if there is an error, then execute catch
the code block, otherwise execute the subsequent code directly
try {
// 用于检测错误的代码块
}
catch(err) {
// 错误出现后执行的代码块
}
try {
var x = y + 1; // ReferenceError
} catch (error) {
console.log(error); // 打印错误信息
}
console.log("Hello World");
Here
error
is a built-inerror
object that provides error information when an error occurs. The error object also has two properties:
1.name
: set or return the error name
2.message
: set or return the error message
catch
The running results are as follows: It can be found that after an error occurs, the statement is executed , and then the subsequent code is executed, and the program is not interrupted
3. try...catch...finally
Statement
Syntax: try...catch
differs from the statement in that finally
the code block in the
try {
// 用于检测错误的代码块
}
catch(err) {
// 错误出现后执行的代码块
}
finally {
// 无论结果如何都执行的代码块
}
try {
var x = y + 1;
} catch (error) {
console.log(error);
} finally {
console.log("Hi");
}
console.log("Hello World");
4. throw
Statements, used to create custom errors, when used try...catch
together , you can control the program flow and generate custom error messages
// 本例规定数字在5-10的范围,为有效数字
try {
var x = prompt("请输入一个数字");
if (x < 5) throw "太小";
if (x > 10) throw "太大";
alert("输入的数字有效");
} catch (error) {
alert("输入的数字" + error);
}
5. The six error types of js
error type | describe |
---|---|
EvalError |
Errors that have occurred in the eval() function |
RangeError |
A number out of range error has occurred |
ReferenceError |
An illegal reference has occurred |
SyntaxError |
A syntax error has occurred |
TypeError |
A type error has occurred |
URIError |
Errors that have occurred in encodeURI() |
5. JSON
JSON: JavaScript Object Notation, a syntax for storing and exchanging data.
- JSON is a grammar, a format for writing text
- The concept of json in js can be divided into two understandings, one is the json object and the other is the json string
- Convert between json object and json string
json object: object in json format
json string: string in json format
5.1 JSON syntax
JSON syntax:
- Data as key-value pairs
- data separated by commas
- curly braces contain object
- Square brackets contain arrays
Note:
1. The suffix of the JSON file is.json
2. The MIME type of the JSON text isapplication/json
1. JSON data is stored in the form of key-value pairs
- Keys must be strings, surrounded by double quotes
- Values can only be strings, numbers, json objects, arrays, booleans and null, where strings must be surrounded by double quotes
Note: JSON does not allow comments
{
"name": "Bill", "age": 18 }
2. Objects and arrays in JSON
Objects and arrays in JSON can be nested within each other
{
"name": "Bill",
"age": 18,
"cars": {
"car1": "Porsche",
"car2": "BMW",
"car3": "Volvo"
},
"models": ["Cayenne", "X5", "XC60"]
}
{
"name": "Bill",
"age": 18,
"cars": [
{
"name": "Porsche", "models": ["Cayenne", "Panamera"] },
{
"name": "BMW", "models": ["X5", "i3", "530Li"] },
{
"name": "Volvo", "models": ["XC60", "S60"] }
]
}
3. JSON object in JS
The difference between the writing of JSON objects and the writing of JSON text is that the keys of JSON objects are not surrounded by double quotes. This is because JSON objects are JS objects, and the keys of JS objects are not surrounded by double quotes.
// JSON对象
var json = {
name: "Bill",
age: 18,
cars: [
{
name: "Porsche", models: ["Cayenne", "Panamera"] },
{
name: "BMW", models: ["X5", "i3", "530Li"] },
{
name: "Volvo", models: ["XC60", "S60"] }
]
};
// 使用objectName.property的语法访问对象属性
console.log(json.name); // Bill
console.log(json.age); // 18
console.log(json.cars[0]); // {name: 'Porsche', models: Array(2)}
console.log(json.cars[0].name); // Porsche
console.log(json.cars[0].models[0]); // Cayenne
// 使用objectName["property"]的语法访问对象属性
console.log(json["name"]); // Bill
console.log(json["age"]); // 18
console.log(json["cars"][1]); // {name: 'BMW', models: Array(3)}
console.log(json["cars"][1]["name"]); // BMW
console.log(json["cars"][1]["models"][0]); // X5
5.2 JSON parsing
JSON parsing: use JSON.parse()
method to convert json string to json object
var jsonstr = '{"name":"Bill","age":18,"cars":{"car1":"Porsche","car2":"BMW","car3":"Volvo"}}';
var json = JSON.parse(jsonstr);
console.log(json); // {name: 'Bill', age: 18, cars: {…}}
You can also use template strings in ES6 to retain the original way of writing JSON text:
// JSON字符串
var jsonstr = `{
"name": "Bill",
"age": 18,
"cars": {
"car1": "Porsche",
"car2": "BMW",
"car3": "Volvo"
}
}`;
var json = JSON.parse(jsonstr);
console.log(json); // {name: 'Bill', age: 18, cars: {…}}
5.3 JSON stringification
JSON stringification: use JSON.stringify()
method to convert json object to json string
// JSON对象
var json = {
name: "Bill",
age: 18,
cars: {
car1: "Porsche",
car2: "BMW",
car3: "Volvo"
}
};
// 将JSON对象转换为字符串
var jsonstr1 = JSON.stringify(json);
console.log(jsonstr1);
// 将JSON对象转换为字符串,并指定缩进用于美化输出
var jsonstr2 = JSON.stringify(json, null, "\t");
console.log(jsonstr2);
The result of the operation is as follows:
6. copy
Copy is divided into shallow copy and deep copy:
- Shallow copy: only copy the data of the first layer, when encountering a deeper object, only copy the address of the object
- Deep copy: copy the data of each layer
6.1 Shallow copy
1. Object.assign()
The method of use can realize shallow copy
var person = {
name: "Bill",
age: 18,
info: {
telephone: "13579",
email: "[email protected]"
}
};
var student = {
};
Object.assign(student, person); // 将person对象浅拷贝到student对象
person.age = 28;
person.info.telephone = "246810";
console.log(person);
console.log(student);
The result of the operation is as follows: person.age
the modification found did not affect the student object, but person.info.telephone
the modification did affect the student object.
Analysis: This is because
person.age
the attribute value of is a simple data type, so the attribute value copied to the student objectage
is a specific value, andperson.info
the attribute value of is an object, so the attribute value copied to the student objectinfo
is an address. This address points toperson.info
. That is to saystudent.info === person.info
,person.age
the modification does not affect the student, butperson.info.telephone
the modification will affect the student
2. If you directly assign an object to another object, it is equivalent to giving the object an alias, which is neither a shallow copy nor a deep copy.
var person = {
name: "Bill",
age: 18,
info: {
telephone: "13579",
email: "[email protected]"
}
};
var student = {
};
student = person; // 将person对象的地址赋值给student对象
person.age = 28;
person.info.telephone = "246810";
console.log(person);
console.log(student);
The result of the operation is as follows: when any attribute of the person object changes, the attribute of the student object also changes, because the student points to the address of the person object, that isstudent === person
6.2 Deep Copy
1. structuredClone()
The method of use can realize deep copy
var person = {
name: "Bill",
age: 18,
info: {
telephone: "13579",
email: "[email protected]"
}
};
var student = structuredClone(person); // 将person对象深拷贝到student对象
person.age = 28;
person.info.telephone = "246810";
console.log(person);
console.log(student);
The results of the operation are as follows: the discovery person.age
and person.info.telephone
modification did not affect the student object.
Analysis: This is because the deep copy will copy the data of each layer. When encountering a deeper object, it will continue to traverse the attributes and attribute values of the object and copy them instead of just copying the address of the object.
2. Use to for...in
encapsulate a deep copy function
// 深拷贝函数
function deepCopy(newObj, oldObj) {
for (var i in oldObj) {
var item = oldObj[i]; // 原对象的属性值
// 判断属性值是否为数组对象
if (item instanceof Array) {
newObj[i] = []; // 将新对象的第i项属性设置为数组对象
deepCopy(newObj[i], item); // 递归调用
}
// 判断属性值是否为普通对象
if (item instanceof Object) {
newObj[i] = {
}; // 将新对象的第i项属性设置为普通对象
deepCopy(newObj[i], item); // 递归调用
}
// 判断属性值是否为简单数据类型
if (!(item instanceof Object)) {
newObj[i] = item;
}
}
}
var person = {
name: "Bill",
age: 18,
info: {
telephone: "13579",
email: "[email protected]"
},
addr: ["Beijing", "Shanghai"]
};
var student = {
};
deepCopy(student, person); // 将person对象深拷贝到student对象
person.age = 28;
person.info.telephone = "246810";
person.addr[0] = "Guangzhou";
console.log(person);
console.log(student);
The result of the operation is as follows:
3. Use to JSON
encapsulate a deep copy function
// 深拷贝函数
function deepCopy(oldObj) {
oldObjstr = JSON.stringify(oldObj); // 将原对象转换为字符串
newObj = JSON.parse(oldObjstr); // 再将字符串转换为对象
return newObj;
}
var person = {
name: "Bill",
age: 18,
info: {
telephone: "13579",
email: "[email protected]"
},
addr: ["Beijing", "Shanghai"]
};
var student = deepCopy(person); // 将person对象深拷贝到student对象
person.age = 28;
person.info.telephone = "246810";
person.addr[0] = "Guangzhou";
console.log(person);
console.log(student);
operation result: