JavaScript面向过程编程

一.JavaScript面向过程编程

1.定义:分析出解决问题需要的步骤,然后用函数这些步骤一步一步实现,使用时再调用

二.类和对象

定义:提取公共部分模块化

1.类:

//创建类class  
class 类名 {
	
}
//利用类创建对象 new
new 类名()

1.类里有一个constructor函数,可以接收传递过来的参数,同时返回实例对象
2.constructor 只要new生成实例时会自动调用这个函数,如果我们不写,类也会自动生成new不能省略
3. 语法规范:类 与类名后面不需要加小括号,生成实例,类名后加小括号,构造函数不需要加function

2.类中添加方法

class 类名 {
            constructor(a, b) {
            }
            方法名(){
	方法逻辑 
        }	
}
        //利用类创建对象 new
        new 类名()

1.我们类里面的函数不需要写function    多个函数方法用逗号分隔

3.类的继承 

class 父类 {
            constructor(a, b) {
            }
            方法名(){
	方法逻辑 
        }	
}
class 子类  extends 父类{
         
}
        let a = new 子类()
	a.方法    //使用 

4.super使用

class 父类 {
            constructor(a, b) {
	this.a = a //使用必须加this
	this.b = b
            }
            方法名(){
	方法逻辑 
        }	
}
class 子类  extends 父类{
          constructor(a, b) {
	super(a,b) //调用了父类中的构造函数 因为this的指向不同所以将子类的参数传给父类
            }
}
        let a = new 子类()
	a.方法    //使用 

1.继承中,如果实例化子类输出的一个方法,先看子类有没有之个方法,有就先执行子类的,就近原则
2.继承中,如果子类没有,就会去父类查找,如果有就执行父类的方法
3.如果两个都有一样的方法或者想调用父类的方法可以,super.方法()调用父类中的函数
重点:
(1).super调用必须再this之前调用
(2).再ES6中类没有变量的提升,所以先定义类,才能通过类的实例化对象 
(3).类里面的共有的属性方法一定加this使用
(4).this的指向,谁调用指向谁

三.构造函数和原型

 1.再ES6之前,对象不基于类创建,而是用构造函数的特殊函数来定义对象和它的特征

使用:

 function 函数名 (a,b){   // a,b是形参
            方法
        }
        let a = new 函数名(a,b)  // a,b是实参
//new执行做的事情

1.在内存中创建一个新的空对象
2.让this指向这个新的对象
3.执行构造函数里的代码,给这个新的对象添加属性和方法
4.返回这个新的对象(不用写return)
// 实例成员就是构造函数内部this添加的成员 实例成员只能通过实例化对象来访问
//静态成员,在构造函数 本身添加的成员 如  函数名.变量 ='xxxx'  (只能通过构造函数来访问)

2.构造函数的问题

1.存在内存浪费的问题,每构造一个函数就会在内存占有不同内存空间
2.构造函数的原型 prototype对象
  我们可以把相同的方法,直接定义在prototype身上,这样所有的对象实例就可以共享
    函数名.prototype.方法 = function(){
    }

3.对象原型__proto__

1.对象都会有一个__proto__属性,指向构造函数的prototype原型对象,之所以我们可以使用构造函数prototype原型对象属性和方法,就是因为对象有__proto__原型存在
2.方法查找原则:首先看调用的对象本身是否有这个方法,有就执行,没有就会去prototype插值
3.__proto__对象原型的意义就是为对象的查找机制提供一个方向,在实际开发中不可以使用这个属性
4.构造函数中的   constructor


1.constructor 这个属性指回原来的构造函数
2.如果我们修改了原来的原型对象,给原型对象赋值的是一个对象,则必须手动的利用constructor指回原来的构造函数
5. 构成函数与实例、原型对象三者关系

1.构成函数与原型对象关系
构造函数 prototype指向 原型对象 原型对象的prototype.constructor也指向构造函数

2.构成函数与实例、原型对象关系 new一个实例对象,构造函数就会指向实例对象 实例对象中__proto__指向原型对象 ,原型对象中prototype.constructor再指回构造函数

3.原型对象中的__proto__指向object原型对象中的prototype,object构造函数 object.prototype再指向object原型对象,object原型对象中,object原型对象.constructor再指回object构造函数  object原型对象prototype.__proto__则为null
4.查找机制:
当访问的一个对象的属性或方法时,首先查找自身,自身没有就会找它的原型对象,(也就是__proto__ 指向prototype) 如果还没有找到就会查找原型对象的原型(object原型对象)类推直到为null为止

四.this指向的问题

1.在构造函数中,this指向的是对象对象实例
2.原型对象函数里的this指向的是实例对象

五.扩展内置对象

自定义方法:

​
Array.prototype.方法名 = function(){
            //方法逻辑
       }

​

六.数组遍历

1.forEach()

数组.forEach((value,index,array)=>{
        //value 返回每个数组元素 index 数组元素的索引值 array数组本身   在forEach中  return  true不会中止迭代
       })

2.filter()

filter()方法创建一个新的数组,新数组的元素是通过检查指定数组中符合条件的所有元素,主要用于筛选数组
注意:它返回一个新数组
数组.filter((value,index,array)=>{
       //value 数组当前项的值  index 数组元素的索引值 array数组本身
       })

3.some()

数组.some((value,index,array)=>{
        //value 数组当前项的值   index 数组元素的索引值     array数组本身     在some中  return  true会中止迭代
       })

1.some()方法用于检测数组元素是否满足指定条件,通俗点查找数组中是否满足条件的元素
2注意:它返回值是布尔值如果查找到元素,就返回ture,如果查找不到就返回flase
3.如果找到第一个满足条件的元素,则中止循环,不在继续查找

