1.原型对象与构造函数
无论什么时候,创建了一个函数后。
1.函数拥有propertype属性。值为这个函数的原型对象的指针。
2.同时对于原型对象,其拥有constructor就指向原来的函数(什么值类型的)
3.原型对象开始只获得constructor属性(默认的)。
4.用构造函数构造对象,实例也会有prototype: 指向原型对象
function Person() {
}
//这里做了两件事。PS中指向了一个原型对象prototype.而原型对象也GET到了constructor属性和其他一堆属性。
Person.prototype.name = '原型名'
Person.prototype.age = '原型年纪'
Person.prototype.job = '原型小白鼠'
Person.prototype.sayname = function () {
alert(this.name)
}
console.log(Person.prototype.isPrototypeOf(person1)) //返回true
var person1 = new Person();
//这里新建了一个person1对象,并且构造函数作用域指向新对象,执行构造函数的代码,返回新对象。
1.1为了简洁而重写原型对象
function Person() {
}
//原型对象用字面量形式创建,实际上constructor就变成了Object.
Person.prototype ={
name : '原型名',
age : '原型年纪',
job : '原型小白鼠',
sayname : function(){
alert(this.name);
}
}
var person1 = new Person();
重写之后要注意,在重写之前新建的实例还是指向原来的原型对象的。
1.2原型对象的弊端
- 没有传参数,创建出来的所有实例属性都是共享的。
- 当原型对象中属性不是基本值,而是引用值得时候。我们在实例中访问该属性,然后指向了该引用,如果是赋值还好,会直接覆盖。如果是对该引用指向的对象做操作,那么就会引起原型被更改,造成所有势力属性的变化。
1.3构造与原型并用
- 构造函数太复杂,复用性太差。
- 原型复用性高,但所有属性全共享了。
为了解决以上的问题,我们两种方法混用。
构造函数中 写入一些比较个性化的属性。而在原型对象中保存一些共享的属性和方法。
还有几种构造函数模式未总结
2. 继承:原型链
基本思想是利用原型让一个引用类型继承另外一个引用类型的属性和方法。
2.1原型链细节
例子:
- 建立一个超集函数(超集的原型),一个子集函数,并且子集函数的实例(新对象)是通过new超集函数构建起来的(意味着新对象的原型是超集的原型)。
function 超集函数(){
this.property = true;
this.age = '1';
}
超集函数.prototype.getSuperValue = function(){
return this.property;
};
超集函数.prototype.name = '我是超级原型函数对象'
function 子集函数(){
this.subproperty = false;
}
//inherit from 超集函数
子集函数.prototype = new 超集函数();
子集函数.prototype.name = '我是子集原型'
子集函数.prototype.getSubValue = function (){
return this.subproperty;
};
console.log(子集函数.prototype)
console.log((超集函数.prototype))
console.log(超集函数.prototype.isPrototypeOf(子集函数.prototype)) //true.
3.练习题
function foo(){
foo.abc = function (){console.log('456')}
this.def = this.abc;
this.abc = function(){console.log('def')}
abc = function(){console.log('@@@@@')}
var abc = function () {console.log('$$$$$')}
}
foo.abc = function () {
console.log('123')
}
foo.prototype = {
abc : function (){console.log('abc')}
}
foo.abc();// 123
var f = new foo();
f.def();//abc
f.abc();//def
foo.abc()//456