JavaScript高级语法复习、学习笔记——————大致了解高级语法内容

这篇博客详细介绍了JavaScript的高级语法,包括面向对象的概念、类的创建与实例化、继承与`super`关键字,深入探讨了构造函数与原型的关系、原型链以及静态成员。此外,还涵盖了ES5新增的数组、字符串和对象方法,如`forEach`、`filter`、`trim`和`Object.keys`,并讨论了函数定义与严格模式、闭包和递归,以及正则表达式的使用和组成部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

本文包含JavaScript高级大致内容(不全部包含ES6新语法),参考与pink老师所讲解视频通过自己理解整理,所以这是一篇用于小白新手入门,或者复习使用的笔记,ES6新语法以后也会更新。
如有做的不好的地方,敬请谅解,欢迎指出,持续更新改正


一 面向对象与类

1 面向对象

面向过程 (POP)
高性能 不易维护

面向对象 (OOP)
性能低 易维护 灵活

特点:

  • 封装
  • 继承
  • 多态

类和对象

对象抽象封装成一个类
类实例化获取类的对象


2 创建类与实例化

用class关键字创建类

   class Star {
     constructor(uname, age) {            //new生成实例时,constructor自动调用,不写自动生成
       this.uname = uname;
       this.age = age;
     }
   }

利用类创建对象

  var ldh = new Star("刘德华", 20);
  var zxy = new Star("张学友");
  console.log(ldh);

类中添加方法

  • 类里面函数不需要写function
  • 多个方法间不需要逗号分隔
 class Star {
     constructor(uname, age) {           
       this.uname = uname;
       this.age = age;
     }
     say(){
     console.log('说')
     }
   }
   
  var zxy = new Star("张学友");
  zxy.say()

3 继承

(就近原则) 实例化输出方法,先在子类找,再到父类找

 class Father {
     constructor() {}
     money() {
       console.log(100);
     }
   }
 class Son extends Father {}
 var son = new Son();
 son.money();

4 super关键字

super() 调用了父类中的构造函数

 class Father {
     constructor(x, y) {
       this.x = x;
       this.y = y;
     }
     sum() {
       console.log(this.x + this.y);
     }
   }
 class Son extends Father {
     constructor(x, y) {
       super(x, y);                  //调用了父类中的构造函数
     }
   }
   
 var son = new Son(1, 2);
 son.sum();

super关键字调用父类普通函数

 class Father {
     say() {
       return "我是爸爸";
     }
   }
 class Son extends Father {
     say() {
       console.log(super.say() + "的儿子");
     }
   }
 var son = new Son();
 son.say();

super必须放在子类this之前

 class Father {
     constructor(x, y) {
       this.x = x;
       this.y = y;
     }
     sum() {
       console.log(this.x + this.y);
     }
   }
 class Son extends Father {
     constructor(x, y) {
       super(x, y);
       this.x = x;
       this.y = y;
     }
     subtract() {
       console.log(this.x - this.y);
     }
   }
 var son = new Son(3, 1);
 son.subtract();
 son.sum();

5 总结

没有变量提升,必须先定义类,才能实例
类里面的公有属性和方法一定要用this

类里this指向问题
constructor 里面this 指向的是创建的实例
方法里的this 指向的是调用者


二 构造函数与原型

1 实例成员和静态成员

实例成员就是构造函数内部通过this添加的成员 uname age就是
实例成员只能通过实例化对象访问

静态成员 是在构造函数本身添加成员
静态成员只能通过构造函数访问

   function Star(uname, age) {
     this.uname = uname;
     this.age = age;
     this.sing = function () {
       console.log("唱歌");
     };
   }
   
   var ldh = new Star("刘德华", 18);    //实例成员
   console.log(ldh.uname);
   Star.sex = "男";                     //静态成员
   console.log(Star.sex);

2 原型

构造函数问题
存在浪费内存问题 函数会开辟不同内存空间

2.1 构造函数原型prototype

通过原型分配的函数是所有对象 共享的
每一个构造函数都有一个prototype属性(对象)

