我们都知道在JavaScript中一切皆对象,那么问题来了,对象是什么呢??
答:对象是某个特定引用类型的实例。
那么新对象如何建立呢??
答:新对象是使用new操作符后跟一个构造函数来创建的。
构造函数本身就是一个函数,只不过该函数是处于创建新对象的目的而定义的。
那我们就来创建一个Object的实例看看吧~~
1 var person = new Object();
这行代码创建了一个Object新实例并保存在变量person中,使用的构造函数就是Object。
那我们如何自定义一个构造函数呢?
1 function Animal(){ 2 this.self = function(){ 3 console.log("我是一只可爱的动物啦"); 4 } 5 }
有没有发现构造函数Animal是首字母大写的呢?Object首字母也是大写哦。这可不是什么巧合哦,构造函数始终都应该以一个大写字母开头。
我们知道ECMAScript中的构造函数可用来创建特定类型的对象。使用构造函数创建的对象是构造函数的一个实例。
var dog = new Animal();
此时dog就是Animal的一个新实例。
这是我们就要想一想了在使用new操作符调用构造函数创建一个新实例的过程中发生了什么呢?一个新实例是怎么生成的呢?
答: 经历以下四个步骤
- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此this就指向了这个新对象)
- 执行构造函数中的代码(为这个新对象添加属性)
- 返回新对象
我们了解了这个过程就能解释函数作为构造函数调用和普通函数调用的区别了吧?
答:当我们把函数作为普通函数调用的时候,属性和方法就被添加到window,this指向全局对象。而作为构造函数调用从上面第二步可以看出,this指向新对象。我们来看一下吧
作为普通函数调用:
1 var name = "dog"; 2 function Animal(name){ 3 this.name = name; 4 this.self = function(){ 5 console.log("我是" + this.name); 6 } 7 } 8 Animal("mouse"); 9 console.log(name);
从结果可以看出,全局变量name被修改了,符合我们的判断。
作为构造函数调用:
1 var name = "dog"; 2 function Animal(name){ 3 this.name = name; 4 this.self = function(){ 5 console.log("我是" + this.name); 6 } 7 } 8 var cat = new Animal("cat"); 9 console.log(cat.name); 10 console.log(name);
this指向新对象cat,全局变量name也没有变化,也符合我们的判断。
而我们创建新实例的用处不只是这样,我们是想要实现共享与继承的,这个时候就要提到一个属性了,也许你已经知道了,就是prototype!
构造函数调用创建一个新的空对象,这个对象继承自构造函数的prototype属性。
1 function Animal(){ 2 } 3 Animal.prototype.self = function(){ 4 console.log("我是一只可爱的动物啦"); 5 } 6 var dog = new Animal(); 7 console.log(dog.self());
关于prototype的内容就不在这里继续展开了,在另外一篇博客JavaScript原型学习笔记里面我会详细在说的啦。