七.函数的定义方式

1.自定义方式(命名函数)

function 函数名 (){}

2.函数表达式(匿名函数)

let a =  function (){}

3.利用new Function

let a =new Function('参数1','参数2','函数体') //字符串形式
//效率低不建议使用 函数也是对象 万物皆对象

八.函数调用的方式

//a是变量的名字,b是方法名字

function a (){}
//调用方式:
1.a() 
2.a.call()

2.对象的方法

 let a ={
        b:function(){

        }
      }
      a.b()       

3.构造函数

function a (){}
new a()

4.绑定事件函数

a.onclick = function(){}  

5.定时器函数

setInterval(()=>{}) //定时器自动调用

6.立即执行函数

(function a (){})() //自己调用

九.this的指向

1.这些this的指向,是当我们调用函数的时候确定的,调用方式的不同决定this的指向不同
2.一般指向我们的调用者

this的指向
调用方式 this的指向
普通函数调用window
构造函数调用实例对象,原型对象里面的方法也指向实例对象
对象方法的调用  该方法所属对象
事件绑定方法绑定事件对象
定时器函数  window
立即执行函数  window 

十.改变this指向

1.改变this指向 有三种方法  bind() call()  apply()

2.使用:

1.call:

let a ={

}
function b (){}
b.call(a)  // b是函数名  a是this要指向的
// call 第一个可以调用函数,第二个可以改变函数this的指向  call也可以实现继承
function a (){


}
function b (){
a.call(this ,a,b....)  //调用了a    也改变了b的this的指向,指向了a

}

2.apply方法

apply()方法调用一个函数。简单理解为调用函数的方式,但是它可以改变函数的this指向

a.apply(thisArg ,[argsArray])

thisArg:在a 函数运行时指定的this值 
argsArray:传递的值,必须在数组里面
返回值就是函数的返回值,因为它就是调用函数

apply的主要应用 比如说我们可以利用 apply借助数学内置对象求最大值

 let a =[1,2,3,5,9]
Math.max.apply(Math,arr)

3.bind方法

bind()的方法不会调用函数。但是能改变函数this指向

let b = a.bind(thisArg  ,  a  ,  b......)   //需要变量接收


1.thisArg  :在a函数运行时指定this的值
2.a ,b:传递的其他参数
3.返回的原函数改变this之后产生的新函数
4.如果有道函数我们不需要立即调用,但想改变内部this的指向 如点击一个按钮一定时间内不可以点击
总结:
相同点:都可以改变函数this的指向
区别:

1.call 和apply 会调用函数,并且改变this的指向
2.call 和apply 传递的参数不易 ,call传参 a,b,c.....
apply必须数组[1,2,3,4]
3.bind 不会调用函数,可以改变函数内部this的指向

主要应用场景:

1.call经常做继承
2.apply经常跟数组有关系,比如借助与数学对象实例求最大最小值
3.bind 不调用函数,但还是想改变this指向,比如改变定时器的指向

 

十一.严格模式

更改:
1.消除了js语法的一些不合理,不严谨之处,减少了一些怪异行为 比如可以先使用变量,再声明这种怪异
2.消除了代码运行的一些不安全之处,保证代码安全运行
3.提高代码编译的速率,加速运行速度
4.禁用了未来版本中可能会定义的一些语法 比如calss,enum,export ........不能做变量名

使用:
严格模式可以应用到整个脚本或个别函数中。因此在使用时,我们可以将严格模式    分为脚本开启严格模式 或     为函数开启严格模式
1.为脚本开启严格模式
需要在所有语句之前放一个特点语句 'use strict' 下面的代码就会按严格模式执行
2.为函数开启严格模式

function a(){
        'use strict'  //为函数a开启严格模式
     }


2.严格模式发生的变化
1.变量名先声明再使用
2.严禁删除声明过的变量
3.严格模式下全局作用域中函数中this的指向undefined
4.如果构造函数不加new调用,this就会报错 加了就会指向实例对象
5.严格模式下函数里面的参数不允许重名

十二.高阶函数

1.函数也是一种数据类型,同样可以作为参数,传递给另一个参数使用。最典型的就是作为回调函数
2.高阶函数时对其他汉书进行操作的函数,他接收函数作为参数或将函数作为返回值输出

十三.闭包

1.定义:闭包指有权访问另一个函数作用域中变量的函数。 一个作用域可以访问另一个函数中的变量
如:

function a(){
        let b = 10
        function c (){
            console.log(b); //可以得出知道b的值
        }
        c()
      }
      a()  
1.外部函数访问内部变量
如:
function a(){
        let b = 10
        function c (){
            console.log(b); 
        }
        return c
      }
      let d =  a()  
      d()   //可以得出知道b的值

十四.递归

定义:一个函数内部可以调用其本身,那么这个函数就是递归函数 容易造成死循环,必须在里面添加退出条件
如:

let b = 0
        function a(){
            console.log(1);
            if (b === 3) {
                return
            }
            b++
            a()
        }
        a()

十五.浅拷贝与深拷贝

1.浅拷贝只能拷贝一层,更深层次只拷贝了地址进行引用
2.深拷贝多层,每一层级别的数据都会拷贝

深拷贝的封装:

function deepCopy(newobj,oldobj){
            for(let k in oldobj){
                let  item  = oldobj[k]
                if (item instanceof Array ) {
                    newobj[k] =[]
                    deepCopy(newobj[k],item)
                }else if( item instanceof Object){
                    newobj[k] ={}
                    deepCopy(newobj[k],item)
                }else{
                    newobj[k] = item
                }

            }
        }
        deepCopy(a,b)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值