什么是this
this的指向在函数定义的时候是确定不来的,只有函数执行的时候,才能确定。
this的最终指向是那个调用它的对象,确切的说,是它的上级父对象,父对象有可能包含在其他对象中。
示例:
<script>
var name = "tom";
function M() {
console.log(this);
}
M(); // window
var o1 = {
name: 'o1',
fun: M
}
o1.fun(); // o1
var o2 = {
name: 'o2',
o3 : {
name: 'o3'
}
}
o2.o3.fun = M;
o2.o3.fun(); // o3
</script>
对于构造函数中的this
在《原型链》中我们提到过new的本质:
- 创建一个空对象o,o继承自构造函数原型
- 执行构造函数,指定执行上下文为o,使o获取到构造函数的属性和方法
- 判断执行构造函数的返回,如果是对象则返回该对象,否则返回o
示例:
function newObject(func) {
var o = Object.create(func.prototype);
var k = func.call(o);
if (typeof(k) === 'object'&&k !== null) {
return k;
} else {
return o;
}
}
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
这里引出一个知识点:
- 在new的语法中,实例对象赋值给谁,this指向的就是谁,确切的说,其实this指向的是示例中的o或k,具体看返回
- 当构造函数中this碰到return,跟示例中一样,如果返回类型是个对象(k),那么this就指向这个新对象,否则返回指向函数的实例(o)
示例:
<script>
function M1() {
return {
name: 'M1'
}
}
function M2() {
return 1;
}
function M3() {
return null;
}
var m1 = new M1(); // {name: 'M1'}
var m2 = new M2(); // M2
var m3 = new M3(); // M3,虽然typeof null='object',但是在这里this还是指向那个函数的实例,因为null比较特殊
</script>
call、apply、bind
相同点:
- 接收多个参数
- 改变了函数执行时this指向,指向为第一个入参对象
不同点:
- call、apply会立即执行函数,bind不执行,返回新的函数对象,需调用
- call、bind支持从第二个参数开始传多个参数,apply只传两个参数,除第一个指定对象外还可以传一个数组形式的参数
示例:
<script>
var name = 'joe'
function M(job, age) {
console.log(this.name, job, age);
}
var o = {
name: 'tom', job: 'student', age: 17
}
M('rose', 16); // joe rose 16
M.call(o, o.job, o.age); // tom student 17
M.apply(o, [o.job, o.age]); // tom student 17
var f = M.bind(o, o.job, o.age); // tom student 17
function K(job, age) {
var o1 = {name: 'lilei'}
M.apply(o, arguments);
}
K(o.job, o.age); // tom student 17
</script>
网友评论