JS的this指向

this是什么?

在JavaScript中,this 是一个特殊的关键字,它代表函数被调用时的上下文(context)。this 的值取决于函数是如何被调用的,而不是它在哪里被定义的。在绝大多数情况下,函数的调用方式决定了 this 的值(运行时绑定)

this绑定的优先级?

new构造函数 > bind call apply方法 > 对象方法 > 普通函数调用

同时,箭头函数的 this 一旦被绑定,就不会再被任何方式所改变。箭头函数中没有this, 会向上级作用域寻找,这意味着箭头函数内部的this值与其定义时父级的上下文相同

如果有多个bind链式调用的话,this也只是指向bind的第一个中对象

ES5中setTimeout的函数时作为回调函数调用的,是挂载到window上的,所以this是指向window的。

call()、apply()、bind()的区别?

1.参数方面的不同

call()、apply()、bind()的第一个参数都是一样的都是想让this指向的值,主要的区别在后面的参数
call()和bind()的第一个参数后面的参数是一个列表形式,就是正常传参
apply()的第一个参数后面的参数是一个数组,数组的中的元素就是要调用的函数的参数

2.返回值方面的不同

call()和apply()都是调用函数后将被调用的函数的返回值返回
bind()则是返回一个函数,所以可以利用bind()将它的返回值多次调用

3.执行方面的不同

call()、apply()都是直接执行调用他们的函数
bind()只是返回一个函数并不执行该函数,需要再手动执行一下

比如如果想让函数立即执行就选择call()或apply()
如果想要多次调用函数就选择bind()
如果不想用数组的形式传参又想让函数立即行就选择call()

总结

  1. this的值是多变的,由函数的调用方式决定this的值,函数的调用方式有比较多所以导致this的值多变。
  2. 即便this的值多变让程序员很难确定,也可以通过call()、apply()、bind()手动更改this的指向。
  3. bind()的返回值是一个函数,并且不会立即执行。

this指向题目,请作答。

要需要补充一点,不管你的对象嵌套多深,this只会绑定为直接引用该函数的地址属性的对象

// 题目一
var name = "window";

var person = {
  name: "person",
  sayName: function () {
    console.log(this.name);
  }
};

function sayName() {
  var sss = person.sayName;
  
  sss();
  person.sayName();
  (person.sayName)();
  (b = person.sayName)();
  
}

sayName();
//题目二
var name = 'window'

var person1 = {
  name: 'person1',
  foo1: function () {
    console.log(this.name)
  },
  foo2: () => console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () => {
      console.log(this.name)
    }
  }
}

var person2 = { name: 'person2' }


// 开始题目:
person1.foo1();
person1.foo1.call(person2);

person1.foo2();
person1.foo2.call(person2);

person1.foo3()();
person1.foo3.call(person2)();
person1.foo3().call(person2);

person1.foo4()();
person1.foo4.call(person2)();
person1.foo4().call(person2);
//题目三
var name = 'window'

/*
	通过new进行调用会执行如下操作
  1.创建一个空的对象
  2.将这个空的对象赋值给this
  3.执行函数体中代码
  4.将这个新的对象默认返回
*/
function Person(name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  },
  this.foo2 = () => console.log(this.name),
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  },
  this.foo4 = function () {
    return () => {
      console.log(this.name)
    }
  }
}

// person1/person都是对象(实例instance)
var person1 = new Person('person1')
var person2 = new Person('person2')


// 面试题目:
person1.foo1()
person1.foo1.call(person2)

person1.foo2()
person1.foo2.call(person2)

person1.foo3()()
person1.foo3.call(person2)()
person1.foo3().call(person2)

person1.foo4()()
person1.foo4.call(person2)()
person1.foo4().call(person2)
// 题目四
var name = 'window'

function Person(name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}

var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()()
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)

person1.obj.foo2()()
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)
//题目五
function Foo(){
    getName =function(){ console.log(1);}; //没用this定义,相当于全局作用域声明了一个getName函数
    return this;
}
Foo.getName =function(){ console.log(2);};
Foo.prototype.getName =function(){ console.log(3);};
var getName =function(){ console.log(4);};
function getName(){ console.log(5)};
//同时声明相同名称的变量和函数,使用了var会造成变量提升,会被解释为
// function getName() {
//   console.log(5);
// }
// var getName; // 变量声明被提升
// getName = function() {
//   console.log(4);
// };


Foo.getName();              //2
getName();                  //4
Foo().getName();            //1  ??当定义 Foo 函数时,getName 并没有被定义。getName 的定义发生在调用 Foo 函数时。
getName();                  //1
new Foo.getName();          //2
new Foo().getName();        //3
new new Foo().getName();    //3


1、审题
考察this指向  原型  重名预编译  构造函数
预编译在最前面(变量提升)
全局预编译  函数声明会覆盖变量声明
然后代码会从上往下按顺序执行
添加函数的属性是静态属性
Foo.prototype会对实例的结果造成影响
重新定义的getName函数

函数中没有关键字声明这个getName
没有这个变量会从父级查找

函数的调用看作一个整体

构造函数创建实例什么情况下有属性?
需要给this去绑定

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值