『JavaScript』Object和Function

本篇博客介绍一下JavaScript中对象和函数的相关概念。

Object


通过前面的学习,我们知道JavaScript中有六种数据类型:String、Number、Boolean、Null、Undefined和Object。其中前五种为基本数据类型,最后一种为引用数据类型。
对象属于一种复合的数据结构,在对象中可以保存多个不同的数据类型的属性。JS中对象分为以下三类

  • 内建对象。由ES标准中定义的对象。在任何的ES的实现中都可以使用,如:Math、String、Number、Function;
  • 宿主对象。由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象。如:BOM、DOM;
  • 自定义对象。有开发人员自己创建的对象。

对象的创建


创建对象有两种方式

  • 使用new关键字创建
    在这里插入图片描述
  • 使用对象字面量创建一个对象
    在这里插入图片描述
    注意对象字面量的属性名可以加引号,也可以不加建议不加。如果要使用一些特殊的名字,则必须加引号

向对象中添加属性


语法对象.属性名 = 属性值;
在这里插入图片描述

读取对象中的属性


语法对象.属性名;
在这里插入图片描述
在这里插入图片描述

  • 如果读取对象中没有的属性,不会报错而是会返回undefined
    在这里插入图片描述
    在这里插入图片描述

修改对象的属性值


语法对象.属性名 = 新属性值;
在这里插入图片描述
在这里插入图片描述

删除对象的属性


语法delete 对象.属性;
在这里插入图片描述
在这里插入图片描述

属性名和属性值


属性名

  • 对象的属性名不强制要求遵守标识符规范,什么乱七八糟的名字都可以,但是推荐遵循标识符规范;
  • 如果要使用特殊的属性名不能采用.操作符而应该采用[]操作符
    在这里插入图片描述
    在这里插入图片描述

属性值

  • JS对象的属性值,可以是任意的数据类型也可以是一个对象
    在这里插入图片描述
  • 当然也可以是一个函数,因为JS中函数也是一个对象。如果一个函数作为一个对象保存,那么我们称这个函数是这个对象的方法
    在这里插入图片描述
    在这里插入图片描述

in操作符


  • 使用in操作符,可以检查一个对象中是否含有指定的属性。如果包含则返回true否则返回false
  • 语法"属性名" in 对象;
    在这里插入图片描述
    在这里插入图片描述

枚举对象中的属性


  • 我们可以使用for…in语句来枚举一个对象中的属性
    在这里插入图片描述
    在这里插入图片描述

基本数据类型和引用数据类型


基本数据类型

  • String、Number、Null、Boolean和Undefined都是基本数据类型;
  • 基本数据类型的值直接在中存储,值与值之间是独立存在,修改一个变量不会影响其他变量;
  • 基本数据类型之间使用==进行比较,比较的是两个变量的值
    在这里插入图片描述

引用数据类型

  • Object是引用数据类型;
  • 引用数据类型是保存在内存中的,每创建一个对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的地址
  • 引用数据类型之间使用==进行比较,比较的是对象的内存地址
    在这里插入图片描述

Function


  • 函数也是一个对象。函数中可以封装一些功能(代码),在需要时可以执行这些功能(代码)。
  • 函数中可以保存一些代码在需要的时候调用,使用typeof 函数;返回的是function
    在这里插入图片描述
    在这里插入图片描述

创建一个函数


创建函数有三种方法

  • 方法一使用构造方法创建一个函数。将代码以字符串的形式传入构造方法
    在这里插入图片描述
    在这里插入图片描述
  • 方法二使用函数声明创建一个函数
    在这里插入图片描述
    在这里插入图片描述
  • 方法三使用函数表达式创建一个函数
    在这里插入图片描述
    在这里插入图片描述

参数和返回值


函数的参数

  • 调用函数时,解析器不会检查实参的类型,所以要注意,是否有可能会接收到非法的参数。如果有可能接收到非法参数,需要对参数类型进行检查;
  • 解析器也不会检查实参的数量,多余的实参不会被赋值
    在这里插入图片描述
    在这里插入图片描述
  • 如果实参的数量少于形参,没有对应实参的形参值为undefined
    在这里插入图片描述
    在这里插入图片描述
  • 函数的实参可以是任意类型
  • 定义形参相当于在函数作用域中声明了变量

