javaScript--函数中的this,箭头函数中的this,改变this指向

全局环境下this就是 window 对象的引用

window.name='xxx'
        function global(){
            console.log(this);//window
            console.log(this.name);//xxx  ---window.name
        }
        global()

但是在严格模式下,全局函数内this为undefined

方法调用

普通函数中的this指向

  • 函数为对象里的方法时this 指向该对象,也就是该函数为对象里的一个属性例如下面的 fangfa()
  • 函数为对象里方法里面的一个方法时,他就是一个普通的全局函数,他的this指向window,例如 fangfa()里面的son()函数

箭头函数中的this指向

  • 函数为箭头函数的时候他的指针和他的父级函数的指针相同,指向同一个对象如果他没有父级函数,就是指向window,
  • 例如getThis(),如果他有父级函数,就和父级函数的this一样,
  • 例如but[0].addEventListener(),他里面的函数是指针函数,所以他的指向就是根据上下文,也就是和他的父级函数fangfa()指向一样,都是指向data这个对象
  • 相比之下but[1].addEventListener(),里面是function(){},他就相当于是but[1]里面的一个方法,所以他指向but[1],它里面的function but1_son()就指向 window,()=>里的this指向but[1]
data={
	site:'xxx',
	 getThis:()=>{
	         console.log(this);//window,箭头函数的this的指向和他父级函数的指向相同
	 },
	 fangfa:function(){
	     console.log(this);//   {site: 'xxx', getThis: ƒ, fangfa: ƒ}
	                     // 这个this指向的就是这个对象
	    
	    function son()
	    {
	     console.log(`fangfa-son+${this}`);//window 对象里第一层的函数被称为方法,this指向对象,第二层(函数里面的函数)就是普通的全局函数,this指向window
     
    }
    son()
    but[0].addEventListener('click',(e)=>{
          console.log(e.target);
          console.log(this);//这里是箭头函数,他的父级是fangfa,fangfa的this指向的是data,所以这个this也是指向data
     // })
     but[1].addEventListener('click',function(){
         //这个function是but对象里的方法,所以this指向but[1]
         console.log(this);//<button>点击按钮2--function</button>,
         (function but1_son(){
             console.log(this);//window  这个funtion就是一个全局函数了
         })();
         (()=>{
             console.log(this);//这个就和他的父级-function指向相同了,<button>点击按钮2--function</button>
         })()
     })
 }
}

构造函数

构造函数可以用来创建对象

  function User() {
            this.name = "xxx";
            this.say = function() {
                console.log(this); //User {name: "xz", say: ƒ}
                return this.name;
            };
            }
        let hd = new User();
        console.log(hd.name);//xxx
        console.log(hd.say()); //xxx

改变函数中的this指向的方式

①把要用的this赋值给一个变量或常量

let Lesson = {
  site: "课程",
  lists: ["js", "css", "mysql"],
  show() {
    return this.lists.map(function(title) {
    //这里的this原本是应该指向window的,但是因为map()里面的第二个参数可以设置this,此处就是把show()里面的this赋值了进来
   console.log(this); //{site: '课程', lists: Array(3), show: ƒ}
      return `${this.site}-${title}`;
    }, this);
  }
};
console.log(Lesson.show());// ['课程-js', '课程-css', '课程-mysql']

②使用 apply,call,bind等方法
这三个方法都是用来改变函数里面的this指向的
1.call() /apply()
call 与 apply 都是用于将对象绑定到 this,只是在传递参数上有所不同。apply 用数组传参,call 需要分别传参,这两个方法都会立即执行

function User(name,age) {
 this.name = name;
 this.age=age

}
let xxx={};
//第一个参数是要设置的指针指向,这里是让User的this指向xxx
//第二个参数是 User()中要传入的参数
User.call(xxx,'xiaozhuo',22)
//User.apply(xxx,['xiaozhuo',22])
console.log(xxx);//{name: 'xiaozhuo', age: 22}

案例:实现构造函数属性继承

function Request() {
  this.get = function(params = {}) {
    //组合请求参数
    let option = Object.keys(params)
      .map(i => i + "=" + params[i])
      .join("&");

    return `获取数据 API:${this.url}?${option}`;
  };
}
function Lesson() {
  this.url = "lesson/index";
  Request.call(this);
  
}
let js = new Lesson();
console.log(
  js.get({
    row: 20
  })
  )//获取数据 API:lesson/index?row=20

2.bind()
bind()是将函数绑定到某个对象,比如 a.bind(hd) 可以理解为将 a 函数绑定到 hd 对象上即 hd.a()。

  • 与 call/apply 不同 bind 不会立即执行
  • bind 是复制函数形为会返回新函数

bind 是复制函数行为

function hd(a, b) {
  return this.f + a + b;
}

let a={f:1}
//使用bind会生成新函数
let newFunc = hd.bind(a);//这里newFunc 的指向就指向a了
console.log(newFunc(2,3));//6

let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc());//10

let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc(2,5));//10 还是会采用之前传入的参数

let newFunc = hd.bind(a,3);//这里newFunc 的指向就指向a了
console.log(newFunc(5));//9

要注意bind()里面的参数传入

function hd(a, b) {
  return this.f + a + b;
}

let a={f:1}
let newFunc = hd.bind(a,3,6);//这里newFunc 的指向就指向a了
console.log(newFunc(2,5));//10 还是会采用之前传入的参数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值