Object对象
Object类型,我们也称为一个对象。是JavaScript中的引用数据类型。
- 它是一种复合值,它将很多值聚合到一起,可以通过名字访问这些值。
- 对象也可以看做是属性的无序集合,每个属性都是一个名/值对。
- 对象除了可以创建自有属性,还可以通过从一个名为原型的对象那里 继承属性。
- 除了字符串、数字、true、false、null和undefined之外,JS中的值 都是对象。
创建对象
创建对象有两种方式:
-
第一种 var person = new Object(); person.name = “孙悟空”; person.age = 18;
-
第二种 var person = { name:”孙悟空”, age:18 };
对象属性的访问
访问属性的两种方式:
-
.访问 对象.属性名
-
[]访问 对象[‘属性名’]
数据类型
JS中的变量可能包含两种不同数据类型的值:基本 数据类型和引用数据类型。
基本数据类型:
- JS中一共有5种基本数据类型:String、Number、 Boolean、Undefined、Null。
- 基本数据类型的值是无法修改的,是不可变的。
- 基本数据类型的比较是值的比较,也就是只要两个 变量的值相等,我们就认为这两个变量相等。
引用数据类型:
- 引用类型的值是保存在内存中的对象。
- 当一个变量是一个对象时,实际上变量中保存的并不是 对象本身,而是对象的引用。
- 当从一个变量向另一个变量复制引用类型的值时,会将 对象的引用复制到变量中,并不是创建一个新的对象。
- 这时,两个变量指向的是同一个对象。因此,改变其中 一个变量会影响另一个
栈和堆
- JavaScript在运行时数据是保存到栈内存和堆内存当中的。
- 简单来说栈内存用来保存变量和基本类型。堆内存用来保存对 象。
- 我们在声明一个变量时实际上就是在栈内存中创建了一个空间 用来保存变量。
- 如果是基本类型则在栈内存中直接保存,
-
如果是引用类型则会在堆内存中保存,变量中保存的实际上对 象在堆内存中的地址。
var a = 123; var b = true; var c = “hello”; var d = {name:’sunwukong’,age:18};
数组
数组是一种用于表达有顺序关系的值的集 合的语言结构。
创建数组:
-
var array = [1,44,33];
-
数组内的各个值被称作元素。每一个元素 都可以通过索引(下标)来快速读取。索 引是从零开始的整数。
函数
函数也是一个对象,所以函数也是在堆内存中保存的。
-
函数声明比较特殊,需要使用function关键字声明。
`var sum = function(a,b){return a+b};`
-
上边的例子就是创建了一个函数对象,并将函数对 象赋值给了sum这个变量。其中()中的内容表示执 行函数时需要的参数,{}中的内容表示函数的主体。
函数的调用
调用函数时,传递给函数的参数称为实参(实际参数)。
函数的声明
可以通过函数声明语句来定义一个函数。函数声明语句以关键字 function 开始,其后跟有函数名、参数列表和函数体。其语法如下所 示:
-
例如:
function 函数名(参数,参数,参数…){ 函数体 }
传递参数
JS中的所有的参数传递都是按值传递的。也就是说把函数外部的值赋值给函数内部的参数,就和把值从一个变量赋值给另一个变量是一样的。
函数内部属性
在函数内部,有两个特殊的对象:
- arguments
- 该对象实际上是一个数组,用于保存函数的参数。
- 同时该对象还有一个属性callee来表示当前函数。
- this
- this 引用的是一个对象。对于最外层代码与函数内部的情况,其 引用目标是不同的。
- 此外,即使在函数内部,根据函数调用方式的不同,引用对象也会有所不同。需要注意的是,this 引用会根据代码的上下文语境自动改变其引用对象。
this 引用的规则
- 在最外层代码中,this 引用的是全局对象。
- 在函数内,this 根据函数调用方式的不同 而有所不同:
执行环境
- 执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的 行为。
- 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量 和函数都保存在这个对象中。
- 全局执行环境是最外围的一个执行环境。在 Web 浏览器中,全局执 行环境被认为是 window 对象,因此所有全局变量和函数都是作为 window 对象的属性和方法创建的。
- 某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中 的所有变量和函数定义也随之销毁。
- 在内部环境可以读取外部环境的变量,反之则不行。
构造函数
构造函数是用于生成对象的函数,像之前调用的Object()就是一个构 造函数。
-
创建一个构造函数:
function MyClass(x,y) { this.x = x; this.y = y; }
- 调用构造函数:
- 构造函数本身和普通的函数声明形式相同。
- 构造函数通过 new 关键字来调用,new 关键字会新创建一个对象并返回。
- 通过 new关键字调用的构造函数内的 this 引用引用了(被新生成的)对象。
new关键字
-
使用new关键字执行一个构造函数时:
- 首先,会先创建一个空的对象。
- 然后,会执行相应的构造函数。构造函数中的this将会引用这个新对象。
- 最后,将对象作为执行结果返回。
- 构造函数总是由new关键字调用。
- 构造函数和普通函数的区别就在于调用方式的不同。
- 任何函数都可以通过new来调用,所以函数都可以是构造函数。
- 在开发中,通常会区分用于执行的函数和构造函数。
- 构造函数的首字母要大写。
属性的访问
在对象中保存的数据或者说是变量,我们称为是一个对象的属性。
读取对象的属性有两种方式:
- 对象.属性名
- 对象[‘属性名’]
修改属性值也很简单:
- 对象.属性名 = 属性值
删除属性
- delete 对象.属性名
constructor
- 每个对象中都有一个constructor属性,它引用了当前对象的构造函数。
垃圾回收
-
不再使用的对象的内存将会自动回收,这 种功能称作垃圾回收。
-
所谓不再使用的对象,指的是没有被任何 一个属性(变量)引用的对象。
-
垃圾回收的目的是,使开发者不必为对象 的生命周期管理花费太多精力
原型
JS是一门面向对象的语言,而且它还是一个基于原型的面向对 象的语言。
-
所谓的原型实际上指的是,在构造函数中存在着一个名为原型 的(prototype)对象,这个对象中保存着一些属性,凡是通过该 构造函数创建的对象都可以访问存在于原型中的属性。
-
最典型的原型中的属性就是toString()函数,实际上我们的对象 中并没有定义这个函数,但是却可以调用,那是因为这个函数 存在于Object对应的原型中
设置原型
原型就是一个对象,和其他对象没有任何区别,可以通过构造 函数来获取原型对象。
-
构造函数. prototype
-
和其他对象一样我们可以添加修改删除原型中的属性,也可以 修改原型对象的引用。
-
需要注意的是prototype属性只存在于函数对象中,其他对象 是没有prototype属性的。
-
每一个对象都有原型,包括原型对象也有原型。特殊的是 Object的原型对象没有原型。
原型链
基于我们上边所说的,每个对象都有原型对象,原型对象也有原型对象。
-
由此,我们的对象,和对象的原型,以及原型的原型,就构成了一个原型链。这个链的次序是:mc对象、mc对象原型、原型的原型(Object)、Object的原型
-
当从一个对象中获取属性时,会首先从当前对象中查找,如果没有则顺着向 上查找原型对象,直到找到Object对象的原型位置,找到则返回,找不到则 返回undefined。
instanceof
之前学习基本数据类型时我们学习了typeof用来检查一个变量的类型。但是typeof对于对象来说却不是那么好用,因为任何对象使用typeof都会返回Object。而我们想要获取的是对象的具体类型。 这时就需要使用instanceof运算符了,它主要用来检查一个对象的具体类型。
- 语法:var result = 变量 instanceof 类型
引用类型
上边我们说到JS中除了5种基本数据类型以外其余的全都是对象,也就是引用数据类型。 但是虽然全都是对象,但是对象的种类却是非常繁多的。比如我们说过的Array(数组),Function(函数)这些都是不同的类型对象。实际上在JavaScript中还提供了多种不同类型的对象。
Object
目前为止,我们看到的最多的类型就是Object,它也是我们在JS中使用的最多的对象。
-
虽然Object对象中并没有为我们提供太多的功能,但是我们会经常会用途来存储和传 输数据。
-
创建Object对象有两种方式:
var obj = new Object();
var obj = {}
-
上边的两种方式都可以返回一个Object对象。但是第一种我们使用了一个new关键字和一个Object()函数。这个函数就是专门用来创建一个Object对象并返回的,像这种函数我们称为构造函数
Array
Array用于表示一个有序的数组。JS的数组中可以保存任意类型的数据。
-
创建一个数组的方式有两种:
-
使用构造器:
var arr = new Array(数组的长度);
var arr = new Array(123,’hello’,true);
-
使用[]
var arr = [];
var arr = [123,’hello’,false];
-
读取数组中的值使用数组[索引]的方式,注意索引是从0开始的
Date
Date类型用来表示一个时间。直接使用new Date()就可以创建一个Date对象。创造对象时不传参数默认创建当前时间。可以传递一个毫秒数用来创建具体的时间。
Function
Function类型代表一个函数,每一个函数都是一个Function类型的对象。而且都与其他引用类型一样具有属性和方法。
- 由于函数是对象,因此函数名实际上也是一个指向函数对象的 指针,不会与某个函数绑定。
-
函数的声明有两种方式:
function sum(){}
var sum = function(){};
- 由于存在函数声明提升的过程,第一种方式在函数声明之前就 可以调用函数,而第二种不行。
函数也可以作为参数
-
函数也是一个对象,所以函数和其他对象一样也可以作为一个参数传递给另外一个函数。
-
但是要注意的是使用函数作为参数时,变量后边千万不要加(),不加()表示将函数本身作为 参数,加上以后表示将函数执行的结果作为参数。
函数对象的方法
每个函数都有两个方法call()和apply()。
-
call()和apply()都可以指定一个函数的运行环境对象,换句话说就是设置函数执行时的this值。
- 使用方式:
- 函数对象.call(this对象,参数数组)
- 函数对象.apply(this对象,参数1,参数2,参数N)
闭包(closure)
闭包是JS一个非常重要的特性,这意味着当前作用域总是能够访问外部作用域中的变量。因为函数是JS中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。 也可以将闭包的特征理解为,其相关的局 部变量在函数调用结束之后将会继续存在。
基本包装类型
基本数据类型是不能去调用方法的,所以JS中还提供了3个特殊的引 用类型:Boolean Number String
-
这三个类型分别包装了Boolean、Number、String并扩展了许多实 用的方法。
-
他们的使用方式和普通的对象一样。
-
要注意的是使用typeof检查这些包装类型时返回的都是object。
###Boolean
-
Boolean 类型是与布尔值对应的引用类型。
-
可以采用这种方式创建: var booleanObject = new Boolean(true);
-
我们最好永远不要使用Boolean包装类。
###Number
-
Number是数值对应的引用数据类型。
-
创建Number对象只需要在调用构造函数时传递一个数值: var num = new Numbaer(20);
-
使用数值时我们建议使用基本数值,而不建议使用包装类。
###String
-
String 类型是字符串的对象包装类型,
-
可以像下面这样使用 String 构造函数来创建:var str = new String(“hello world”);
-
可以使用length属性来获取字符串的长度
Math
JS 还为保存数学公式和信息提供了一个公共位置,即 Math 对象。 与我们在 JavaScript 直接编写的计算功能相比, Math 对象提供的计算功能执行起来要快得多。 Math 对象中还提供了辅助完成这些计算的属性和方法。
###Math的方法
- 最大最小值 -Math.max()获取最大值
- Math.min()获取最小值
- 舍入:
- 向上舍 Math.ceil()
- 向下舍 Math.floor()
- 四舍五入 Math.round()
- 随机数: Math.random()
- 选取某个范围内的随机值:
- 值 = Math.floor(Math.random() * 可能值的总数 + 第一个可能的值)