函数的返回值

  • 函数内部可以声明一个函数
    在这里插入图片描述
  • 函数返回值可以是任意的数据类型,也可以是一个对象,当然也可以是一个函数。
    在这里插入图片描述
    在这里插入图片描述

立即执行函数


  • 我们知道函数定义完并不会立即执行,而是在函数被调用时才会执行
  • 立即执行函数在函数定义完,立即就会被调用
  • 语法(function(){})();
    在这里插入图片描述
    在这里插入图片描述
  • 立即执行函数只能执行一次

call和apply方法


  • 这两个方法都是函数对象的方法,需要通过函数对象来调用;
  • 对函数对象调用call()和apply()都会调用函数执行
    在这里插入图片描述
    在这里插入图片描述
  • 调用call和apply的时候可以将一个对象指定为第一个参数,此时这个对象将会成为函数执行时的this
    在这里插入图片描述
    在这里插入图片描述
  • call方法可以将实参在对象之后依次传递apply方法需要将实参封装到一个数组中统一传递
    在这里插入图片描述
    在这里插入图片描述

arguments


每次调用函数时,浏览器每次都会传递进两个隐含的参数

  • 函数的上下文对象this
  • 封装实参的对象arguments

arguments是一个类数组对象不是一个数组对象
在这里插入图片描述
在这里插入图片描述
我们在调用函数时,我们所传递的实参都会在arguments中保存,我们可以通过arguments.length获取实参的数量;也可以通过下标来使用传递来的实参,即使我们不定义形参
在这里插入图片描述
在这里插入图片描述
arguments有一个属性callee这个属性对应一个函数对象,就是当前正在执行的函数对象
在这里插入图片描述
在这里插入图片描述

作用域


JS中有两种作用域

  • 全局作用域
  • 函数作用域

全局作用域


  • 直接编写在script标签中的JS代码,都在全局作用域中
  • 全局作用域在页面打开的创建,页面关闭时销毁
  • 全局作用域中有一个全局对象window,我们可以直接使用。它代表的是一个浏览器窗口,由浏览器窗口创建,在全局作用域中,创建的变量都做为window对象的属性保存;创建的函数都会作为window的方法保存
    在这里插入图片描述
    在这里插入图片描述
  • 全局作用域中的变量都是全局变量,在页面的任意部分都可以访问到

变量的声明提前

  • 变量未创建使用会报错属性不存在使用不会报错,返回undefined
    在这里插入图片描述
    在这里插入图片描述
  • 定义一个变量可以省略var关键字
    在这里插入图片描述
    在这里插入图片描述
  • 使用var关键字声明的变量会在所有代码执行之前被声明如果不使用var关键字,则变量不会被声明提前
    在这里插入图片描述
    在这里插入图片描述

函数的声明提前

  • 使用函数声明形式创建的函数function 函数名(){}会在所有的代码执行之前就被创建,所以可以在函数声明前调用;
    在这里插入图片描述
    在这里插入图片描述
  • 使用函数表达式创建的函数,不会被声明提前,不会被提前创建
    在这里插入图片描述
    在这里插入图片描述

函数作用域


  • 调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
  • 每调用一次函数就会创建一个新的函数作用域,它们之间相互独立
  • 函数作用域中可以访问到全局作用域变量
    在这里插入图片描述
    在这里插入图片描述
  • 全局作用域中无法访问到函数作用域中的变量
    在这里插入图片描述
    在这里插入图片描述
  • 在函数作用域中操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有则向上一级作用域寻找,直到全局作用域。如果全局作用域也没有找到,则报错;
    在这里插入图片描述
    在这里插入图片描述
  • 如果想要在函数作用域中访问全局作用域中的变量,可以使用window.属性
    在这里插入图片描述
    在这里插入图片描述
  • 函数作用域中也有声明提前特性使用var关键字声明的变量,会在函数中所有的代码执行之前被声明函数声明创建的函数也会在所有代码执行之前创建
    在这里插入图片描述
    在这里插入图片描述
  • 函数作用域中不使用var关键字声明的变量都会成为全局变量
    在这里插入图片描述
    在这里插入图片描述

