this指向的四项规则
【摘要】 this指向规则
一、默认绑定规则
console.log(this === window);// true
console.log({}==={});// false
// 函数的独立调用
function test(){
console.log(this === window);// true
}
test(); // 相当于window.test();
二、隐式绑定规则:谁调用就指向谁
var a =0;
var obj = {
a = 2,
foo: function(){
console.log(this);//obj
function test(){
console.log(this);//window
}
test();
// (function(){
// console.log(this);//window
//})();函数声明后在浏览器中立即执行IFEthis指向window,在node中执行会指向相应的全局对象
}
}
obj.foo();
每一个函数执行都会有一个自身的this指向
预编译会产生Global Object与Activity Object,this已经存在,但如果函数不执行this没有意义。
-
闭包中的this指向
当函数执行的时候,导致函数被定义,并抛出,会产生闭包(不严谨的描述,但这句话也是对的,只是方便理解)var obj = { a = 2, foo: function(){ console.log(this);//obj function test(){ console.log(this);//window } return test; } } obj.foo()();//相当于test的独立调用,主要看函数的调用方式
当对函数存在赋值的时候存在隐式丢失,不管是变量赋值还是参数赋值
var a = 0;
function foo(){
console.log(this);
}
var obj = {
a = 2,
foo: foo
}
obj.foo();//obj
var bar = obj.foo;//当对函数存在赋值的时候存在隐式丢失 var bar = foo;
bar();//window 相当于独立调用
var a = 0;
function foo(){
console.log(this);
}
function bar(fn){
fn();
//fn.bind(obj)();
}
//父函数有能力决定子函数的this指向
var obj = {
a = 2,
foo: foo
}
bar(obj.foo);//window 预编译过程中形参与实参存在一个浅拷贝过程,也是一个赋值过程
//子函数又叫做回调函数
var arr = [1,2,3];
arr.forEach(function(item,index,arr){
console.log(this);//obj
},obj);
arr.sort(function(a,b){
console.log(this);//window
return a-b;
});
setInterval(function(){
console.log(this);//window
})
三、显示绑定:call、apply、bind
传参方式不一样
var a = 0;
function foo(){
console.log(this);
}
function bar(fn){
fn();
//fn.bind(obj)();
}
bar.call(obj,1,2,3);//第一个参数是要绑定的this指向
bar.apply(obj,[1,2,3]);
bar.bind(obj)(1,2,3);//bin返回一个函数需要执行一下
bar.call(1,2,3)//Number
bar.call(undefied,2,3)//window undefied没有包装类绑定失败使用默认指向
bar.call(null,2,3)//window null没有包装类绑定失败使用默认指向
四、new绑定:new绑定优先级大于显示绑定大于隐式绑定大于默认绑定
function Person(){
var this = {};
this.a = 1;
return this;//this是实例化之后的对象
return 1;//this的指向不受影响
return {};//this的指向会发生改变
}
var person = new Person();实例是对象
// 证明显示绑定优先级高于隐式绑定优先级
function foo() {
console.log(this.a);
}
var obj1 = {
a:1,
foo: foo
}
var obj2 = {
a:2,
foo:foo
}
obj1.foo.call(obj2);//2
obj2.foo.call(obj1);//1
// 证明new 绑定优先级高于显示绑定
function foo(b) {
this.a = b;
}
var obj1 = {};
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a);//2
var baz = new bar(3);
console.log(obj1.a);//2
console.log(baz.a);//3
五、箭头函数
var a = 0;
function foo() {
var that = this;
function test() {
console.log(this);
}
test();
}
foo();// window
如果想让test中的this跟随外层foo的指向
第一种方法 将外层作用域的this,保留在that中,内部使用that
function foo() {
var that = this;
function test() {
console.log(that);
}
test();
}
var obj = {
a:1,
foo:foo
}
obj.foo();// obj
第二种方法 调用test的时候使用显示绑定指向当前作用域this
function foo() {
function test() {
console.log(this);
}
test.call(this);
}
var obj = {
a:1,
foo:foo
}
obj.foo();// obj
第三种方法 利用箭头函数直接取到外层作用域指向
箭头函数本身是没有this指向的,它的this指向实际上是使用外层作用域的this
function foo() {
console.log(this);
var test = ()=> {
console.log(this);
}
test();
}
var obj = {
a:1,
foo:foo
}
obj.foo();// obj,obj
对于箭头函数,所有绑定规则都不适用,箭头函数的this指向取决于父环境中的this指向,箭头函数本身不存在this指向
1.默认绑定规则
var a = 0;
function foo() {
console.log(this);
var test = ()=> {
console.log(this);
}
return test;
}
var obj1 = {
a:1,
foo:foo
}
var obj2 = {
a:2,
foo:foo
}
obj1.foo()(); // 默认绑定规则(独立调用对箭头函数)无效
2.显示绑定规则
var a = 0;
function foo() {
console.log(this);
var test = ()=> {
console.log(this);
}
return test;
}
var obj1 = {
a:1,
foo:foo
}
var obj2 = {
a:2,
foo:foo
}
var bar = foo().call(obj2); // 显示绑定规则对箭头函数this指向无效,如果test是一般函数是有效的
3.隐式绑定规则
var obj1 = {
a:1,
foo:() => {
console.log(this);
}
}
obj.foo();// window 隐式绑定规则无效
4.new不能实例箭头函数
var foo = () => {
console.log(this);
}
new foo();// 报错
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)