把那些不变的方法,直接定义在prototype对象上,所有对象实例就可以共享这些方法
一般情况下,公共属性定义到构造函数里,公共方法放到原型对象上

 function Star(uname, age) {
     this.uname = uname;
     this.age = age;
   }
   
 Star.prototype.sing = function () {
     console.log("我会唱歌");
   };
   
 var zt = new Star("张铁", 18);
 var yy = new Star("鸳鸯", 18);
 zt.sing();
 yy.sing();
 console.log(zt);
 console.log(Star);

2.2对象原型 proto

对象身上系统自己添加一个__proto__指向构造函数原型对象

实例对象没有sing 这个方法, 因为有__proto__ 存在, 就去构造函数原型对象prototype找

   console.log(zt. __proto__  === Star.prototype);

2.3 constructor

对象原型和原型对象 都有一个属性constructor属性 称为构造函数,因为它指回构造函数本身

主要用于记录该对象引用于哪一个构造函数,可以让原型对象重新指向原来构造函数

如果我们修改了原来的原型对象, 给原型对象赋值的是一个对象,必须手动利用constructor

在用原型对象添加许多方法时,可以利用对象{}形式添加,但是 = 的操作会覆盖constructor,所以需要手动添加

   Star.prototype = {                        //此时不是用 .   而是用 = 覆盖了
     constructor: Star,						 //重新指向
     sing: function () {
       console.log("我会唱歌");
     },
     movie: function () {
       console.log("我会演电影");
     }
   };

3 构造函数 , 实例, 原型对象三者之间的关系

                      Star.prototype
Star构造函数      ------------------------------->         Star原型对象
                 <------------------------------
                     Star.prototype.constructor
             \                                        /
              \                                      /ldh.__proto__
               \                                    /
                         ldh对象实例
                   ldh.__proto__.constructor

在这里插入图片描述


4 原型链

每一个对象都有一个对象原型,通过__proto__一层一层向上寻找

原型链查找

  • 当访问一个对象属性或方法时,首先查找这个对象自身有没有
  • 如果没有,就查找他的原型(__proto__指向的prototype原型对象)
  • 如果还没有,就查找原型对象的原型(Object的原型对象)
  • 依次类推直到Object为止(null);
  • __proto__对象原型存在意义在于为对象成员查找机制提供方向,或者说一条路线

在这里插入图片描述


5 继承

ES6之前没有提供extends继承, 通过构造函数+原型对象模拟实现继承,组合继承

fun.call(thisArg,arg1,arg2)
调用这个函数
并且修改函数运行时this指向

  • thisArg: 当前调用函数this指向对象
  • arg1,arg2: 传递的其他参数
 function fn(x, y) {
   console.log("测试");
   console.log(this);
   console.log(x + y);
 }
 var o = {
   name: "andy",
 };
 fn.call(o, 1, 2);

利用父构造函数继承属性

 function Father(uname, age) {
   this.uname = uname;
   this.age = age;
 }
 
 function Son(uname, age, score) {
   Father.call(this, uname, age);
   this.score = score;
 }
 
 var son = new Son("李德华", 18, 100);
 console.log(son);

利用原型对象继承方法

 Son.prototype = new Father();
       //如果利用对象的形式修改了原型对象,利用constructor 指回原来的构造函数
 Son.prototype.constructor = Son;

6 类的本质

其实还是一个函数 类就是构造函数的另外一种写法

class Star {}

       //类有原型对象
 console.log(Star.prototype);
 
       //类原型对象里有constructor 指向本身
 console.log(Star.prototype.constructor);
 
       //类可以通过原型对象添加方法
 Star.prototype.sing = function () {
   console.log("冰雨");
 };
 
 var ldh = new Star();
 console.dir(ldh);
 
       //类创建的实例对象有__proto__ 原型指向 类的原型对象
 console.log(ldh.__proto__ === Star.prototype);

三 ES5新增方法

1 新增数组方法

1.1 forEach() 遍历数组

 var arr = [1, 2, 3];
 var sum = 0;
 arr.forEach(function (value, index, array) {
   console.log("每个数组元素" + value);
   console.log("每个数组元素索引" + index);
   console.log("数组本身" + array);
   sum += value;
 });
 console.log(sum);
 

1.2 filter() 筛选数组

