博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavScript基础学习——面向对象编程
阅读量:3917 次
发布时间:2019-05-23

本文共 4435 字,大约阅读时间需要 14 分钟。

一、全局作用域

在函数外部定义的变量或函数,叫全局变量或全局函数。它们可以在当前程序的任意位置使用。在全局中定义变量可以用var,也可以直接添加window的属性。

生命周期:它们会一直占用内存,只能在当前文件中使用。如果想在多个文件中使用变量,需要用到cookie或本地存储。

例1 测试全局作用域

  
Document

二、局部作用域

在函数内部定义的变量或函数,叫局部变量或局部函数。它们只能在函数内部使用。在函数内部用var定义局部变量,如果用window定义的变量,则为全局变量。

生命周期:从调用时开始创建,到函数执行完后立即销毁。

例2 测试局部作用域

  
Document

三、块级作用域

在ES5中没有块级作用域,ES6中有。一对{ }为一个块,块级作用域就是变量或函数只在当前这组{}中有效。

在ES5中可以用IIFE实现块级作用域,ES6中用let实现。

 

四、IIFE

1、什么是IIFE?

IIFE(Immediately Invokeed Function Expression:立即执行函数表达式),声明函数的同时立即执行调用这个函数。定义的函数没有函数名,只能执行一次,无法在其它地方被调用,也不会造成全局污染。

2、IIFE的作用

可以用于解决运算中产生的全局污染问题(实际上它是一个闭包的写法)。它也是ES5中实现块级作用域的方式。

3、IIFE和特点

(1)将所有运算代码都放在匿名函数中;
(2)函数是一个表达式,没有函数名,只能被执行一次;
(3)执行一次后所产生的数据和变量就立即销毁,不会造成全局污染。

4、IIFE语法

(function(params){

  ...
})(exprs)

将函数的定义和调用写在一起。

5、IIFE的用法(推荐用前面两种写法)

(function(形参列表){

    ...
    window.变量 = 表达式;
})(实参列表);

例3 测试第一种写法 计算1+2+3+...+100

  
Document

var 变量名 = (function(形参列表){

    ...
    return 表达式;
})(实参列表);

例4 测试第二种写法 计算1+2+3+...+100

  
Document

!(function(形参列表){

    ...
    return 表达式;
})(实参列表);

+(function(形参列表){

    ...
    return 表达式;
})(实参列表);   

 

五、闭包

1、什么是闭包?

闭包就是一种作用域的体现,函数外部可以访问函数内部的数据。正常情况下,函数外部不能访问函数内部的变量,但是通过这种特殊的写法,将函数内的子函数暴露在全局上,可以在外部调用且可以访问到函数内部的数据,即可以让全局访问局部的数据。

简单地说:就是在函数外部获取函数内部的数据。

2、闭包的作用

(1)实现函数外部可以访问函数内部的数据;

(2)减少了全局变量的使用,避免全局变量的污染。

3、闭包的特点

(1)闭包一定是函数内嵌套函数;
(2)闭包是一种作用域的体现,函数外可以访问函数内的数据;
(3)闭包采用IIFE写法,由于内部数据被全局所调用,将延缓资源的回收(即闭包中的变量的值用完后不会立即销毁,会驻留内存一段时间)。

4、闭包的缺点

(1)闭包中的变量会占用更多的内存空间;
(2)可能会导致内存泄露。

5、闭包的写法

第1种写法:

      (function(){
        ...
        window.函数名 = function(){
          ...
          return 变量;
        }
      })()

例5 测试第一种写法

  
Document

第2种写法:

      var 变量 = (function(){
        ...
        return function(){
          ...
          return 变量;
        }
      })()

例6 测试第二种写法

  
Document

六、内存管理

在闭包中调用局部变量,会导致这个局部变量无法及时被销毁,相当于全局变量一样会一直占用着内存。如果需要回收这些变量占用的内存,可以手动将变量设置为null。然而在使用闭包的过程中,比较容易形成 JavaScript 对象和 DOM 对象的循环引用,就有可能造成内存泄露。这是因为浏览器的垃圾回收机制中,如果两个对象之间形成了循环引用,那么它们都无法被回收。

解决方案:

(1)把循环引用中的变量设为 null 即可;
(2)把闭包写法改造成一个引用外部函数写法。

例7 测试内存管理

  
Document
box

七、JavaScript对象

对象分为内置对象(构造函数/方法)和用户自定义对象。

1、内置对象:String Date Math RegExp Function Object Array Boolean Number...

var str1 = new String('abc');// 类型为object
var str2 = 'abc'  // 类型为string

2、用户自定义对象

(1)字面量

      var obj1 = {
        name: 'aaa',
        sex: 'male'
      }

(2)用new构建

      var obj2 = new Object({
        name: 'aaa',
        sex: 'male'
      })

