学习时间 | 完成时间 ✅ | 重难点 | 疑问/遗漏 |
---|---|---|---|
复习时间 | |||
计算器插件
;(function(){
var Compute=function(){}
Compute.prototype={
plus: function(a,b){
return a+b;
},
munus:function(a,b){
return a-b;
},
mul:function(a,b){
return a*b;
},
div:function(a,b){
return a/b;
}
}
window.Compute=Compute;
})();
var compute=new Compute();
compute.munus(1,2)
通过改变this的指向,公用属性(这种方式无法继承Teacher的原型)
Teacher.prototype.wife='Ms.Liu';
function Teacher(name,mSkill){
this.name=name;
this.mSkill=mSkill;
}
function Student(name,mSkill,age,major){
Teacher.apply(this,[name,mSkill]);
this.age=age;
this.major=major;
}
var student=new Student('Mr.Zhang','JS/JQ',18,'Computer')
console.log(student.wife) //undefined
公共原型
function Teacher(){
this.name='Mr.Cao';
this.tSkill='JAVA';
}
Teacher.prototype={
pSkill:'JS/JQ'
}
var t=new Teacher();
console.log(t)
function Student(){
this.name='Mr.zhang'
}
Student.prototype=Teacher.prototype;
Student.prototype.age=18;
var s=new Student();//将Teacher的prototype赋值给Student的原型,此时改变Student的原型,
Teacher的原型也跟着改变了
继承
圣杯模式
实现继承又不改变父元素的原型的实现方式
圣杯模式
function Teacher(){
this.name='Mr.Li';
this.tSkill='JAVA';
}
Teacher.prototype={
pSkill:'JS/JQ'
}
var t=new Teacher();
function Student(){
this.name='Mr.Wang';
}
function Buffer(){}
Buffer.prototype=Teacher.prototype;
var buffer=new Buffer();
Student.prototype=buffer;
Student.prototype.age=18;
var s=new Student();
console.log(s) //此时给Student添加原型属性,将不会改变Teacher的原型
封装的写法
方式一
function inherit(Target,Origin){
function Buffer(){}
Buffer.prototype=Origin.prototype;
Buffer.prototype=new Buffer();
Target.prototype.constructor=Target;
Target.prototype.super_class=Origin;
}
方式二(模块化开发)
var inherit=(function(){
var Buffer=function(){};
return function(Target,Origin){
Buffer.prototype=Origin.prototype;
Buffer.prototype=new Buffer();
Target.prototype.constructor=Target;
Target.prototype.super_class=Origin;
}
})();
function Teacher(){}
function Student(){}
inherit(Student,Teacher);
var s=new Student();
var t=new Teacher();
当使用构造函数的时候,每次实例化的时候,构造函数都会return this
如果显示的写return {},则会返回return {},如果是基本数据类型则会不生效,依旧返回this
MDN上的对象原型
原型链的定义
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
原型的定义
在javascript中,函数可以有属性。每个函数都有一个特殊的属性叫做原型(prototype)
constructor是原型上的一个属性,该属性指向用于构造此实例对象的构造函数
function doSomething(){}
console.log( doSomething.prototype );
//如何声明函数并不重要
var doSomething = function(){};
console.log( doSomething.prototype );
⚠️
function Foo(){
this.a=1;
}
var foo=new Foo();
Foo.prototype={
aa:10
}
console.log(foo.aa);//undefined 要在实例化之前改变数据,才可以访问到
原型链的继承方式
1、原型链继承; 引来 引用值共享问题
2、构造函数继承; 没办法拿到父级原型链上的方法
3、组合继承; (伪经典继承)
4、寄生组合继承; (经典继承)
5、圣杯模式
6、extends 继承
function Super(){
this.a='111';
this.b=[1,2,3,4,5]
}
Super.prototype=function(){
console.log(222)
}
function Sub(){
}
Sub.prototype=new Super();
var sub1=new Sub();
var sub2=new Sub();
sub1.a='222';
sub1.b.push(6)
console.log('sub1',sub1)
console.log('sub2',sub2)
引发的问题:引用值共享问题
措施:使用构造函数的方式
但是构造函数类型的继承,没有办法拿到原型上的方法
我们需要使用组合继承的方式(伪经典继承)=>
寄生组合继承 缺点:Sub.prototype=Object.create(Super.prototype);自组建的原型有可能被覆盖=>
解决方案 圣杯模式
function Sub(){
Super.call(this)
}
// Sub.prototype=new Super();
var sub1=new Sub();
var sub2=new Sub();
sub1.a='222';
sub1.b.push(6)
console.log('sub11',sub1)
console.log('sub22',sub2)
组合继承,就可以拿到原型上的方法
function Sub(){
Super.call(this)
}
Sub.prototype=new Super();
寄生组合继承
function Sub(){
Super.call(this)
}
Sub.prototype=Object.create(Super.prototype);