返回一个新数组

 var arr = [12, 3, 5, 66, 88];
 var newArr = arr.filter(function (value, index, array) {
   return value >= 2;
 });
 console.log(newArr);

1.3 some() 是否满足条件元素

返回一个布尔值

如果找到第一个满足条件的元素,则终止循环,不在继续查找

 var arr = ["red", "pink", "blue"];
 var flag = arr.some(function (value) {
   return value == "pink";
 });
 console.log(flag);

1.4 some和forEach区别

forEach 和 filter 里 return 不会终止迭代
some 里 return 就是终止调用


2 新增字符串方法 trim()

会从一个字符串 两端 删除空白字符 , 返回一个新字符串

 var str = "  andy   ";
 console.log(str);
 var str1 = str.trim();
 console.log(str1);

3 ES5新增对象方法

3 1 Object.keys(obj) 获取对象属性名

效果类似于for in 返回由属性名组成的数组

 var obj = {
   name: "zt",
   age: 19,
   sex: "男",
 };
 
 var arr = Object.keys(obj);
 console.log(arr);
 
 arr.forEach(function (value) {
   console.log(value);
 });

3.2Object.defineProperty() 定义对象中新属性或修改原有属性

Object.defineProperty(obj,prop,descriptor)

  • obj: 必须 目标属性
  • prop: 必须 需定义或修改的属性名字
  • descriptor:
    对象格式 必须 目标属性所拥有的特性
    • value: 设置属性的值 默认为undefined
    • writable: 值是否可以重写 true|false
    • enumerable: 目标属性是否可以被枚举 是否可以被遍历 true|false
    • configurable: 目标属性是否可以被删除或是否可以被再次修改特性 true|false

在这里插入图片描述


四 函数定义与严格模式

1 新函数定义方式

利用new Funcation(‘参数1’,‘参数2’,‘函数体’)

 var fn = new Function('a' + 'b' + "console.log(a+b)");
 fn(1,2);

所有的函数都是Function 的实例(对象)
函数也属于对象


2 改变函数内部this 指向

2 1 apply()

方法调用一个函数, 也可以改变函数this指向

  • fun.apply(thisArg,[argsArray])
  • argsArray: 传递的值,必须包含在 数组 里

主要应用
利用apply() 借助于数学内置对象求最大值

 var arr = [1, 66, 3, 88, 99];
 var max = Math.max.apply(Math, arr);
 console.log(max);

2.2 bind()

不会调用函数, 可以改变this指向

返回的是原函数改变 this 指向的新函数
fun.bind(thisArg, arg1, arg2);

 var o = {
   name: "zt",
 };
 function fn(a, b) {
   console.log(this);
   console.log(a + b);
 }
 var f = fn.bind(o, 1, 2);
 f();

如果有的函数我们不需要立即调用,但又想改this指向, 此时用bind
有一个按钮,点击之后,禁用,3s后开启这个按钮

 var btn = document.querySelector("button");
 btn.onclick = function () {
   this.disabled = true;
   setTimeout(
     function () {
       this.disabled = false;
     }.bind(this),
     3000
   );
 };

2.3 call()

fun.call(thisArg,arg1,arg2)
调用这个函数
并且修改函数运行时this指向

  • thisArg: 当前调用函数this指向对象
  • arg1,arg2: 传递的其他参数

3 严格模式

整个script开启严格模式
下面的js 代码就会按照严格模式执行代码

 'use strict'

函数开启严格模式

 function fn() {
     "use strict";
 }

4 严格模式的变化

变量规定

  • 必须先声明再使用
  • 不能随意删除已经声明好的变量

this指向问题

  • 全局作用域定义的函数中this 是undefined, 不再指向window
  • 构造函数不加new 调用, this会报错

函数变化

  • 函数不能有重名的参数
  • 函数不能在块级作用域内声明

5 高阶函数

是对其他函数操作的函数, 接收函数作为 (参数) 或者将函数作为 (返回值) 输出
函数也是一种数据类型,同样可以作为参数,传递给另一个参数使用. 最经典的是作为回调函数

   function fn(a, b, callback) {
     console.log(a + b);
     callback && callback();
   }
   fn(1, 2, function () {
     console.log("我是最后调用的");
   });

