醉梦孤城的个人博客

记录我旅程美好的风景

Open Source, Open Mind,
Open Sight, Open Future!
  menu
9 文章
19681 浏览
1 当前访客
ღゝ◡╹)ノ❤️

关于js高级的学习

JavaScript高级学习

首先由于JavaScript也是一种成熟的编程语言,所以也有编程思想的应用;下面以两大成熟的编程思想来进行开篇。

两大编程思想

面向过程 POP(Process-oriented programming)

面向过程的核心思想就是,详细分析之后列出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现使用的时候在一个一个的一次调用就行了。

面对对象OOP(Object Oriented Programming)

面对对象思想是将事务分解成一个个的对象,然后由对象之间分工与合作。
####面对过程和面对对象区别
面向过程目的性强,适合小项目使用。代码不能很好的重复利用,后期维护,更新,扩展都比较麻烦
面向对象 目的性比较弱,需要谁调用谁就可以。代码重用性比较高。而且由于各部分分工明确互不干扰,所以后期维护,扩展和更新都比较方便适合大项目使用,灵活性高。而且效率高。

面向对象三大特性

封装:将功能封装到一个函数中谁使用谁调用大大提高了代码的重用性
继承:可以将一个函数中的属性方法让另一个函数使用,大大减少了冗余代码
多态:同一类事务可以拥有多种形态

JavaScript中ES6

类实在ES6中新加入的概念在以往的Es5中并没有类的概念。其实类的本质还是function
类的所有方法都定义类的prototype属性上
类创建的实例中,里面也有__proto__指向类的prototype原型对象
所以在ES6中的类大部分功能在ES5中也能够实现只不过新的class写法只是让对象原型的写法更加清晰更像面向对象编程的语法而已
####类:一些具有共同属性对象的集合
在ES6中是指的将对象属性和方法封装成一个类
类可以进行实例化,获取类的对象
对象:具体的一个事物
对象是由属性和方法组成的
属性:事物的特征,在对象中用属性来表示(常用名词)
f方法:事物的行为,在对象中用方法来表示(常用动词)
面向对象的思维特点:

​ 1.抽取(抽象)对象共用的属性和方法组织(封装)成一个类(模板)

​ 2.对类进行实例化, 获取类的对象

创建类

//类名首字母要大写
class F(){
//constructor构造函数
constructor(参数){
//具体属性
//共有属性都放在constructor中
this.uname=unae;
this.age=age;

}
//添加方法
//方法之间不能用逗号隔开而且不用使用function关键字,在类中调用方法需要使用this关键字
say(){
}
tiao(){
}
}

ES6中的继承

直接上代码

//定义父类
class Father(){
constructor(name,age){
this.name=name;
this.age=age;

}
say(){
}
}
//定义子类
//使用extends实现继承现在子类就可以使用父类中的属性和方法
//但是如果子类中要创建自己的属性,再继承父类的话需要使用关键字super
//产生原因是当子类没有constructor的时候可以随意用父类的,但是如果子类也含有的话,constructor会返回实例,this的指向不同,不可以再直接使用父类的东西必须要使用super关键字
class Son extends Father(){
conconstructor(name,age,color){
//super关键字需要放在this之前
super(name,age);
this.color=color;
}
}

ES6三个注意事项

  1. 在ES6中类的没有变量提升,所以必须要先定义类,才能通过类实例化对象
  2. 类里面的共有属性和方法一定要加this使用
  3. constructor里面的this指向实例对象方法里面的this指向这个方法调用者

this指向

构造函数的this指向实例对象
在事件处理中this指向事件源
普通函数和自调用函数this指向window对象

构造函数和原型

前言:在典型的OOP 的语言中(如Java),都存在类的概念,类就是对象的模板,对象就是类的实例,但在ES6之前,JS 中并没用引入类的概念。

ES6,全称ECMAScript6.0 ,2015.06 发版。但是目前浏览器的JavaScript 是ES5 版本,大多数高版本的浏览器也支持ES6,不过只实现了ES6 的部分特性和功能。

在ES6之前,对象不是基于类创建的,而是用一种称为构建函数的特殊函数来定义对象和它们的特征。而构造函数是一种特殊的函数主要是用爱初始化对象的,给对象成员变量赋值初始值,它总与new一起使用。我们可以把对象一些公共属性和方法抽取出来然后封装到这个函数中。

注意事项

构造函数用于创建某一类对象,首字母要大写
构造函数需要和new一起使用

new的那些事

new在创建的时候会做四件事
首先在内存中创建一个新的对象
让this指向这个新的对象
执行构造函数里面的代码,让这个新对象添加属性和方法
返回这个新对象

静态对象和实例对象

在构造函数中我们可以添加一些成员,添加的方式不同名字也不同,可以在构造函数本身上添加的称为静态成员,只能由构造函数本身来访问。实例成员:在构造函数内部创建的对象成员。只能通过实例化的对象来访问

function Person (uname, age) {
			this.uname = uname;
			this.age = age;

		this.say = function () {
			console.log(123);
		}

}

	var obj = new Person('张三',22);	
	console.log(obj.uname);

	// console.log( Person.uname );
	Person.leibie = '人';

	console.log(Person.leibie);
	console.log(obj.leibie);
