1.创建方式
使用function(如F)创建object类型的对象(如obj),只需要在function对象(F)前面加new关键字就可以。
function F(){
this.v=1
}
var obj=new F() //创建F类型对象
console.log(obj.v) //1
也就是说
对于一个function类型的对象,若调用时前无new,则为调用方法处理业务,若前有new关键字,那就是来创建对象
2.创建过程
1.创建function对应的空object类型对象
2.将function的函数体作为新创建的object类型对象的方法来执行
特别注意,创建过程的第二部,在使用function对象新建object对象时依然会执行function的函数体
var a=1
function num(){
a=2
}
console.log(a) //1
var num1=new num()
console.log(a) //2
有一种特殊情况,当function的函数体返回一个对象雷星时,使用new关键字创建的对象就是返回的对象而不是function所对应的对象
function F()
function Car(color,disolacement){
this.color=color
this.displacement-displacement
return new F()
}
var car=new Car("black","2.4T")
console.log(car.color+","+car.dispalcement) //undefined,undefined
console.log(car instanceof Car) //false
console.log(car instanceof F) //true
例子中存在两个function对象:F和Car。在Car的函数体中返回了新建的F类型实例对象,此时Car新建出的car对象就成了F类型的实例对象,而不是Car类型的实例对象。
3.prototype属性
1.继承方法
prototype是ES中function类型对象的一个特殊属性。每个function的类型对象
都有prototype属性,prototype属性的值是object类型对象。
function对象中prototype属性对象作用:在function对象创建出的object类型实例中可以直接调用function对象的prototype属性对象中的属性(包括方法属性)。
function Car(color,displacement){
this.color=color
this.displacement=displacement
}
Car.propotype.logMessage=function(){
console.log(this.color+','+this.displacement)
}
var car=new Car("black","3.0T")
car.logMessage() //black,3.0T
给Car的protype属性添加了logMessage方法,这样使用Car创建的car对象就可以直接调用logMessage方法。虽然这里可以使用car调用logMessage方法,但car对象本身不会添加这个方法,仅可以调用。
function创建的实例对象在调用属性时会首先在自己的属性中查找,若找不到则去function的prototype的属性对象中查找。但创建的对象仅可调用prototype中的属性,但不实际拥有那些属性,也不可对他们进行修改(修改操作会在实例对象中添加一个同名属性)。当创建的实例对象定义了同名的属性后则覆盖prototype中的属性,但原来prototype中的数学并不会发生变化,且当创建出来的对象删除了添加的属性后,原来prototype中的属性还可以继续调用
function Car(color,displacement){
this.color=color
this.displacement=displacement
}
Car.prototype.logMessage=function(){
console.log(this.color+","+this.displacement)
}
var car=new Car("black","3.0T")
car.logMessage() //black,3.0T
car.logMessage=function(){
console.log(this.color)
}
car.logMessage() //black
delete car.logMessage
car.logMessage() //black,3.0T
使用Car直接创建的car对象并没有logMessage方法,因此第一次调用logMessage方法时会调用Car的prototype属性对象中的logMessage方法,之后,给car定义了logMessage方法了,最后又删除了car的logMessage方法,此时调用logMessage方法就会再次调用Car的prototype属性对象中的logMessage方法,且Car的prototype属性对象中的logMessage方法的内容也内发生变化。
2.多层继承
function的prototype属性是object类型的属性对象,其本身也可能使用function创建的对象,通过此方法可实现多层继承
function log(msg){
console.log(msg)
}
function Person(){
Person.prototype.logPerson=function(){
log("teacher")
}
}
Teacher.prototype=new Person()
Teacher.prototype.logPrototype=function(){
log("prototype")
}
var techer=new Teacher()
teacher.logTeacher() //teacher
tcacher.logPrototype() //prototype
teacher.logPerson() //person
因为Teacher的prototype属性是Person创建的实例对象,而使用Teacher创建出来的teacher对象可以调用Teacher的prototype属性对象的属性,因此teacher对象可调用Person创建的实例对象的属性。又因Person创建的实例对象可以调用Person的prototype属性对象中的属性,因此teacher对象也可调用Person的prototype属性对象中的属性方法logPerson。另外,因为此程序给Teacher的prototype属性对象添加了logPrototype方法,所以teacher也可调用logPrototype方法
Teacher创建出来的teacher对象在调用属性时会首先在自己的属性中查找,如果找不到就到Teacher的prototype属性对象中查找,若还找不到就会到Person的prototype属性中查找,而Teacher的prototype又由两部分组成,一部分是用Person创建的person对象,另一部分是直接定义的logPrototype方法。