五 闭包与递归

1 闭包 closure

指有权访问另一个函数作用域中变量的 函数

一个作用域可以访问到另一个函数内部的局部变量

 function fn() {
   var num = 100;
   function fun() {
     console.log(num);
   }
   fun();
 }
 fn();

fn外面的作用域可以访问fn 内部的局部变量

 function fn() {
   var num = 100;
   return function () {
     console.log(num);
   };
 }
 var f = fn();
 f();

闭包的主要作用: 延伸了变量的作用范围


2 闭包应用

点击li输出当前li 索引号

 <ul class="nav">
      <li>榴莲</li>
      <li>臭豆腐</li>
      <li>鱼罐头</li>
      <li>猪蹄子</li>
 </ul>
    
 var lis = document.querySelector("ul").querySelectorAll("li");
 for (var i = 0; i < lis.length; i++) {
   lis[i].index = i;
   lis[i].onclick = function () {
     console.log(this.index);
   };
 }

利用闭包的方式得到当前小li 的索引号

立即执行函数也称为小闭包, 因为里面任意一个函数都可以使用它的i这个变量

 for (var i = 0; i < lis.length; i++) {
       //利用for循环创建4个立即执行函数
       //立即执行函数也称为小闭包, 因为里面任意一个函数都可以使用它的i这个变量
   (function (i) {
     lis[i].onclick = function () {
       console.log(i);
     };
   })(i);
 }

3 递归

如果一个函数内部可以调用其本身,那么这个函数就是递归函数

函数内部自己调用自己,就叫递归函数 作用和循环效果一样
容易发生"栈溢出",必须加退出条件

 var num = 1;
 function fn() {
   console.log("话");
   if (num == 6) {
     return;
   }
   num++;
   fn();
 }
 fn();

利用递归函数求1~n 阶乘 1234…n

 function fn(n) {
   if (n == 1) {
     return 1;
   }
   return n * fn(n - 1);
 }
 console.log(fn(3));

4 浅拷贝和深拷贝

浅拷贝只是拷贝一层,更深层对象只拷贝引用

 Object.assign(目标,)

深拷贝拷贝多层,每一级别数据都会拷贝


六 正则表达式

js中正则表达式也是对象

验证表单(匹配)
过滤掉内容中的一些敏感词(替换)
获取特定部分(提取)


1 使用

利用RegExp对象来创建

 var regexp = new RegExp(/123/);
 console.log(regexp);

利用字面量创建

 var rg = /123/;
 console.log(rg);

测试正则表达式 test() 用于检测是否符合规则,返回true或false
regexObj.test(str) str:检测的文本


2 正则表达式的组成

2.1 边界符

^ 表示以谁开始
$ 表示以谁结束

 var rg = /^abc$/;
 console.log(rg.test("abc"));

2.2 字符类

[]有一系列字符供选择,只需匹配一个就可
如果[] 里面有^表示取反
[]外面有 ^ 正常表示开头

 var rg = /[abc]/;                 //只要包括a 或 包括b 或 包括c   就行
 console.log(rg.test("andy"));
 
 var rg = /^[abc]$/               //三选一,只有是a 或者是b 或者是c
 var rg = /^[a-z0-9]$/            //26个英文字母任何一个字母和数字返回 true

2.3 量词符

用来设定某个模式出现的 次数

*相当于 >=0 可以出现0次或者很多次

 var rg = /^a*$/;
 console.log(rg.test(""));
 console.log(rg.test("a"));
 console.log(rg.test("aaa"));
  • +相当于 >=1 可以出现1次或者很多次 不包含0次

  • ? 相当于 1||0 只包括 1次 或 0次

  • {3 }重复3次 {3,} 大于等于3 {3,16} 大于等于3,小于等于16


2.4 预定义类

某些常见模式的简写方式

  • \d 相当于[0-9]
  • \D 相当于[^0-9]
  • \w 相当于[A-z0-9]
  • \W 相当于[^A-z0-9]
  • \s 匹配空格等
  • \S 匹配非空格

2.5正则替换

replace 替换

正则表达式参数

  • g: 全局匹配
  • i: 忽略大小写
  • gi:都有
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Neworend

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值