javaScript中this的绑定规则

this的绑定规则

绑定一:默认绑定;
绑定二:隐式绑定;
绑定三:显示绑定;
绑定四:new绑定;

绑定一:默认绑定;

独立函数调用
独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用;
案例1:

function foo() {
  console.log(this)//this指向window
}
foo()

案例2:

// 2.案例二:
function foo1() {
  console.log(this)//window
}
function foo2() {
  console.log(this)//window
  foo1()
}
function foo3() {
  console.log(this)//window
  foo2()
}
foo3()

案例3:

var obj = {
  name: "why",
  foo: function() {
    console.log(this)// window
  }
}
var bar = obj.foo
bar() // 独立函数调用--与定义位置无关,跟调用方式和调用位置有关,bar是在全局调用的

案例4:

function foo() {
  console.log(this)
}
var obj = {
  name: "why",
  foo: foo
}
var bar = obj.foo
bar() // window

案例5:

function foo() {
  function bar() {
    console.log(this)// window
  }
  return bar
}
var fn = foo()
fn() 

闭包里的this不一定就指向window,只要独立调用就指向window
如:

function foo() {
  function bar() {
    console.log(this)
  }
  return bar
}
var fn = foo()
fn() // window
var obj = {
  name: "why",
  eating: fn
}
obj.eating() // obj  隐式绑定 
绑定二:隐式绑定;

obj.fn():obj对象会被js引擎绑定到fn函数中的this里面(内部自动绑定)
通过某个对象进行调用的:
也就是它的调用位置中,是通过某个对象发起的函数调用
前提条件:
1.必须在调用的对象的内部有一个对函数的引用(比如一个属性);
2.如果没有这样的引用,在进行调用时,会报找不到该函数的错误;
3.正是通过这个引用,间接的将this绑定到了这个对象上.
案例一:

function foo() {
  console.log(this)
}
// 独立函数调用
// foo()

// 1.案例一:
var obj = {
  name: "why",
  foo: foo
}
obj.foo() // obj对象

案例2:

var obj = {
  name: "why",
  eating: function() {
    console.log(this.name + "在吃东西")
  },
  running: function() {
    console.log(obj.name + "在跑步")
  }
}
obj.eating()
obj.running()
var fn = obj.eating
fn()//独立函数调用了 name是空,取的是window里的name

在这里插入图片描述
案例3:

var obj1 = {
  name: "obj1",
  foo: function() {
    console.log(this)
  }
}
var obj2 = {
  name: "obj2",
  bar: obj1.foo
}
obj2.bar()//obj2 bar调用时boj2绑定到this
绑定三:显式绑定;

如果我们不希望在对象内部包含这个函数的引用,同时又希望在这个对象上进行强制调用,该怎么做呢?
1.javaScript所有的函数都可以使用call和apply方法(这个和prototype有关).
ps:call和apply区别:第一个参数是相同的,后面的参数,apply为数组,call为参数列表
2.这两个函数的第一个参数都要求是一个对象,这个对象的作用就是给this准备的.
3.在调用这个函数时,会将this绑定到这个传入的对象上.
案例:

function foo() {
  console.log("函数被调用了", this)
}
// 1.foo直接调用和call/apply调用的不同在于this绑定的不同
// foo直接调用指向的是全局对象(window)
foo()

var obj = {
  name: "obj"
}
// call/apply是可以指定this的绑定对象
foo.call(obj)
foo.apply(obj)
foo.apply("aaaa")

在这里插入图片描述
2.call和apply有什么区别?

 function sum(num1, num2, num3) {
  console.log(num1 + num2 + num3, this)
 }

sum.call("call", 20, 30, 40)
sum.apply("apply", [20, 30, 40])

在这里插入图片描述
3.call和apply在执行函数时,是可以明确的绑定this, 这个绑定规则称之为显示绑定
bind:

function foo() {
  console.log(this)
}
// 默认绑定和显示绑定bind冲突: 优先级(显示绑定)
var newFoo = foo.bind("aaa")//显示绑定了this为aaa
newFoo()
newFoo()
newFoo()//在被调用时,this永远是aaa  这是个新函数
绑定三:new绑定;

javaScript中的函数可以当做一个类的构造函数来使用,也就是使用new关键字.
使用new关键字来调用函数时,会执行如下操作:
1.创建一个全新的对象;
2.这个新对象会被执行prototype(原型)连接;
3.这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
4.如果函数没有返回其他对象,表达式会返回这个新对象;

function Person(name, age) {
  this.name = name
  this.age = age
}

//js中通过 new Person()调函数 会生成一个新{} 然后把生成的这个对象赋值给函数内部中的this,最后将这个对象也就是this返回
//之后就可以通过var a=new Person()拿到这个对象
//每次会创建一个新的对象重复以上步骤

var p1 = new Person("why", 18)
console.log(p1.name, p1.age)//所以p1可以拿到对象中属性

var p2 = new Person("kobe", 30)//每次会创建一个新的对象
console.log(p2.name, p2.age)

我们通过一个new关键字调用一个函数时(构造器),这个时候this是在调用这个构造器时创建出来的对象
this=创建出来的对象
这个绑定过程就是new绑定

var obj = {
  foo: function() {
    console.log(this)
  }
}
new obj.foo();//这时候就是new绑定和obj绑定冲突了--这里就要考虑优先级的问题了 具体细节见下篇文章

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值