call()和原型继承的方法

1.call()

call()方法接受两个参数,obj和arg 

比如functionA.call(obj,arg)   就是说现在运行(执行)functionA这个方法,但是functionA里面的方法不是为它以前的对象而运行了,把functionA的this强行改变成了obj

obj成为functionA中的this,然后来运行functionA这个方法,而arg是传给functionA的参数

function Student(props) {
    this.name = props.name || 'Unnamed';
}

Student.prototype.hello = function () {
    alert('Hello, ' + this.name + '!');
}
function PrimaryStudent(props) {
    Student.call(this, props);
    this.grade = props.grade || 1;
}

比如上面的代码,先定义了Student方法,然后定义了PrimaryStudent方法
PrimaryStudent中, Student.call(this, props);指的是把this——也就是PrimaryStudent对象作为Student运行时的那个this,把props传给Student作为参数,来运行Student这个方法,运行出来的结果是什么呢
PrimaryStudent.name=props.name //这个props是传进来那个props  
然后PrimaryStudent.prototype.hello = function () { alert('Hello, ' + this.name + '!'); } 它还获得了一个写在原型里的方法
PrimaryStudent这个函数运行下来的结果相当于
function PrimaryStudent(props){
this.name = props.name || 'Unnamed';
this.prototype.hello = function () {
    alert('Hello, ' + this.name + '!');
}
}
这就是call方法
它会运行一个函数,然后告诉这个函数你现在得用我给你的对象来运行你的那套方法,返回出什么东西是什么东西


2.原型继承


而原型继承呢
一般我们会先定义一个方法 比如刚才的Student
Student方法里有属性,有定义在原型里的方法
然后我们想继承Student,我们定义出一个新的函数 littleStudent
在这个新的函数内部我们 Student.call(this,arg) 在这里this指的是littleStudent,按上面定义的Student函数(内部拿this写属性和方法),我们会获得一个littleStudent它内部有Student的那些属性和方法
等于Student在我们littleStudent内部执行了一遍,并且是为我们造属性和方法的,我们littleStudent现在也有这些方法了
但这样是继承吗?Student日后有改变,我们的littleStudent会有改变吗,不会
因为我们只是拿call让Student给我们也造了一套属性的方法,我们littleStudent的原型仍然指向littleStudent.protptype
当前的原型链是职业的 new littleStudent() ----> littleStudent.prototype ----> Object.prototype ----> null 跟Student没有关系
需要变成这样 new littleStudent() ----> littleStudent.prototype ----> Student.prototype ----> Object.prototype ----> null

那么怎么继承呢

先创建一个空函数F(){ }
把这个空函数的原型指向Student的原型:F.prototype = Student.prototype;
然后把littleStudent的原型指向F的实例:littleStudent.prototype=new F();; 则littleStudent的原型里包含了student原型里的所有内容
然后把littleStudent原型的构造函数修复为littleStudentlittleStudent.prototype.constructor = littleStudent; 因为之前littleStudent.prototype=new F() 则new F().constructor指向的是构造函数F
然后我们就可以继续在littleStudent对象的原型上添加方法和属性了
littleStudent.prototype.getGrade = function () {
    return this.grade;
};
而这并不会影响Student的原型,因为我们在这儿添加方法相当于是在new F()上添加方法
至此我们又给littleStudent继承了Student的原型,又可以随意给它扩展,这就完成了一次继承









 
posted @ 2016-01-19 17:53  刺蛇笑眯眯  阅读(656)  评论(0编辑  收藏  举报