1.this对象是在运行时基于函数的执行环境绑定的:
(即函数可能在全局里运行,那么this指向全局对象,也可能在某个对象里运行,那么this指向那个对象。this的值是可以动态的改变的)。构造函数创建不同的实例的时候,this指向不同的新对象。当使用new关键字声明,this指向新建对象。
2.call,apply是函数的方法(非继承而来):function.call(thisobj,args 对象或array实例),apply里面是agrs数组。用call/apply可以动态的改变this 值。即call和apply
扩展:每个函数都包含两个属性 length(命名参数个数)和prototype
3.将Person.prototype设置为等于一个以对象字面量形式创建的新对象。相当于重写了prototype对象。因为创建一个函数时,会同时创建一个prototype对象,这个对象会自动获得一个constructor属性。所以重写prototype对象时,constructor属性会指向Object构造函数,而不会指向Person构造函数了。可以手动创建constructor属性。constructor:Person
4.
function Animal(){
var aaa="ggg" //(1)
this.aaa="zheng";(2)
this.bb="si"
this.jjj=function(){
return aaa;
}
}
Animal.prototype.aaa="haha"
var cat=new Animal()
console.log(cat.jjj()) //"ggg" 不会查找this里面的
重点:首先要改为return this.aaa,如果删掉(1), 结果为“zheng”,删掉(2)结果为“haha”
console.log(cat.aaa) //"zheng"
function Animal(){
this.bb="si"
}
var cat=new Animal() //<3>
Animal.prototype={
constructor:Animal,
aaa:"haha",
jjj:function(){
return this.aaa;
}
//<4>
}
console.log(cat.jjj()) 结果:“haha”
重写原型对象的问题:如果将<3>写在<4>处,那么就报错,因为重写了后,切断了现有原型与实例的联系,引用的仍是之前的原型。
function Animal(){
this.aaa="ff" <5>
var aaa="nn"
this.bb="si"
}
var cat=new Animal()
Animal.prototype.aaa="haha";
Animal.prototype.jjj=function(){
return aaa;
}
console.log(cat.jjj()) //error报错了
原型对象里面的方法找不到 var的 aaa 因为不在一个作用域里面。要变成return this.aaa; 则访问到"ff",如果去掉<5>,则访问到“haha”。可以想象成带this的属性和方法存储了一份在新实例里面,找不到才去prototype里面找。
5.组合使用构造函数模式和原型模式
1)构造函数模式用于定义实例属性 ==》每个新实例都会有自己的一份实例属性的副本。(通过this去copy)
2)原型模式