本文共 1398 字,大约阅读时间需要 4 分钟。
我们来看一下结果:
我们发现第一次单独调用fn()的时候,this打印出来的是global,因为我们在node环境下运行的,在浏览器端运行代码这里this就指向window
第二次我们使用call方法调用fn的时候,由于我们在call方法的第一个参数那里传入了一个obj,所以fn()方法内部的this指向了这个obj,所以打印出来的this就是这个obj
我们看一下同样的代码在浏览器里是什么结果:
call方法后面还可以接收多个参数,看一个例子:
结果:
function fn(x, y) { console.log(this) console.log('x + y = ', x + y)}fn()var obj = { name: "Dean", gender: "male"}fn.call(obj, 10, 20)
ES6之前并没有提供extends继承,我们是通过
构造函数+原型对象
模拟实现继承,被称为组合继承
其中,构造函数用来继承父类的属性,原型对象用来继承父类的方法
子类Son想借用父类Father的属性,于是调用Father.call()
方法,传入this,这样就相当于Father执行的时候,内部的this指向了子类Son的实例对象son
结果:
我们在浏览器里面打个断点看看:
看到没?这里的this指向Son
我们还可以给子类单独设置属性:
先看一个错误的做法:
如果直接把子类Son的prototype指向父类Father的prototype, 那么确实子类可以拿到父类原型上的方法money:
但是此时子类的原型对象和父类的原型对象都指向了同一个内存地址,这样就会相互影响,子类如果想添加一个子类单独的方法,父类的实例对象也能拿到子类定义的这个方法,这显然不是我们想要的:
我们在上面代码中,使用Son.prototype = Father.prototype,那么接下来操作Son.prototype,就会影响到父类,比如我们在Son.prototype上面添加一个exam方法,然后看父类的原型对象Father.prototype:
所以我们可以这样写:
这样的原理如下图:
我们把Son的prototype指向一个Father的实例对象,然后子类Son想要单独添加的方法就写在Son.prototype上,因为此时Son.prototype是Father的一个实例对象,修改它不会影响Father.prototype,并且Son的实例对象可以通过Son.prototype(此时是Father的一个实例对象)的__proto__属性访问到父类原型对象上的方法money
我们来打印一下下面的数据
这里子类Son的prototype.constructor指向了Father,这明显是不对的,我们之前说过,如果利用对象的形式修改了原型对象,别忘了利用contructor属性指回原来的构造函数
所以我们还要加一步:
这样就改回来了
转载地址:http://umtq.baihongyu.com/