this


  • 解析器在调用函数时,会向函数内部传递一个隐含的参数,这个隐含的参数就是this
  • this指向的是一个对象,这个对象我们称为函数执行的上下文对象;

根据函数调用方式的不同,this会指向不同的对象

  • 当我们以函数的形式调用时,this永远都是window
    在这里插入图片描述
    在这里插入图片描述
  • 方法的形式调用时,this就是调用方法的那个对象
    在这里插入图片描述
    在这里插入图片描述
  • 以构造函数的形式调用的时候,this指向新创建的对象

使用工厂方法创建对象


我们可以通过工厂方法来大批量的创建对象
下面,我们来看一个例子来具体理解一下如何使用
在这里插入图片描述
在这里插入图片描述

构造函数


  • 构造函数就是一个普通的函数,创建方式和普通函数没有区别;
  • 构造函数习惯上首字母大写
  • 构造函数和普通函数的区别就是调用的方式不同,普通函数直接调用,而构造函数需要使用new关键字来调用

下面我们来看一个具体的例子
在这里插入图片描述
在这里插入图片描述

构造函数执行流程

  • 立刻创建一个新的对象
  • 将新的对象设置为函数的this,构造函数中的this指向新对象
  • 执行函数中的代码
  • 将新创建的对象作为返回值返回

使用同一个构造函数构造出来的对象,我们称为一类对象。我们将通过一个构造函数创建的对象,称为是类的实例。

  • 使用instanceof可以检查一个对象是不是一个类的实例。语法:对象 instanceof 构造函数;
    在这里插入图片描述
    在这里插入图片描述
  • 所有对象都是Object的后代任何对象 instanceof Object结果都是true
    在这里插入图片描述
    在这里插入图片描述

原型对象


  • 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype这个属性对应着一个对象,这个对象就是我们所说的原型对象
    在这里插入图片描述
    在这里插入图片描述
    我们来具体画一下示意图
    在这里插入图片描述
  • 如果函数作为普通函数调用,prototype没有任何作用;当函数以构造函数的方式调用时,它所创建的对象中都会有一个__proto__属性指向该构造函数的原型对象
  • 我们知道Student构造函数中有prototype属性指向其原型对象,同样的使用Student构造出的对象中也有__proto__属性,该属性同样指向Student的原型对象。原型对象相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象
    在这里插入图片描述
    在这里插入图片描述
  • 当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会到原型对象中寻找,注意原型对象也是一个对象,也有其原型对象,所以会一直去原型对象中找,直到Object对象的原型,Object对象的原型没有原型,如果在Object的原型中依然没有找到,则返回undefined

原型对象有什么用呢?


首先,我们再来看一下前面的通过构造函数创建对象的代码
在这里插入图片描述
使用这种方式来创建对象是有问题的Student函数中为每一个对象都添加了info方法。方法是在构造函数内部创建的。构造函数每执行一次,就会创建一个info方法。而这些方法是一模一样的,这是完全没有必要的,我们完全可以让所有的对象共享同一个方法

如何解决这个问题呢?我们有两种方法

  • 将info方法写到全局作用域中
    在这里插入图片描述
    在这里插入图片描述
    这种方法虽然可以避免创建多个函数对象,但是将函数定义在全局作用域中会污染全局作用域的命名空间。而且定义在全局作用域中很不安全
  • 使用原型对象,将函数写到原型对象中
    在这里插入图片描述
    在这里插入图片描述

总结

  • 以后创建构造函数时,可以将这些对象共有的属性和方法,同一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了

in和hasOwnProperty


  • 我们可以使用in来检查对象中是否具有某个属性,如过对象中没有,但是原型对象中有,也会返回true
  • 我们可以使用对象的hasOwnProperty()方法来检查对象自身中是否包含指定属性,使用该方法只有对象本身包含时才返回true,不包括原型对象中有

在这里插入图片描述
在这里插入图片描述

toString


  • 当我们在页面中打印一个对象时,实际上输出的是对象的toString方法的返回值
    在这里插入图片描述
    在这里插入图片描述
  • 如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法
    在这里插入图片描述
    在这里插入图片描述

版权声明:本文为sss_0916原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。