面向对象编程 —— Object Oriented Programming,简称 OOP
面向对象的特征
封装性
继承性
多态性
创建对象的四种方式
字面量
new Object()
工厂模式
构造函数
(1)、解析构造函数代码的执行
创建一个实例对象,必须使用 new 操作符。以这种方式调用构造函数会经历以下 4 个步骤:
1、创建一个新对象
2、将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
3、执行构造函数中的代码
4、返回新对象
(2)、constructor属性
对象的 constructor 属性最初是用来标识对象类型的
可以通过实例的 constructor 属性判断实例和构造函数之间的关系
构造函数实例化对象的constructor属性指向的是构造函数本身
要检测对象的类型,使用 constructor操作符更可靠一些,返回true为对象
例如:obj.constructor == Object
(3)、instanceof关键字
如果要检测对象的类型,还是使用 instanceof 操作符更可靠一些,返回true为对象
obj instanceof Object
总结:
构造函数是根据具体的事物抽象出来的抽象模板
实例对象是根据抽象的构造函数模板得到的具体实例对象
每一个实例对象都具有一个 constructor 属性,指向创建该实例的构造函数
演示示例:实例对象与构造函数之间的关系
原型
(1)、原型
prototype
Javascript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。
这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在 prototype 对象上。
构造函数、实例、原型三者之间的关系
任何函数都具有一个 prototype 属性,该属性是一个对象。
构造函数的 prototype 对象默认都有一个 constructor 属性,指向 prototype 对象所在函数。
通过构造函数得到的实例对象内部会包含一个指向构造函数的 prototype 对象的指针 __proto__。
总结:
1、任何函数都具有一个 prototype 属性,该属性是一个对象
2、构造函数有一个protoType属性,它本身是一个对象,我们称之为原型
3、构造函数的protoType原型对象的属性和方法,都可以被构造函数实例化的对象所继承
4、构造函数的protoType原型对象有个constructor属性,指向的是当前原型对象所在的构造函数
5、实例对象有__proto__属性,它是一个指针,指向的是构造函数的的原型prototype
6、实例对象都具有一个 constructor 属性,指向创建该实例的构造函数
额外的一些技巧
利用自调用函数把局部变量变为全局变量。
改变this指向的方法
(1)、call方法
1、call()方法可以进行普通函数的调用
2、call()方法可以改变this的指向,如果没有参数,this指向window
3、call()方法可以改变this的指向,如果有一个参数,this指向该参数
4、call()方法可以改变this的指向,如果有多个参数,this指向第一个参数,剩下的是个参数列表(构造函数继承的案例)
(2)、apply方法
1、 apply()方法可以进行普通函数的调用
2、apply()方法可以改变this的指向,如果没有参数,this指向window
3、apply()方法可以改变this的指向,如果有一个参数,this指向该参数
4、apply()方法可以改变this的指向,如果有多个参数,第一个参数是null或者window,第二个参数是数组
(3)、bind方法
推荐使用第二种形式,第三种用的相对较少,但也是必须掌握的内容。
bind() 函数会创建一个新函数(称为绑定函数),新函数与被调函数(绑定函数的目标函数)具有相同的函数体(在 ECMAScript 5 规范中内置的call属性)。当目标函数被调用时 this 值绑定到 bind() 的第一个参数,该参数不能被重写。绑定函数被调用时,bind() 也接受预设的参数提供给原函数。一个绑定函数也能使用new操作符创建对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。
bind()不能进行函数的调用
可以改变this指向