this的五种不同情形

本文详细解析了JavaScript中this关键字的五种不同情景下的指向规则,包括默认情况、作为对象方法调用、通过call/apply/bind改变绑定、构造函数及特殊绑定情况。

this的五种不同情形

默认情况

在默认的,纯粹的函数调用时,视作全局性调用,此时的this指向全局对象Global,在浏览器环境下,也即window对象。

window.x = 'Jackie'

function func() {
  console.log(this.x)
}

func() // Jackie

在严格模式("use strict")下,会禁止this指向全局对象,此时的this会是undefined

作为对象的方法调用

此时this指向调用这个方法的对象。

var x = 'Property of Window'

var obj = {}
obj.x = 'Property of obj'
obj.f = function () {
    console.log(this.x)
}

obj.f() // Property of obj

// 值得注意的情况
var f = obj.f
f() // Property of Window

callapplybind 的显式绑定

callapplybind都可以改变一个函数的this指向。

callapply

callapply会将它们的调用对象的this指向它们的第一个参数。

function f () {
  console.log(this.x)
}

var x = 'Property of Window'

var obj = {
  x: "Property of obj"
}

f.apply(obj)     // "Property of obj"

当传入的第一个参数为undefined,或者不传入参数时,在非严格模式下,自动会将this指向全局对象Global,在浏览器里是window对象,严格模式下则会是undefined

function f () {
  console.log(this)
}

f.apply()             // window
f.apply(undefined)     // window

function ff () {
  'use strict'
  console.log(this)
}
ff.apply()             // undefined
ff.apply(undefined) // undefined

callapply没有本质区别。唯一的区别在于:

call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组

bind

bind和前面两者也并未有什么本质的区别,只不过bind将第一个参数绑定当调用函数的this上,并将这个函数返回(不执行)。

function f () {
  console.log(this.x)
}

var x = 'Property of Window'

var obj = {
  x: "Property of obj"
}

var ff = f.bind(obj)
ff() // "Property of obj"

构造函数

当一个函数被当做构造函数,用new关键字新建一个对象的时候,这个函数内部的this以及原型链上的this都会指向这个新建的对象。

function Jackie(para) {
  this.para = para
  console.log(this)
}
Jackie.prototype.log = function(){
  console.log(this)
}

Jackie('hehe')                 // Window
var p = new Jackie('haha')     // Jackie {para: "haha"}
p.log()                     // Jackie {para: "haha"}

其他值得注意的绑定

放在超时代码里

JavaScript中超时调用的代码都是在全局作用域中执行的,因此函数中this的值会指向window对象,在严格模式下也一样。因为超时调用的代码都会有一个隐式绑定:setTimeout(f, time) == setTimeout(f.bind(window), time)

"use stric"
var x = 'Property of Window'

var obj = {}
obj.x = 'Property of obj'
obj.ff = function () {
    setTimeout(
        function () {
            console.log(this.x)
        }, 100)
}

obj.ff()     // Property of Window

// 可以这么解决问题
obj.fff = function () {
    var that = this
    setTimeout(
        function () {
            console.log(that.x)
        }, 100)
}
obj.fff()     // Property of obj
事件监听函数中的this

事件监听函数中的this指向监听对象。

var one = document.getElementById('one')
one.onclick = function () {
  console.log(this)
};

one.click() // <div id="one"></div>
箭头函数

箭头函数中this的指向,在函数定义时即绑定完毕,且后续无法更改。

var obj = {
  x: 1
}

var f1 = () => {
  console.log(this)
}
f1.apply(obj) // Window

var f2 = function () {
  var f3 = () => {
    console.log(this)
  }
  return f3
}

var f4 = f2.apply(obj)
f4() // Object {x: 1}

一个更神奇的例子,超时调用的代码在定义时,绑定了this的指向。

function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

var id = 21;

foo.call({ id: 42 }); // id: 42

绑定的优先级

var obj = {x: 0, name: 'obj'}
var robj = {x: -1, name: 'robj'}
var factory = function (x) {
  this.x = x
  console.log(this)
}

var factoryBind = factory.bind(obj)
robj.factory = factoryBind
robj.factory(2) // Object {x: 2, name: "obj"},作为方法的绑定的优先级低于bind的显式绑定

factoryBind.call(robj, 3) // Object {x: 3, name: "obj"},call的优先级低于bind
console.log(robj) // Object {x: -1, name: "robj", factory: function},未对robj进行修改
console.log(obj) // Object {x: 3, name: "obj"},修改的是obj,因为this指针指向未变化

var p = new factoryBind(4) // factory {x: 4}
console.log(p) // factory {x: 4}
console.log(obj) // Object {x: 3, name: "obj"},构造函数绑定的优先级高于bind的显式绑定

可以见得,优先级从高到低:

  1. new,构造绑定

  2. bind,显式绑定

  3. call/apply,显示绑定

  4. 作为方法绑定

  5. 默认绑定

### BUCK电路的三种工作模式 BUCK电路是一种常见的直流-直流转换器,其主要功能是将较高的输入电压转换为较低的输出电压。根据电感电流的变化特性,BUCK电路可以分为以下三种不同的工作模式: #### 1. 连续电流模式 (Continuous Conduction Mode, CCM)[^2] 在这种模式下,电感中的电流在整个开关周期内始终不降为零。具体来说,在开关管导通期间,电感能够储存能量;而在开关管关断期间,电感释放之前存储的能量给负载供电。 这种模式的特点包括: - 输入功率因数较高。 - 输出纹波较小,适合于对稳定性要求高的应用场合。 - 需要较大的电感值以维持电流连续性。 #### 2. 断续电流模式 (Discontinuous Conduction Mode, DCM)[^2] 在该模式中,当开关管关闭之后,电感内的电流会完全降至零,并保持一段时间直到下一个开关周期重新开始充电过程。因此,DCM下的占空比通常小于CCM情况下的相同条件设定。 此模式的主要特征有: - 较低效率,因为存在额外的时间间隔无任何能量传输至负载。 - 更简单的控制策略可能适用于此种情形。 - 对应更小尺寸元件的选择可能性更大一些。 #### 3. 临界电流模式 (Boundary Conduction Mode, BCM)[^1] BCM实际上是介于上述两者之间的一种特殊状态——即刚好达到使电感电流每次都能下降到接近但不会真正等于零的程度后再进入下一循环。它结合了前两者的优点:既拥有相对平稳的输出又不需要特别大的储能组件体积重量增加太多成本负担。 值得注意的是,在实际设计过程中,工程师们往往会依据特定应用场景的需求选择合适的运行区域。例如对于某些便携设备而言可能会优先考虑采用高效能方案即使这意味着稍微复杂一点的设计流程;而对于那些追求极致紧凑型解决方案的产品线则或许愿意牺牲部分性能指标换取更加轻薄短小的结果呈现出来。 ```python def buck_mode(duty_cycle, inductor_current_min): if inductor_current_min > 0: return "Continuous Conduction Mode (CCM)" # elif duty_cycle * inductor_current_min == 0: return "Boundary Conduction Mode (BCM)" # else: return "Discontinuous Conduction Mode (DCM)" # # Example usage of the function to determine mode based on given parameters. print(buck_mode(0.5, 0)) # This will output 'Boundary Conduction Mode (BCM)' ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值