prototype构造函数原型

什么是构造函数原型对象,其实就是一个属性。每个构造函数都有的属性。我们可以在里面放一些函数达到共享方法,从而节省内存。特别注意每个构造函数都有prototype属性
共享实例

function Star (uname, age) {
this.uname = uname;
​		this.age = age;
​	

​	}
​	Star.prototype.sing = function () {
​		console.log(this.uname + '在唱歌');
​	}

​	var zs = new Star('张三', 22);
​	var ls = new Star('李四', 22);
​	// console.log( Star.prototype );
​	zs.sing();
​	ls.sing();

总结:所有的公共属性写到构造函数里面,所有的公共方法写到原型对象里面

__proto__对象原型

主要作用就是指向prototype,构造函数和原型对象都会有一个属性proto 指向构造函数的prototype 原型对象,之所以我们对象可以使用构造函数prototype 原型对象的属性和方法,就是因为对象有proto 原型的存在。

基于es5的继承(组合继承)

上面已经说过类的本质还是函数,所以es6的类实现的继承es5也能实现,实现原理就是更改this指向

实现属性的继承
function Father (uname,age) {
			// this指向父类的实例对象
			this.uname = uname;
			this.age = age;
			// 只要把父类的this指向子类的this既可
		}
		function Son (uname, age,score) {
			// this指向子类构造函数
			// this.uname = uname;
			// this.age = age;
			// Father(uname,age);
			Father.call(this,uname,age);
			this.score = score;
		}
		Son.prototype.sing = function () {
			console.log(this.uname + '唱歌')
		}
		var obj = new Son('zs',22,99);
		console.log(obj.uname);
		console.log(obj.score);
		obj.sing();

实现方法的继承

实现原理:通过让子类的prototype 原型对象=new父类();一般情况下,对象的方法都在构造函数的原型对象中设置,通过构造函数无法继承父类方法。(ps:hu会覆盖掉子类的constructor属性,所以需要我们手动添加上去)

function Father () {

		}
		Father.prototype.chang = function () {
			console.log('唱歌');
		}

		function Son () {

		}

		Son.prototype = new Father();
		var obj = new Son();
		obj.chang();

		Son.prototype.score = function () {
			console.log('考试');
		}
//实现了方法继承
		obj.score();
	//实现继承后,让Son指回原构造函数
Son.prototype.constructor = Son;


总结:用构造函数实线属性继承,用原型对象实线方法继承

ES5新增方法

数组方法

forEach()

array.forEach(function(currentValue, index, arr))
数值说明:
currentValue:数组当前项的值
index:数组当前项的索引
arr:数组对象本身

filter()

array.filter(function(currentValue, index, arr))
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组

注意它直接返回一个新数组

currentValue: 数组当前项的值

index:数组当前项的索引

arr:数组对象本身回调函数里面添加return添加返回条件

some()

array.some(function(currentValue, index, arr)) 【注意:找到或者满足条件立刻停止】

some() 方法用于检测数组中的元素是否满足指定条件. 通俗点查找数组中是否有满足条件的元素

注意它返回值是布尔值, 如果查找到这个元素, 就返回true , 如果查找不到就返回false.

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

currentValue: 数组当前项的值index:数组当前项的索引

arr:数组对象本身

字符串方法

str.trim()
trim():删除字符串两侧的空白符

函数进阶

函数类型

  1. 普通函数【fn()】

  2. 对象的方法【obj.taiji = function () {}【obj.taiji()】】

  3. 构造函数【new Fn();】

  4. 绑定事件函数【btn.onclick = function () {}【btn.onclick();】】

  5. 定时器函数【window.setInterval(function () {},1000);】

  6. 立即执行函数【(function () {})()】

改变this指向

普通函数中this指向window
在构造函数中this指向的是当前实例对象
在对象当中指向的就当前对象
在事件处理函数指向事件源

call()
apply()
bind()
相同点: 都可以改变函数内部的this指向.
区别点: 1.call 和apply 会调用函数, 并且改变函数内部this指向.2.call 和apply 传递的参数不一样, call 传递参数aru1, aru2..形式apply 必须数组形式[arg]3.bind 不会调用函数, 可以改变函数内部this指向
主要应用场景: 1.call 经常做继承. 2.apply 经常跟数组有关系.比如借助于数学对象实现数组最大值最小值3.bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向

严格模式

严格模式就是对正常的JavaScript 语义做了一些更改:

1.消除了Javascript语法的一些不合理、不严谨之处,减少了一些怪异行为。【例如变量,不声明就报错】2.消除代码运行的一些不安全之处,保证代码运行的安全。3.提高编译器效率,增加运行速度。4.禁用了在ECMAScript的未来版本中可能会定义的一些语法,为未来新版本的Javascript做好铺垫。比如一些保留字如:class, enum, export, extends, import, super 不能做变量名

<script>"use strict"</script>:脚本开启严格模式
<script>function fn () {"use strict"}</script>为函数开启严格模式

