使用工厂化函数创建对象,使用的构造函数都是Obeject(),所以创建的对象都是object这个类型,就导致我们无法区分多种不同类型的对象。
function creatPerson(){
var obj=new Object();
obj.name="孙悟空";
obj.age=18;
obj.sayName=function(){
console.log(obj.name);
}
return obj
}
function creatDog(){
var obj=new Object();
obj.name="小狗";
obj.age=19;
obj.sayName=function(){
console.log(obj.name)
}
return obj
}
var person=creatPerson();
var Dog=creatPerson();
console.log(person);//Object
console.log(Dog);//Object
//因为两个都是Object对象,所以无法区分出哪一个是人对象,哪一个是狗对象
以上我们在创建一个一个小狗对象,创建一个人的对象都用的是:
var obj=new Object();
这样是区分不出来哪个是小狗类型,哪个是人类型的。但是我们希望的是创建人的时候
var person=new person();
构建狗的时候,
var dog=new dog() 用不同的构造函数创建就可以区分出来哪个是哪个对象了。那么怎么创建一个person类型对象,一个dog类型对象呢?
//构造函数是一个普通的函数,创建方式和普通的函数创建的方式是一样的
//不同的是构造函数的函数名习惯上首字母大写
function Person(){
}
//构造函数和普通函数的区别就是调用的方式不同,普通函数就是直接调用,构造函数是用new来调用
var obj=Person();//普通函数的调用方式
console.log(obj)//结果undefined,因为Person()的函数体里面没有return返回值。所以为underfind
var people=new Person();//构造函数的调用方式,用new关键字
console.log(people)//结果Person{}
函数前面加new的是构造函数,不加new的是普通函数,只是调用的当时不同。
上面的代码的Person()函数体里面的没有返回值,但是var people=new Person();再在控制台输出people时却是一个person{}对象呢?
现在我们来看一下构造函数的流程
1.当调用一个构造函数时,立即创建了一个新的对象,当一调用构造函数(当一用new关键字,就立马在内存里开辟出一个新的空间,创建一歌新的对象)
- 将新的对象作为返回值返回
//创建一个构造函数
function Dog(){
alert("汪汪汪")
}
var dog=new Dog();//用new关键字调用。所以立马在函数体内创建了一个新的对象,并且将这个对象返回
console.log(dog)//Dog{}
当我们在调用的时候发现alert()也被执行了,所以
3、数体内的代码是逐行执行的
2、用的函数所新建的对象设置为函数中的this,在构造函数中,可以使用this来引用新建的对象。
//创建一个构造函数
function Dog(){
//this是谁,this是调用Dog时创建的一个新的对象和dog这个对象的指向是一样的,死用一个对象
console.log(this);//Dog{}
}
var dog=new Dog();//用new关键字调用。所以立马在函数体内创建了一个新的对象,并且将这个对象返回
console.log(dog)//Dog{}
当函数以构造函数出现时,this就是这个新创建的函数对象。
现在我们往person函数里面添加属性和方法
function Person(){
this.name="孙悟空";
this.age=18;
this.sayName=function(){
alert(this.name);
}
//this作为放回值给people
}
var people1;
people1.sayName();
var people2=new Person();
people2.sayName();
var people3=new Person();
people3.sayName();
以上代码每调用一次就会创建一个新的对象,所以以上有三个对象,分别是people1,people2,people3。这是三个人的名字都是孙悟空,都只会弹出自己的名字。 因为Person()函数体里面的属性值写死了,那么怎么修改成为动态的呢?显然,我们可以通过形参来达到这个需求。
//我们将一个构造函数称为类,这里叫Person类
function Person(name,age){
this.name=name;
this.age=age;
this.sayName=function(){
alert(this.name);
}
//this作为放回值给people
}
//使用同一个构造函数创建的对象,我们称为一类对象(这里的people1、people2、people3都是Person类对象)
var people1=new Person("孙悟空",18);
people1.sayName();
var people2=new Person("猪八戒",19);
people2.sayName();
var people3=new Person("沙和尚",20);
people3.sayName();
使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为类
var people=new Person("孙悟空",18);
people是Person构造函数(Person类)的实例
var dog=new Dog();
dog是Dog()构造函数(Dog类)的实例
总结:使用同一个构造函数创建的对象,我们称为这一类对象,也将一个构造函数称为类,我们将通过一个额构造函数创建的对象,称为该类的实例(或该构造函数的实例)
instanceof
instanceof判断一个对象是否是一个类的实例 如果是返回true 否则返回false
语法:
对象 instanceof 类
console.log(people instanceof Person);//true
console.log(dog instanceof Person);//false
console.log(people instanceof Object);//true
q:为什么people instanceof Object返回的是true呢?
a:因为Object相当于阿当和夏娃,是所有人的老祖宗,所有的对象都是Object的后代,所以任何对象instanceof Object时都会返回true
最后总结一下this的指向情况
- 当以函数形式调用时,this是window
- 当以方法的形式调用时,调用这个方法的对象是谁,this就是谁
- 当以构造函数的形式调用时,this就是新创建的那个对象