This 漫谈
by 小鱼二
2016年10月27日
为什么要使用 this
function say() {
console.log('I am ' + this.name.toUpperCase());
}
function say2(person) {
console.log('I am ' + person.name.toUpperCase());
}
var me = {
name: 'Yanqi'
};
var you = {
name: 'little fish'
};
say.call(me);
say.call(you);
say2(me);
say2(you);
this 提供了一种更好的方式来隐式'传递'一个对象引用.
使得 API 的设计更加简洁且易于复用
显示的传递上下文对象会随着项目的复杂变得混乱.
在介绍对象和原型的时候, 函数可以自动引用合适的上下文对象很重要 .
关于 this 的误解
1. 指向函数自身
2. 作用域指向函数的作用域
function foo() {
this.count += 1;
}
foo.count = 2;
var count = 1;
foo();
console.log(foo.count);
console.log(count);
function foo() {
var a = 1;
bar();
}
function bar() {
console.log(this.a);
}
bar();
This 是什么
- this 的绑定和函数的声明位置没有关系, 只取决于函数的调用方式
- this 即 函数的调用者
调用位置
函数的调用位置即被调用的位置, 而不是声明的位置
方法: 分析调用栈
function baz() {
bar();
}
function bar() {
foo();
}
function foo() {
console.log('foo');
}
baz();
绑定规则
- 默认绑定
- 隐式绑定
- 显示绑定
- new 绑定
- 优先级
隐式绑定: 独立函数调用
function foo() {
console.log(this.a);
}
function foo2() {
"use strict";
console.log(this.a);
}
var a = 1;
foo();
foo2();
注意区分 严格模式
隐式绑定
var name = 'global name';
function foo() {
console.log(this.name);
}
var obj = {
name: 'Yanqi',
foo: foo
};
var obj2 = {
name: 'litte fish',
foo: foo
}
obj.foo();
obj2.foo();
var bar = obj1.foo;
bar();
function doFoo(fn) {
fn();
}
doFoo(obj.foo);
注意隐式丢失
显示绑定
call/apply/bind
function foo() {
console.log(this.name);
}
var name = 'global name';
var obj = {
name: 'Yanqi'
}
foo();
foo.call(obj);
foo.call();
var bar = foo.bind(obj);
bar();
new 绑定
使用 new 来调用函数, 都发生了什么
- 创建一个全新的对象
- 这个对象会被执行[[prototype]]链接
- 这个全新的对象会绑定到函数调用的 this
- 如果函数没有其他的返回值, 那么返回这个新对象
function foo(a) {
this.a = a;
}
var bar = new foo(1);
console.log(bar.a);
优先级
function foo() {
console.log(thi.a);
}
var a = 0;
var obj1 = {a: 1, foo: foo};
var obj2 = {a: 2, foo: foo};
obj1.foo();
obj1.foo.call(obj2);
function foo(a) {
this.a = a;
}
var obj1 = {foo: foo};
var obj2 = {};
obj1.foo(2);
obj1.a;
obj1.foo.call(obj2, 3);
obj1.a;
obj2.a;
var bar = new obj1.foo(4);
obj1.a;
bar.a;
new 绑定
显示绑定
隐式绑定
默认绑定
箭头函数....
箭头函数不适用 this 的四种标准
根据外层的作用域来决定 this
function foo() {
return (a) => {
console.log(this.a);
}
}
var obj1 = {a:2};
var obj2 = {a:3};
var bar = foo.call(obj1);
bar.call(obj2);
总结
- 找到函数的直接调用位置
- 判断 this 的绑定对象
- new?
- call/apply/bind 显示绑定
- 上下文对象调用
- 默认: 区分严格模式
This 漫谈
By xy2
This 漫谈
- 2,224