对象的继承和方法
继承
对象之间的继承
var wjl = {
name:'王健',
money:100000,
car:['宝马','玛莎拉蒂'],
play:function(){
console.log('abc');
}
}
var wsc = {
name:'王思';
}
继承函数
function extend(parent,child){
for(var key in parent)//遍历parent的所有属性
if(child[key])//如果child中有这个属性名就跳过这次循环,直接下一次循环{
continue;//continue是跳过此次循环,直接执行下一次循环.
}
child[key]=parent[key]//把parent对象中的属性都遍历给child对象
}
}
extend('wjl','wsc');
原型之间的继承
继承的目的 是把子类型中共同的成员提取到父类型中,代码重用
(定时器中的this指向的是window对象),可以通过创建一个变量的方式来访问自调用函数内的对象。例如。设置that=this;

组合继承
借用构造函数+原型继承
window.onload=function(){
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}//父对象
Person.prototype.sayhi=function(){
console.log(123);
}
function Student(name,age,sex,score){
Person.call(this,name,age,sex);
this.score=score;
}//子对象
Student.prototype=new Person;//还有种写法是 Student.prototype=Person.prototype; 但是这种写法有个问题
Student.prototype在内存中不是独立的空间,而且指向了person的原型空间,这样的话 student添加自己的方法,就等于person添加方法
Student.prototype.constructor=Student;
var s1=new Student('lilei',18,'man',90);
console.dir(s1);//继承了父对象的属性和原型方法
}
例子的原型图

寄生继承
function Parent (name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
function object(o) {
function F() {}
F.prototype = o;
return new F();
// 通过构造一个介于 Parent 与 Child 之间的对象,并使该对象的 prototype 属性指向 Parent 的 prototype对象,
// 来避开通过调用 Parent 构造函数的方式来产生一个 prototype 指向Parent prototype对象的对象。
}
function prototype(child, parent) {
// 不直接child.prototype=parent.prototype呢?
// 原因 : 当我们想给 Child 的prototype里面添加共享属性或者方法时,如果其 prototype 指向的是 Parent 的 prototype,那么在 Child 的 prototype 里添加的属性和方法也会反映在 Parent 的 prototype 里面,
// 这明显是不合理的,这样做的后果是当我们只想使用 Parent 时,也能看见 Child 往里面扔的方法和属性。
// 所以需要每个构造函数都需要持有自己专用的prototype对象
var prototype = object(parent.prototype);
prototype.constructor = child;
child.prototype = prototype;
}
prototype(Child, Parent);
var child1 = new Child('kevin', '18');
console.log(child1);
bind()方法
bind方法 ES5中新增 IE9才支持,新建一个方法,bind中的第一个参数可以改变函数中的this指向,例如,f.bind(obj),实际上可以理解为obj.f(),这时,f函数体内的this自然指向的是obj. bind并不会调用函数,而且在内存中重新创建了一个函数,并且函数内this指向第一参数
例子

再看另外一种用法
例子
function f(y, z){
return this.x + y + z;
}
var m = f.bind({x : 1}, 2);
console.log(m(3));
//6
注意:这里bind方法会把它的第一个实参绑定给f函数体内的this,所以这里的this即指向{x : 1}对象,从第二个参数起,会依次传递给原始函数,这里的第二个参数2,即是f函数的y参数,最后调用m(3)的时候,这里的3便是最后一个参数z了,所以执行结果为1 + 2 + 3 = 6
分步处理参数的过程其实是一个典型的函数柯里化的过程(Curry)
(浅谈函数柯里化)
curry 的概念:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数
先看一个简单例子,add函数接受 2 个参数(或者多个),addX函数接受 1 个参数。
换而言之,所谓"柯里化",就是把一个多参数的函数,转化为单参数函数。将一个函数转换为一个新的函数
// 非柯里化
function add(x, y) {
return x + y;
}
add(1, 2) === 3; // true
// 柯里化
function addX(y) {
return function(x) {
return x + y;
};
}
addX(2)(1) == 3; // true
柯里化好处:
- 代码复用,减少维护成本
- 尽可能的函数化,便于阅读
call()方法
改变函数中的this,直接调用函数
比如 fn.call(O) 直接调用fn函数 并且this指向o
call的返回值就是函数的返回值
call()例子

//[object object] 5,9 [object Array] 最后例子是用object原型对象里面的toString来判断数据类型,把tihs指向了arr ,[object Array]指的是前面代表的对象,后面是对象类型
借用构造函数
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
function Student(name,age,sex,score){
Person.call(this,name,age,sex);//第一个this是指向的Student函数,把student函数传给了person。而后面三个是传的参数
//只借用属性里面的,不借用原型里面的
this.score=score;
}
var s1=new Student('lilei',18,'man',90);
console.dir(s1);
javascript中call()、apply()、bind()的用法终于理解
先看明白下面:
例1

obj.objAge; //undefined
obj.myFun() //小张年龄undefined
例2

shows() // undefined
比较一下这两者this 的差别,第一个打印里面的this 指向obj,第二个全局声明的shows()函数 this 是window ;
1,call()、apply()、bind() 都是用来重定义 this 这个对象的!
如:

obj.myFun.call(db); //德玛年龄99
obj.myFun.apply(db); //德玛年龄99
以上出了bind 方法后面多了个 () 外 ,结果返回都一致!
obj.myFun.call(db,'成都','上海'); //德玛 年龄 99 来自 成都去往上海
obj.myFun.apply(db,['成都','上海']); //德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,'成都','上海')(); //德玛 年龄 99 来自 成都去往上海
obj.myFun.bind(db,['成都','上海'])(); //德玛 年龄 99 来自 成都,上海去往undefined
微妙的差距!
函数的其他成员

console.dir(fn)

私有变量arguments不是fn.arguments。fn.arguments是一个属性、当函数的参数个数不固定时,在函数内部,可以通过argument获取到实际传过来的参数
个人总结重点
组合继承 借用构造函数加原型继承 比如Student.prototype=new Person Student会继承Person的属性和原型方法
记得 设置了prototype后,要重新设置constructor
call() apply() bind()用法 首先都是用来重定义this这个对象的
但是bind返回的是一个新的函数,必须要调用才会执行
传参区别 三个函数的第一个参数都是this的指向对象,第二个参数差别 call是直接放进入,逗号隔开就行。bind也是。apply则是把参数放入一个数组传进去。apply常见应用就是把数组展开传给函数

浙公网安备 33010602011771号