当我们重复操作一些属性方法时,就可以想到将属性方法进行一定得封装方便使用,这个时候我们就面临两种选择
- 普通函数
- 构造函数
简单的区分一下普通函数和构造函数:
当我们直接调用一个方法的时候,他就叫普通函数,此时用全局对象的window作为上下文,
用new操作符调用的时候他叫构造函数,此时用新生对象作为上下文,
普通函数比较理解,今天重点理解一下构造函数。
什么时候使用构造函数?
当对象有很多实例,可以被标志为特定的类型,可以通过继承扩展代码时,我们就快可以使用构造函数。
创建对象的几种方式
- 使用new关键字创建
1 | var cq=new Object(); |
- 使用字面量创建
就是平常建立普通对象的一种方式
1 | var cq={ |
- 工厂模式
当我们需要写多个相似的对象时,就可以用工厂函数(专门造对象的一个函数)来进行创建
1 | function createCQ(name,bar){ |
- 构造函数
本质上是一个工厂函数,像这种用new来生成一个对象我们称它为构造器(constructor),
每个实例都有一个constructor属性,默认调用prototype对象的constructor属性,object.constructor可以查看对象的构造函数,
1 | console.log(cq1.constructor==CreateCQ.prototype.constructor);//true |
一般情况下构造函数的第一个字母需要大小,来和普通函数作为区分
生成对象的过程叫做实例化
1 | function CQ(name,bar){ |
- .create()方法创建对象
1 | var a=Object.create(null); |
__proto__和prototype的区别
__prototype__(隐式原型)与prototype(显式原型)
显式原型的作用:用来实现基于原型的继承与属性的共享。
隐式原型的作用:构成原型链,同样用于实现基于原型的继承。举个例子,当我们访问obj这个对象中的x属性时,如果在obj中找不到,那么就会沿着
__proto__依次查找。
几乎任何一个对象都有prototype属性,这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的方法和属性(我们把这个对象叫做原型对象)
这意味着我们可以把那些不变的属性和方法,直接定义在prototype上,
例如构造函数Foo(),这个构造函数的属性Foo.prototype指向了原型对象,它保存着实例共享的方法
通过原型的方式来指定一个方法,如果中途改变了这个方法,所有引用它的方法都会跟着做出相应的变化:
1 | function User(name,age){//原型对象 |
总结
可理解为__proto__ = constructor.prototype
__proto__是一些浏览器提供的一个查看prototype的接口,也就是说prototype才是标准的原型、可用在代码中,而__proto__用于调试。在chrome调试中,函数的原型可以用prototype查看,而
__proto__可以看所有对象的原型。
1.每个对象有属性__proto__,指向该对象的构造函数的原型对象。
2.只有函数方法才有属性prototype,prototype指向该方法的原型对象。
对象在调用一个方法时会首先在自身里寻找是否有该方法,若没有,则通过内部的__proto__属性去自己的构造函数原型上去寻找,依次层层递进,直到Object.prototype.__proto__=null为止,这样往上追溯的整个过程,即原型链。
继承
- 显性属性用call/apply改变作用于的方法更换作用域范围
- 隐性属性通过重写prototype对象的方式进行继承
1 | function Animal(color,age){ |