(3)构造函数(相当于ES6中类)

      a.创建方法

        function 构造函数名/类名(形参列表){
          // 类的特征-属性
          this.属性名 = 参数;
          ...

          // 类的形为-方法

          this.方法名 = function(){
            ...
          }
          ...
        }
      b.使用构造函数实例化对象
        var 对象名 = new 构造函数名/类名(实参列表)
      c.构造函数特征
        i)构造函数名(类名)首字母要大写(W3C的规定)(要使用大驼峰写法);

          补充:

            小驼峰写法:studentClassicScore
            大驼峰写法:StudentClassicScore
        ii)属性和方法都要挂载到this上;
        iii)没有return语句。
      d.实例化机制
        i)创建一个对象;
        ii)将构造函数中的this指向新对象;
        iii)执行构造函数中的语句,将所有的属性和方法挂载到新的对象上;
        iv)把新的对象的内存地址赋值给变量。
      e.问题
        如果构造函数实例化的对象中的属性和方法的内容一样,因为它们会各自占用独立的空间,会造成内存的浪费。

例8 构造函数

  
Document

4、原型

      a.什么上原型?
        原型就是prototype,所有function定义的函数都拥有这个属性。
        prototype这个属性是一个对象,也是一个指针,是用来添加所有实例共享属性和方法的。
      b.原型的作用
        i)解决方法过载(为每个对象都单独创建一个方法,浪费了大量的内存资源,这种情况叫方法过载);
        ii)扩展构造函数的属性和方法(功能)。
      c.原型的写法
        i)扩展属性
          构造函数名.prototype.属性名 = 表达式;
        ii)扩展方法
          构造函数名.prototype.方法名 = function(){
            ...
          }
        
        注意:在开发过程中,私有属性和方法放在构造函数中,而共享属性和方法用原型添加。

例9 原型

  
Document

5、混合模式

混合模式 = 构造函数 + 原型 

在构造函数中定义私有的属性和方法,通过原型添加共享的属性和方法。

例10 混合模式

  
Document

6、基本模式(JSON语法格式)

      var 对象 = {
        属性:属性值,
        ...,
        方法:function(){...},
        ...
      }

这样做的目的是为了减少全局变量和全局方法的使用,从而避免全局污染。

例11 基本模式

  
Document
id
class

pppppp

pppppp

pppppp

7、工厂模式

一般用于大批量创建对象(这批对象有相同的属性和方法)。给定一些值,创建一个结果。

      a.创建方法:

        创建一个函数,在函数中创建对象,最后再返回这个对象。

      b.缺陷

        让不同对象有不同属性或方法,工厂模式就很难实现了。

      c.优点

        减少了重复性代码。

  混合模式(构造函数+原型)在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。

例12 工厂模式

  
Document

八、this(面试核心点)

this是一个地址指针。

1、全局中的this,指向window对象。

  
Document

2、函数中的this

原则:谁调用就指向谁。一般情况下是指向window对象的。

  
Document

如果开启了"use strict;"严格代码格式,this指向的是window。

  
Document

3、对象方法中的this,指向当前对象。

  
Document

4、构造函数中的this,指向当前实例化的对象。

  
Document

5、借来的this,所有函数都有三个方法(call、apply和bind),可以用它们实现函数中this指向新的对象(修改函数中this的指向)。

(1)call:主动式将函数中的this指向新的对象,调用一次就立即执行一次(谁调用就指向谁)。

语法:被调用对象的方法.call(当前对象,参数1,参数2,...)

  
Document

(2)apply

用法与call一样,只是传参格式不一样。传参必须以伪数组的方式传递,不管有几个参数,都必须以这种格式进行传递。

语法:被调用对象的方法.apply(当前对象,[参数1,参数2,...])

  
Document

(3)bind(ES5新增)

被动式改变this指向,实现对原对象的拷贝。

语法:回调函数.bind(对象,参数1,参数2,...)

  
Document

6、call、apply和bind的区别

相同点:

    i)都是函数原型的方法,可以改变函数中this的指向;
    ii)第一个参数都是this要修改的目标对象;
    iii)都可以传递参数。

不同点:

    i)call和apply是主动式的,修改this指向时立即调用1次;
    ii)bind是被动式的,只修改this的指向,不执行;
    iii)call的参数是直接列举在对象的后面,而apply是以伪数组的形式传参;
    iv)bind一般用在回调函数中。

转载地址:http://sfvrn.baihongyu.com/

你可能感兴趣的文章
程序员过关斩将--少年派登录安全的奇幻遐想
查看>>
ASP.NET Core 依赖注入-集成 Autofac
查看>>
ASP.NET Core Authentication and Authorization
查看>>
如何在 ASP.NET Core 中 自定义中间件
查看>>
蚂蚁调度AntJob-分布式任务调度系统
查看>>
Dapr微服务应用开发系列3:服务调用构件块
查看>>
【源码解读】Vue与ASP.NET Core WebAPI的集成
查看>>
临近年关,发生两起磁盘占满引发的服务下线故障
查看>>
如何在 ASP.NET Core 中使用 ActionFilter
查看>>
引入Jaeger——使用
查看>>
玩转git-flow工作流-分支解析
查看>>
灵魂拷问:你和大佬,技术差距有多大?
查看>>
年终将至,回顾我们一起走过的 2020
查看>>
开源·共享·创新|2020年中国.NET开发者大会圆满收官!
查看>>
C# 9 新特性——init only setter
查看>>
什么是ASP.NET Core静态Web资产?
查看>>
如何在 C# 中使用 反射
查看>>
银河麒麟V10入选2020中国十大科技新闻
查看>>
Windows Terminal 新手入门
查看>>
IdentityServer4 之Client Credentials走起来
查看>>