ps:严格模式在IE10 以上版本的浏览器中才会被支持,旧版本浏览器中会被当做字符串忽略掉。

高阶函数

概念:高阶函数是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。

  function fn (n) {
 n();

            }

            var m = function () {console.log('你好');};

            fn(m);
//第二种高阶函数
       function fun () {

                var k = function () {console.log('你好');}

                return k;

            }

            var result = fun();
result();

闭包

闭包(closure)指有权访问另一个函数作用域中变量的函数。【很多种解释,都并不权威】

简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。

function fn1(){
	// fn1 就是闭包函数
	var num = 10;
	function fn2(){
		console.log(num); // 10,num就被提升为了全局变量
	}
	fn2()
}
fn1();
/*
变量根据作用域的不同分为两种:全局变量和局部变量。

1. 函数内部可以使用全局变量。
    
2. 函数外部不可以使用局部变量。
    
3. 当函数执行完毕,本作用域内的局部变量
会销毁。
但是闭包函数不会被主动销毁作用域需要我们手动销。所以闭包函数一定要慎用,太占用资源
*/

递归

/*递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数。简单理解:函数内部自己调用自己, 这个函数就是递归函数

递归:函数调用函数其本身

注意:递归函数的作用和循环效果一样,由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件return。*/
//利用递归求1~n的阶乘

//利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
 function fn(n) {
     if (n == 1) { //结束条件
       return 1;
     }
     return n * fn(n - 1);
 }
 console.log(fn(3));

## 深拷贝和浅拷贝

浅拷贝

//浅拷贝:只拷贝最外面一层,对于结构复杂的数据类型来说无法完成拷贝
var obj = {
			name : '张三',
			age : 22
		};

		var newObj = {};
		for (key in obj) {
			newObj[key] = obj[key];
		}

		console.log(newObj);
		
es6:新方法
Object.assign(target, sources);

console.log(newObj);

深拷贝

var obj = {
			name : '张三',
			age : 22,
			messige : {
				sex : '男',
				score : 16
			},
			color : ['red','blue','pink']

		}

		var newObj = {};


		function kaobei (newObj,obj) {

			for (key in obj) {

				if (obj[key] instanceof Array) {
					newObj[key] = [];
					kaobei(newObj[key],obj[key]);
				} else if (obj[key] instanceof Object) {
					newObj[key] = {};
					kaobei(newObj[key],obj[key])
				} else {
					newObj[key] = obj[key];
				}

			}

		}
		obj.messige.sex = 99;
		kaobei(newObj,obj);
		console.log(newObj);

正则表达式

正则表达式( Regular Expression )是用于匹配字符串中字符组合的模式。在JavaScript中,正则表达式也是对象。

作用:检索关键字,过滤敏感字符,表单验证

正则表通常被用来检索、替换那些符合某个模式(规则)的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)。此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等 。
特点: 灵活性、逻辑性和功能性非常的强。
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
3. 对于刚接触的人来说,比较晦涩难懂。比如:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$。
4. 实际开发,一般都是直接复制写好的正则表达式. 但是要求会使用正则表达式并且根据实际情况修改正则表达式. 比如用户名: /^[a-z0-9_-]{3,16}$/
示例:

//第一种方法:通过调用RegExp对象的构造函数创建 
var regqq=new RegExp(/123/);
console.log(regqq);
//第二种方法:利用字面量创建 正则表达式
var rg=/abc/;//含义:只要包含abc就可以了

边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

^ : 表示匹配行首的文本(以谁开始)【/^abc/:以abc为开头】

$:表示匹配行尾的文本(以谁结束)【/^abc$/:只能是abc】

 [] 方括号

var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true

量词符
量词		说明

*		重复0次或更多次【>=0次】/^[a-z]*$/

+		重复1次或更多次【>=1次】【/^[a-z]+$/】

?		重复0次或1次

{n}		重复n次

{n,}	重复n次或更多次

{n,m}	重复n到m次
注意:{n,m}n和m之间不准有空格

敏感字符处理

使用replace替换

      // 点击发布:点击按钮,获取文本内容,创建li添加内容

  

        // 获取元素

        var btn = document.querySelector('input');

        var txt = document.querySelector('.txt');

        var ul = document.querySelector('ul');

        // 屏蔽敏感字

        btn.onclick = function() {

  

            // 获取到文本域的内容

            var lue = txt.value;

            // 判断文本域内容是否为空

  

            if (lue.trim()) {

                // 创建一个li元素

                var li = document.createElement("li");

                // 判断内容是否有敏感字,若有则替换掉

                lue = lue.replace(/si/, "**");

                lue = lue.replace(/士大夫撒/, "66666");

                //给创建的li添加内容

                li.innerHTML = lue;

                // 将心创建的li添加到ul中

                ul.appendChild(li);

            }

  

            // 清空文本域

            txt.value = '';

  
  

        }

本期分享结束。下次将会分享下关于Ajax学习


标题:关于js高级的学习
作者:zuimenggucheng
地址:http://chengwy.top:8080/articles/2019/09/22/1569152559512.html