目录
一,作用域
1.1,局部作用域
1.2,全局作用域
1.3,作用域链
1.4,js垃圾回收机制
1.5,闭包
1.6,变量提升
二,函数进阶
2.1,函数提升
2.2,函数参数
2.3,展开运算符
2.4,箭头函数
编辑
2.5,箭头函数参数
2.6,箭头函数的this
三,解构赋值
3.1,数组解构
3.2,对象解构
渲染案例
综合案例:
补充 Filter方法:
三,方法
内置构造函数
案例:
四,面向对象编程
1.2,数组扩展最大值和求和方法
1.3,总结
1.4,原型继承
1.5,原型链
综合案例
函数作用域:
块作用域
Document
思考上面的结果
引用计数法 :
标记清除法:
Document
闭包 就无法修改这个变量了
总结:
动态参数:(伪数组)
function foo() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
foo('Hello', 'World', '!');
剩余参数:(真数组)
function sum(...numbers) {
let total = 0;
for (let number of numbers) {
total += number;
}
return total;
}
console.log(sum(1, 2, 3)); // 输出 6
console.log(sum(4, 5, 6, 7, 8)); // 输出 30
动态参数是指在定义或调用函数时,不需要指定参数的个数和名称,而是可以根据实际情况传递任意数量和类型的参数。js中有两种常用的方式来处理动态参数:arguments对象和剩余参数语法。
arguments对象是一个类数组对象,它包含了传给函数的所有实参,无论是否有对应的形参。arguments对象可以通过索引访问每个实参的值,也可以通过length属性获取实参的个数。arguments对象还有一些其他的属性和方法,例如callee属性和caller属性等。arguments对象只在函数内部有效,可以用来实现一些高级的功能,例如递归调用、重载等。
剩余参数语法是ES6引入的一种新特性,它使用扩展运算符(...)来收集动态参数并将其存储在一个数组中。剩余参数语法可以让我们将一个不定数量的参数表示为一个数组,而不需要使用arguments对象。剩余参数只包含那些没有对应形参的实参,而arguments对象包含了传给函数的所有实参。剩余参数是一个真正的数组,可以直接使用所有的数组方法,例如sort、map、forEach或pop等。
动态参数和剩余参数语法都可以让我们更灵活地定义和调用函数,但它们也有一些区别和注意事项。以下是一些示例代码和网页链接,你可以参考学习:
• 使用arguments对象处理动态参数https://bing.com/search?q=js%E4%B8%AD%E5%8A%A8%E6%80%81%E5%8F%82%E6%95%B0%E5%92%8C%E5%89%A9%E4%BD%99%E5%8F%82%E6%95%B0&form=SKPBOT:
// 定义一个函数,不指定形参
function dynamicParams() {
// 使用arguments对象迭代输出所有传递的参数
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
// 调用函数,传递任意数量和类型的实参
dynamicParams(1, 2, 3); // 输出 1 2 3
dynamicParams("a", "b", "c"); // 输出 a b c
dynamicParams(true, false, null, undefined); // 输出 true false null undefined
• 使用剩余参数语法处理动态参数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters:
// 定义一个函数,使用扩展运算符收集剩余参数
function dynamicParams(...args) {
// args是一个数组,可以直接使用数组方法
args.forEach(function (element) {
console.log(element);
});
}
// 调用函数,传递任意数量和类型的实参
dynamicParams(1, 2, 3); // 输出 1 2 3
dynamicParams("a", "b", "c"); // 输出 a b c
dynamicParams(true, false, null, undefined); // 输出 true false null undefined
• 剩余参数 - JavaScript | MDNhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters:这是一个介绍剩余参数语法的网页,它有详细的概述、语法、描述、示例和规范等内容。
• js动态参数arguments和剩余参数、展开运算符https://blog.csdn.net/lxllxl211/article/details/129359549:这是一篇博客文章,它介绍了js中动态参数、剩余参数和展开运算符的概念、用法和区别等内容。
Document
Document
展开运算符(spread operator)是一种用三个点(...)表示的语法,它可以将一个可迭代的对象(如数组、字符串、集合等)在某处展开,变成多个参数或元素。展开运算符可以用在以下几种场合:
• 在函数调用时,可以将一个数组或字符串展开为多个参数,而不需要使用apply方法。例如:
function add(a, b, c) {
return a + b + c;
}
var arr = [1, 2, 3];
// 不使用展开运算符,需要使用apply方法
console.log(add.apply(null, arr)); // 6
// 使用展开运算符,直接将数组展开为参数
console.log(add(...arr)); // 6
• 在构造字面量数组时,可以将一个或多个数组或字符串展开为多个元素,而不需要使用concat方法。例如:
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
// 不使用展开运算符,需要使用concat方法
var arr3 = arr1.concat(arr2); // [1, 2, 3, 4, 5, 6]
// 使用展开运算符,直接将数组展开为元素
var arr4 = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
• 在解构赋值时,可以将一个数组或字符串展开为多个变量,而不需要使用slice方法。例如:
var str = "hello";
// 不使用展开运算符,需要使用slice方法
var [a, b] = str.slice(0, 2); // a = "h", b = "e"
// 使用展开运算符,直接将字符串展开为字符
var [c, d] = [...str]; // c = "h", d = "e"
• 在ES2018中,还可以在构造字面量对象时,将一个或多个对象展开为多个属性,而不需要使用Object.assign方法。例如:
var obj1 = {a: 1, b: 2};
var obj2 = {c: 3, d: 4};
// 不使用展开运算符,需要使用Object.assign方法
var obj3 = Object.assign({}, obj1, obj2); // {a: 1, b: 2, c: 3, d: 4}
// 使用展开运算符,直接将对象展开为属性
var obj4 = {...obj1, ...obj2}; // {a: 1, b: 2, c: 3, d: 4}
• 箭头函数使用=>符号来表示,它可以接受一个或多个参数,也可以不接受任何参数。例如:
// 无参数的箭头函数
() => {
// 函数体
}
// 一个参数的箭头函数
param => {
// 函数体
}
// 多个参数的箭头函数
(param1, param2, ...) => {
// 函数体
}
• 箭头函数的函数体可以是一个表达式或一个语句块。如果是一个表达式,那么函数会隐式地返回表达式的值。如果是一个语句块,那么需要使用return语句来返回值。例如:
// 表达式作为函数体,隐式返回
param => param + 1
// 语句块作为函数体,需要显式返回
param => {
let result = param + 1;
return result;
}
• 箭头函数不绑定自己的this值,而是继承外层作用域的this值。这样可以避免一些常见的this指向问题,例如在回调函数或对象方法中。例如:
// 普通函数中的this指向问题
var obj = {
name: "obj",
sayName: function () {
setTimeout(function () {
console.log(this.name); // this指向window,输出undefined
}, 1000);
}
};
obj.sayName();
// 箭头函数中的this继承问题
var obj = {
name: "obj",
sayName: function () {
setTimeout(() => {
console.log(this.name); // this指向obj,输出"obj"
}, 1000);
}
};
obj.sayName();
• 箭头函数不能用作构造函数,也就是说不能用new关键字来调用它们,否则会抛出错误。这是因为箭头函数没有自己的原型属性和构造器。例如:
// 尝试用new调用箭头函数
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
• 箭头函数也不绑定自己的arguments对象,而是继承外层作用域的arguments对象。这样可以避免一些常见的arguments使用问题,例如在嵌套函数或默认参数中。例如:
// 普通函数中的arguments对象问题
function foo(a) {
var f = function (b) {
return arguments[0]; // arguments指向f的实参,而不是foo的实参
};
return f(a + 1);
}
console.log(foo(1)); // 输出2,而不是1
// 箭头函数中的arguments对象继承
function foo(a) {
var f = (b) => {
return arguments[0]; // arguments指向foo的实参,而不是f的实参
};
return f(a + 1);
}
console.log(foo(1)); // 输出1,而不是2
箭头函数没有动态参数 有剩余参数
Document
应用
const arr = [1, 2, [3, 4]] //二维数组
console.log(arr[2][0]);
const [a, b, [c, d]] = [1, 2, [3, 4]]
console.log(a);
console.log(b);
console.log(c);
console.log(d);
// 对象解构 等价于 const uname = obj.uname
//要求对象名和属性名必须一致
const { uname, age } = { uname: 'bestwishes', age: 18 }
console.log(uname);
console.log(age);
const { uname: username, age } = { uname: 'bestwishes', age: 18 }
console.log(username);
console.log(age);
例子:
const pig = {
name:"bes",
family:{
mother:'ma',
father:'fa',
sister:'si'
},
age:6
}
//对象解构
const {name,family:{mother,father,sister}} = pig
案例:
const msg = {
"code": 200,
"msg": "获取新闻列表成功",
"data": [
{
"id": 1,
"title": "5G商用自己,三大运用商收入下降",
"count": 58
},
{
"id": 2,
"title": "国际媒体头条速览",
"count": 56
},
{
"id": 3,
"title": "乌克兰和俄罗斯持续冲突",
"count": 1669
},
]
}
解构data:
// 需求1: 请将以上msg对象 采用对象解构的方式 只选出 data 方面后面使用渲染页面
const { data } = msg
function render(arr) {
console.log(arr);
}
render(msg)
// // 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数
function render({ data }) {
console.log(data);
}
render(msg)
// 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData
function render({ data: myData }) {
console.log(myData);
}
render(msg)
遍历数组forEach方法(重点)
+
//声明空字符变量
let str = ''
const { name, price, picture } = goodsList //列表解构
goodsList.forEach(index => {
//渲染
str += `
${name}
${price}
`
// 追加到大盒子去
document.querySelector('.list').innerHTML = str
})
数组中嵌套 对象 解构时 解构名和对象属性名相同
css实现
/* tab栏切换 */
.filter a:active,
.filter a:focus {
background: #05943c;
color: #fff;
}
构造函数:
实例成员是指没有用static修饰的类成员,例如实例变量和实例方法。实例成员属于类的对象,每个对象都有自己的实例成员的副本。实例成员只能通过对象来访问和调用,不能直接通过类名来访问和调用。例如:
class Person {
// 实例变量
String name;
int age;
// 实例方法
void sayHello() {
System.out.println("Hello, I am " + name);
}
}
// 创建一个Person对象
Person p1 = new Person();
// 通过对象访问和修改实例变量
p1.name = "Alice";
p1.age = 20;
// 通过对象调用实例方法
p1.sayHello(); // 输出 Hello, I am Alice
静态成员是指用static修饰的类成员,例如静态变量和静态方法。静态成员属于类本身,不属于任何一个对象,所有对象共享同一个静态成员。静态成员可以直接通过类名来访问和调用,也可以通过对象来访问和调用,但是推荐使用前者。例如:
class Person {
// 静态变量
static int count;
// 静态方法
static void showCount() {
System.out.println("There are " + count + " persons.");
}
}
// 直接通过类名访问和修改静态变量
Person.count = 10;
// 直接通过类名调用静态方法
Person.showCount(); // 输出 There are 10 persons.
// 创建一个Person对象
Person p1 = new Person();
// 通过对象访问和修改静态变量
p1.count = 20;
// 通过对象调用静态方法
p1.showCount(); // 输出 There are 20 persons.
实例成员和静态成员的区别主要有以下几点:
• 实例成员需要创建对象后才能使用,而静态成员不需要创建对象就能使用。
• 实例成员在内存中为每个对象分配一份空间,而静态成员在内存中只占一份空间。
• 实例成员可以访问静态成员和其他实例成员,而静态成员只能访问其他静态成员,不能访问实例成员。
• 静态成员在类加载时就初始化,而实例成员在创建对象时才初始化
实例成员是指没有用static修饰的类成员,例如实例属性和实例方法。实例成员属于类的对象,每个对象都有自己的实例成员的副本。实例成员只能通过对象来访问和调用,不能直接通过类名来访问和调用。例如:
class Person {
// 实例属性
constructor(name, age) {
this.name = name;
this.age = age;
}
// 实例方法
sayHello() {
console.log(`Hello, I am ${this.name}`);
}
}
// 创建一个Person对象
let p1 = new Person("Alice", 20);
// 通过对象访问和修改实例属性
p1.name = "Bob";
p1.age = 21;
// 通过对象调用实例方法
p1.sayHello(); // 输出 Hello, I am Bob
静态成员是指用static修饰的类成员,例如静态属性和静态方法。静态成员属于类本身,不属于任何一个对象,所有对象共享同一个静态成员。静态成员可以直接通过类名来访问和调用,也可以通过对象来访问和调用,但是推荐使用前者。例如:
class Person {
// 静态属性
static count = 0;
// 静态方法
static showCount() {
console.log(`There are ${Person.count} persons.`);
}
// 实例属性
constructor(name, age) {
this.name = name;
this.age = age;
// 每创建一个对象,静态属性加一
Person.count++;
}
}
// 直接通过类名访问和修改静态属性
Person.count = 10;
// 直接通过类名调用静态方法
Person.showCount(); // 输出 There are 10 persons.
基本包装类型:
Object静态方法:
拷贝对象
数组常用方法
reduce方法
常见的方法(前三个知道,后面几个了解)
every 方法:
const arr = [10, 20, 30, 40]
const flag = arr.every(item => item >= 10)
console.log(flag);
将伪数组转转换为真数组
- 1
- 2
- 3
String
• startswith和endswith方法都接受一个字符串类型的参数,用于指定要检索的子字符串。
• startswith和endswith方法都返回一个布尔值,如果字符串以参数值为开头或结尾则返回true,否则返回false。
• startswith和endswith方法都区分大小写,如果参数值和字符串的大小写不一致,则返回false。
• startswith和endswith方法都可以接受一个可选的第二个参数,用于指定字符串的长度。如果提供了第二个参数,那么只会在字符串的前length个字符中进行检索。
以下是一些使用startswith和endswith方法的示例代码和网页链接,你可以参考学习:
• 使用startswith和endswith方法判断字符串https://www.x1y1z1.com/javascript/startsendwith.html:
let text = "Hello world!";
let result1 = text.startsWith("Hello"); // true
let result2 = text.startsWith("hello"); // false
let result3 = text.endsWith("world!"); // true
let result4 = text.endsWith("World!"); // false
• 使用startswith和endswith方法指定字符串长度https://www.runoob.com/jsref/jsref-endswith.html:
let text = "Hello world!";
let result1 = text.startsWith("world", 6); // true
let result2 = text.startsWith("world", 5); // false
let result3 = text.endsWith("Hello", 5); // true
let result4 = text.endsWith("Hello", 6); // false
• substring方法接受两个参数,分别是开始索引和结束索引,它会返回从开始索引到结束索引(不包括)之间的子字符串。
• substring方法不会修改原始字符串,而是返回一个新的字符串。
• 如果开始索引大于结束索引,substring方法会自动交换两个参数的位置,这意味着substring(4, 1)等同于substring(1, 4)。
• 如果开始索引或结束索引为负数或NaN,substring方法会将它们视为0。
• substring方法和substr方法、slice方法都可以用来提取子字符串,但它们有一些区别和注意事项。
以下是一些使用substring方法的示例代码和网页链接,你可以参考学习:
• 使用substring方法提取子字符串https://www.w3school.com.cn/jsref/jsref_substring.asp:
let text = "Hello world!";
let result = text.substring(1, 4); // "ell"
• 使用substring方法交换两个参数https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/substring:
let text = "Hello world!";
let result = text.substring(4, 1); // "ell"
• 使用substring方法处理负数或NaNhttps://bing.com/search?q=js%E4%B8%AD%E7%9A%84substring%E6%96%B9%E6%B3%95&form=SKPBOT:
let text = "Hello world!";
let result = text.substring(-3); // "Hello world!
小案例:
Number:
• toFixed方法接受一个参数,表示要保留的小数位数,它是0到20之间的整数,包括0和20。如果省略了该参数,或者提供了非法的值,将默认使用0。
• toFixed方法返回一个新的字符串,不会修改原始的数字。返回的字符串可能会用0来填充小数部分,以达到指定的长度。
• toFixed方法在进行四舍五入时可能会产生一些不准确的结果,这是因为toFixed方法在处理浮点数时,实际上使用的是舍入到最近的偶数(银行家舍入)策略,而不是标准的四舍五入。这种舍入策略是为了在大量运算时减小累积误差。
目录
一,作用域
1.1,局部作用域
1.2,全局作用域
1.3,作用域链
1.4,js垃圾回收机制
1.5,闭包
1.6,变量提升
二,函数进阶
2.1,函数提升
2.2,函数参数
2.3,展开运算符
2.4,箭头函数
编辑
2.5,箭头函数参数
2.6,箭头函数的this
三,解构赋值
3.1,数组解构
3.2,对象解构
渲染案例
综合案例:
补充 Filter方法:
三,方法
内置构造函数
案例:
四,面向对象编程
1.2,数组扩展最大值和求和方法
1.3,总结
1.4,原型继承
1.5,原型链
综合案例
以下是一些使用toFixed方法的示例代码和网页链接,你可以参考学习:
• 使用toFixed方法转换数字https://www.w3school.com.cn/jsref/jsref_tofixed.asp:
let num = 5.56789;
let n = num.toFixed(2); // "5.57"
• 使用toFixed方法处理非法参数https://www.runoob.com/jsref/jsref-tofixed.html:
let num = 5.56789;
let n = num.toFixed(-1); // "6"
• 使用toFixed方法产生不准确结果https://bing.com/search?q=js+tofixed+%E6%96%B9%E6%B3%95&form=SKPBOT:
let num = 0.615;
let n = num.toFixed(2); // "0.61" 而非 "0.62"
合计:1000.00
自定义数组方法
添加新方法出现问题 woman 和man 都被添加这个方法
所以要抽取一个父类