函数对象

js里函数即对象,凡是使用 function 关键字或 Function 构造函数创建的对象都是函数对象。只有函数对象才拥有 prototype 属性

构造函数

构造函数由 new 关键字创造,用来初始化新创建的对象的函数是构造函数。

function Animal(name,color,age){
    this.name = name;
    this.color = color;
    this.age = age
}
var cat = new Animal("阿斑","灰白色","1岁");   
//只有当一个函数以 new 关键词来调用的时候,我们才能说是一个构造函数
1
2
3
4
5
6
7

在使用对象字面量创建一系列同一类型的对象时,这些对象可能具有一些相似的特征(属性)和行为(方法),此时会产生很多重复的代码,而使用构造函数就可以实现代码的复用

new 操作符

1)当以 new 关键字调用时,会创建一个新的内存空间,标记为Animal的实例

2)函数体内部的 this 指向该内存,每创建一个实例的时候,就会创建一个新的内存空间

var cat = new Animal("阿斑","灰白色","1岁");   //创建新内存 f1
var cat2 = new Animal("阿鲁","灰白色","1岁");   //创建新内存 f2
1
2

3)执行函数体内的代码(给this加属性,就相当于给实例添加属性)

4)默认返回this

  • new Object() 底层运行的步骤:
    • 创建一个空对象{};
    • 将空对象的 proto 原型对象 指向 Object.prototype;
    • 将 Object 构造函数的 this 指向当前空对象

prototype

每一个函数都有一个 prototype 属性。prototype 属性指定了使用该构造函数生成的对象实例继承了哪个对象实例。

constructor 属性

每一个原型对象都有一个 constructor 属性

__proto__

每一个实例都有一个 __proto__ 指针,指向构造函数的原型对象。

原型继承

利用原型中的成员可以被和其相关的对象共享这一特性,可以实现继承,这种实现继承的方式,就叫做原型继承

  • 实现方式就是:
    • 定义新的构造函数,并在内部用call()调用希望“继承”的构造函数,并绑定this;
    • 借助中间函数F实现原型链继承,最好通过封装的inherits函数完成;
    • 继续在新的构造函数的原型上定义新方法。

原型链

prototype 指定了使用该构造函数生成的对象实例继承了哪个对象实例。所以修改 prototype 属性使其指向其它对象实例,就可以达到实现继承任意对象的效果了

通过 __proto__ 属性,集成的对象实例 被 被继承的对象的实例 链接起来,形成了一条由对象实例,指向 被继承对象实例的引用所构成的链条,即原型链

递归访问 __proto__ 必须最终到头,并且值是null